# -*- coding: utf-8 -*-
import os
import re
import json
import logging
from dataclasses import dataclass
from typing import Dict, Pattern

from dotenv import load_dotenv
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import (
    ApplicationBuilder, ContextTypes,
    CommandHandler, MessageHandler, CallbackQueryHandler,
    filters
)

# --- Setup ---
load_dotenv()
TOKEN = os.getenv("TELEGRAM_TOKEN")

# Sitio oficial
WEBSITE_URL = "https://www.newintlcenter.org"

# Dirección + mapa
ADDRESS_ES = "80 Maiden Lane, Piso 13, New York, NY 10028"
ADDRESS_EN = "80 Maiden Lane, 13th Floor, New York, NY 10028"
MAP_URL = "https://www.google.com/maps?q=80+Maiden+Lane+13th+Floor+New+York+NY+10028"

# Programas (ES/EN)
PROGRAMS_TEXT_ES = """📚 *Programas del International Center:*
• Inglés Básico (10 am – 1 pm)
• Inglés Nivel 1 (10 am – 1 pm)
• Inglés Nivel 2 (10 am – 1 pm)
• Inglés Nivel 3 (10 am – 1 pm)
• Inglés Nivel 4 (horario a confirmar)
• Open Classes (horarios variables)
• Home Health Aide (HHA)
• Ciudadanía
• Conversation Partner

💸 *Nuestros cursos son gratuitos.*
⏰ *Horarios:* Mañana 10 am – 1 pm | Tarde 6 pm – 9 pm, de lunes a viernes.
ℹ️ Detalles y posibles cambios: {WEBSITE_URL}"""

PROGRAMS_TEXT_EN = """📚 *International Center Programs:*
• Basic English (10 am – 1 pm)
• English Level 1 (10 am – 1 pm)
• English Level 2 (10 am – 1 pm)
• English Level 3 (10 am – 1 pm)
• English Level 4 (time TBA)
• Open Classes (variable schedules)
• Home Health Aide (HHA)
• Citizenship
• Conversation Partner

💸 *Our courses are free.*
⏰ *Schedules:* Morning 10 am – 1 pm | Evening 6 pm – 9 pm, Monday–Friday.
ℹ️ Details and updates: {WEBSITE_URL}"""

logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO
)
logger = logging.getLogger("ic-bot")

LANGS = {"es": "Español", "en": "English"}
DEFAULT_LANG = "es"  # idioma por defecto

@dataclass
class Matcher:
    pattern: Pattern
    answer: str

def load_faq(lang: str) -> Dict[str, str]:
    """Carga FAQs desde data/faq_{lang}.json si existe; si no, usa fallbacks."""
    fname = f"data/faq_{lang}.json"
    if os.path.exists(fname):
        with open(fname, "r", encoding="utf-8") as f:
            return json.load(f)
    if lang == "es":
        return {
            "horario|clases|zoom|horarios|schedule":
                "🗓️ Horarios: Mañana 10 am – 1 pm | Tarde 6 pm – 9 pm (lun–vie). Enlaces pueden cambiar. Revisa: {WEBSITE_URL}.",
            "inscripci[oó]n|registrarme|matr[ií]cula|aplicar|apply":
                "📝 La inscripción y requisitos están explicados en: {WEBSITE_URL}.",
            "direcci[oó]n|location|ubicaci[oó]n|address":
                "📍 {ADDRESS}\n🗺️ Mapa: {MAP_URL}\n🌐 Más info: {WEBSITE_URL}",
            "programa|programas|courses|clases de ingl[eé]s":
                "{PROGRAMS}",
            "contacto|tel[eé]fono|email|correo":
                "📬 Contáctanos desde la web oficial: {WEBSITE_URL}.",
            "costos|precio|fees|pagar":
                "💵 Nuestros cursos son gratuitos. Más info: {WEBSITE_URL}."
        }
    else:
        return {
            "schedule|class|zoom|time|when":
                "🗓️ Schedules: Morning 10 am – 1 pm | Evening 6 pm – 9 pm (Mon–Fri). Links may change. Check: {WEBSITE_URL}.",
            "apply|enroll|registration":
                "📝 Enrollment and requirements: {WEBSITE_URL}.",
            "location|address|where":
                "📍 {ADDRESS}\n🗺️ Map: {MAP_URL}\n🌐 More info: {WEBSITE_URL}",
            "program|programs|course|english class|esl":
                "{PROGRAMS}",
            "contact|email|phone":
                "📬 Please reach us via the official site: {WEBSITE_URL}.",
            "cost|price|fees|pay":
                "💵 Our courses are free. More info: {WEBSITE_URL}."
        }

def build_matchers(lang: str):
    data = load_faq(lang)
    matchers = []
    for patt, ans in data.items():
        matchers.append(Matcher(pattern=re.compile(patt, flags=re.IGNORECASE), answer=ans))
    return matchers

MATCHERS = {"es": build_matchers("es"), "en": build_matchers("en")}

def get_lang(context: ContextTypes.DEFAULT_TYPE) -> str:
    return context.user_data.get("lang", DEFAULT_LANG)

def t(lang: str, key: str) -> str:
    texts = {
        "welcome_es": "¡Hola! Soy el asistente del *International Center*. ¿En qué puedo ayudarte hoy?",
        "welcome_en": "Hi! I’m the *International Center* assistant. How can I help you today?",
        "help_es": "Escribe tu pregunta (ej.: *horarios*, *inscripción*, *ubicación*). Usa /menu para opciones rápidas o /lang para cambiar de idioma.",
        "help_en": "Type your question (e.g., *schedule*, *apply*, *location*). Use /menu for quick options or /lang to switch language.",
        "lang_set_es": "✅ Idioma configurado a *Español*.",
        "lang_set_en": "✅ Language set to *English*.",
        "no_match_es": "No encontré una respuesta exacta 🤔. Revisa {WEBSITE_URL} o usa /menu.",
        "no_match_en": "I couldn’t find an exact answer 🤔. Check {WEBSITE_URL} or use /menu."
    }
    return texts.get(f"{key}_{lang}", texts.get(key, key))

def menu_keyboard(lang: str) -> InlineKeyboardMarkup:
    if lang == "es":
        buttons = [
            [InlineKeyboardButton("📚 Programas", callback_data="programs")],
            [InlineKeyboardButton("🗓️ Horarios", callback_data="schedule")],
            [InlineKeyboardButton("📍 Ubicación", callback_data="location")],
            [InlineKeyboardButton("❓ FAQ", callback_data="faq")],
            [InlineKeyboardButton("🌐 Sitio web", url=WEBSITE_URL)]
        ]
    else:
        buttons = [
            [InlineKeyboardButton("📚 Programs", callback_data="programs")],
            [InlineKeyboardButton("🗓️ Schedule", callback_data="schedule")],
            [InlineKeyboardButton("📍 Location", callback_data="location")],
            [InlineKeyboardButton("❓ FAQ", callback_data="faq")],
            [InlineKeyboardButton("🌐 Website", url=WEBSITE_URL)]
        ]
    return InlineKeyboardMarkup(buttons)

# ---------------- Handlers ----------------

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    lang = get_lang(context)
    text = t(lang, "welcome")
    await update.message.reply_text(
        text.replace("{WEBSITE_URL}", WEBSITE_URL),
        reply_markup=menu_keyboard(lang),
        parse_mode="Markdown"
    )

async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    lang = get_lang(context)
    await update.message.reply_text(
        t(lang, "help").replace("{WEBSITE_URL}", WEBSITE_URL)
    )

async def menu_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    lang = get_lang(context)
    await update.message.reply_text("👇", reply_markup=menu_keyboard(lang))

async def lang_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if context.args and context.args[0].lower() in LANGS:
        context.user_data["lang"] = context.args[0].lower()
        key = "lang_set"
        await update.message.reply_text(t(context.user_data["lang"], key))
    else:
        kb = InlineKeyboardMarkup([
            [InlineKeyboardButton("Español 🇪🇸", callback_data="setlang_es"),
             InlineKeyboardButton("English 🇺🇸", callback_data="setlang_en")]
        ])
        await update.message.reply_text("Choose language / Elige idioma:", reply_markup=kb)

async def on_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    data = query.data
    await query.answer()
    lang = get_lang(context)

    if data.startswith("setlang_"):
        new_lang = data.split("_", 1)[1]
        if new_lang in LANGS:
            context.user_data["lang"] = new_lang
            await query.edit_message_text(t(new_lang, "lang_set"))
        return

    if data == "programs":
        text = PROGRAMS_TEXT_ES if lang == "es" else PROGRAMS_TEXT_EN
        kb = InlineKeyboardMarkup([
            [InlineKeyboardButton("🌐 Sitio web" if lang == "es" else "🌐 Website", url=WEBSITE_URL)]
        ])
        await query.edit_message_text(
            text.replace("{WEBSITE_URL}", WEBSITE_URL),
            reply_markup=kb,
            parse_mode="Markdown",
            disable_web_page_preview=True
        )

    elif data == "schedule":
        if lang == "es":
            msg = (
                "🗓️ Horarios:\n"
                "• Mañana: 10 am – 1 pm\n"
                "• Tarde: 6 pm – 9 pm\n"
                "👉 Enlaces (Zoom/presencial) pueden cambiar. Revisa: {WEBSITE_URL}."
            )
        else:
            msg = (
                "🗓️ Schedules:\n"
                "• Morning: 10 am – 1 pm\n"
                "• Evening: 6 pm – 9 pm\n"
                "👉 Links (Zoom/in-person) may change. Check: {WEBSITE_URL}."
            )
        await query.edit_message_text(msg.replace("{WEBSITE_URL}", WEBSITE_URL))

    elif data == "location":
        addr = ADDRESS_ES if lang == "es" else ADDRESS_EN
        msg = f"📍 {addr}"
        kb = InlineKeyboardMarkup([
            [InlineKeyboardButton("🗺️ Abrir mapa" if lang == "es" else "🗺️ Open map", url=MAP_URL)],
            [InlineKeyboardButton("🌐 Sitio web" if lang == "es" else "🌐 Website", url=WEBSITE_URL)]
        ])
        await query.edit_message_text(msg, reply_markup=kb)

    elif data == "faq":
        msg = ("Escribe palabras clave como: *horarios*, *inscripción*, *ubicación*, *costos*."
               if lang == "es" else
               "Type keywords like: *schedule*, *apply*, *location*, *cost*.")
        await query.edit_message_text(msg, parse_mode="Markdown")

def answer_from_faq(text: str, lang: str) -> str:
    """Devuelve la respuesta de las FAQs con reemplazo de placeholders."""
    for m in MATCHERS[lang]:
        if m.pattern.search(text):
            ans = m.answer
            addr = ADDRESS_ES if lang == "es" else ADDRESS_EN
            programs = (PROGRAMS_TEXT_ES if lang == "es" else PROGRAMS_TEXT_EN).replace("{WEBSITE_URL}", WEBSITE_URL)
            return (ans
                    .replace("{WEBSITE_URL}", WEBSITE_URL)
                    .replace("{MAP_URL}", MAP_URL)
                    .replace("{ADDRESS}", addr)
                    .replace("{PROGRAMS}", programs))
    return t(lang, "no_match").replace("{WEBSITE_URL}", WEBSITE_URL)

async def on_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
    lang = get_lang(context)
    user_text = update.message.text or ""
    reply = answer_from_faq(user_text, lang)
    await update.message.reply_text(reply, disable_web_page_preview=True, parse_mode="Markdown")

def main():
    if not TOKEN:
        raise SystemExit("Missing TELEGRAM_TOKEN in environment (.env)")

    app = ApplicationBuilder().token(TOKEN).build()

    app.add_handler(CommandHandler("start", start))
    app.add_handler(CommandHandler("help", help_cmd))
    app.add_handler(CommandHandler("menu", menu_cmd))
    app.add_handler(CommandHandler("lang", lang_cmd))
    app.add_handler(CallbackQueryHandler(on_callback))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, on_text))

    logger.info("IC bot is running (polling)...")
    app.run_polling(drop_pending_updates=True)

if __name__ == "__main__":
    main()
