# -*- 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")
WEBSITE_URL = "https://www.newintlcenter.org"

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"  # You can change this

@dataclass
class Matcher:
    pattern: Pattern
    answer: str

def load_faq(lang: str) -> Dict[str, str]:
    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 embedded into the zip during creation
    if lang == "es":
        return {
            "horario|clases|zoom|horarios|schedule": "🗓️ Los horarios y enlaces se actualizan con frecuencia. Consulta la web oficial: {WEBSITE_URL}. Si eres estudiante, verifica también tu grupo de WhatsApp o el mensaje del profesor.",
            "inscripci[oó]n|registrarme|matr[ií]cula|aplicar|apply": "📝 La inscripción y requisitos están explicados en el sitio oficial: {WEBSITE_URL}. Si necesitas ayuda, responde *Inscripción* aquí y te guiamos paso a paso.",
            "direcci[oó]n|location|ubicaci[oó]n|address": "📍 Consulta sedes/ubicaciones y cómo llegar en: {WEBSITE_URL}.",
            "programa|programas|courses|clases de ingl[eé]s": "📚 Conoce los programas y cursos vigentes en: {WEBSITE_URL}.",
            "contacto|tel[eé]fono|email|correo": "📬 Contáctanos desde la página oficial: {WEBSITE_URL}. Si eres estudiante actual, también puedes escribir a tu profesor o coordinador.",
            "cursos|precio|fees|pagar": "💵 La información sobre costos/becas (si aplican) se publica en: {WEBSITE_URL}. Para casos específicos, consúltalo con coordinación."
        }
    else:
        return {
            "schedule|class|zoom|time|when": "🗓️ Schedules and links change often. Please check the official website: {WEBSITE_URL}. If you’re a current student, check your WhatsApp group or your teacher’s message.",
            "apply|enroll|registration": "📝 Enrollment and requirements are explained on the official website: {WEBSITE_URL}. If you need help, reply *Apply* here and we’ll guide you step by step.",
            "location|address|where": "📍 See campuses/locations and directions at: {WEBSITE_URL}.",
            "program|programs|course|english class|esl": "📚 Learn about current programs and courses: {WEBSITE_URL}.",
            "contact|email|phone": "📬 Please reach us via the official contact page: {WEBSITE_URL}. If you’re a current student, you can also message your teacher or coordinator.",
            "cost|price|fees|pay": "💵 Info about costs/scholarships (if applicable) is published at: {WEBSITE_URL}. For specific cases, ask coordination."
        }

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 compiled matchers per language
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": "Puedes escribir tu pregunta en español (ej: *horarios*, *inscripción*, *ubicación*). Usa /menu para ver opciones rápidas o /lang para cambiar de idioma.",
        "help_en": "You can type your question in English (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)

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:
        # show buttons
        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) se actualizan 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":
        msg = ("📍 Mira sedes/ubicación y cómo llegar: {WEBSITE_URL}."
               if lang == "es" else
               "📍 See campuses/location and directions: {WEBSITE_URL}.")
        await query.edit_message_text(msg.replace("{WEBSITE_URL}", WEBSITE_URL))
    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:
    for m in MATCHERS[lang]:
        if m.pattern.search(text):
            return m.answer.replace("{WEBSITE_URL}", WEBSITE_URL)
    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()
