# -*- 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 y mapa (según lo que pediste)
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"
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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)
    # Fallbacks (incluyen {WEBSITE_URL}, {ADDRESS}, {MAP_URL})
    if lang == "es":
        return {
            "horario|clases|zoom|horarios|schedule":
                "🗓️ Los horarios y enlaces se actualizan con frecuencia. Consulta: {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":
                "📚 Conoce los programas y cursos vigentes: {WEBSITE_URL}.",
            "contacto|tel[eé]fono|email|correo":
                "📬 Contáctanos desde la web oficial: {WEBSITE_URL}.",
            "costos|precio|fees|pagar":
                "💵 La información sobre costos/becas (si aplican) está en: {WEBSITE_URL}."
        }
    else:
        return {
            "schedule|class|zoom|time|when":
                "🗓️ Schedules and links change often. Please 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":
                "📚 Current programs and courses: {WEBSITE_URL}.",
            "contact|email|phone":
                "📬 Please reach us via the official site: {WEBSITE_URL}.",
            "cost|price|fees|pay":
                "💵 Info about costs/scholarships (if applicable): {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

# Cache de patrones por idioma
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":
        msg = ("📚 Programas actuales y detalles: {WEBSITE_URL}"
               if lang == "es" else
               "📚 Current programs and details: {WEBSITE_URL}")
        await query.edit_message_text(msg.replace("{WEBSITE_URL}", WEBSITE_URL))

    elif data == "schedule":
        msg = ("🗓️ Los horarios y enlaces (Zoom/presencial) cambian frecuentemente. Revisa: {WEBSITE_URL}."
               if lang == "es" else
               "🗓️ Schedules and links (Zoom/in-person) change often. Please check: {WEBSITE_URL}.")
        await query.edit_message_text(msg.replace("{WEBSITE_URL}", WEBSITE_URL))

    elif data == "location":
        # Mostrar dirección + botones a mapa y sitio
        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
            return (ans
                    .replace("{WEBSITE_URL}", WEBSITE_URL)
                    .replace("{MAP_URL}", MAP_URL)
                    .replace("{ADDRESS}", addr))
    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)

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()
