"""
app.py — ABA PayWay Stream Alert (Web Edition)

Run with:  python app.py
Dashboard: http://127.0.0.1:5000/
Overlays:  http://127.0.0.1:5000/overlay/alert/<theme>
           http://127.0.0.1:5000/overlay/leaderboard/<theme>
"""
import os
import time

from flask import Flask, render_template, request, jsonify, redirect, url_for, send_from_directory
from flask_socketio import SocketIO
from werkzeug.utils import secure_filename

import storage
from telegram_worker import TelegramManager, EDGE_TTS_AVAILABLE

BASE_DIR = os.path.dirname(__file__)
UPLOAD_DIR = os.path.join(BASE_DIR, "static", "uploads")
os.makedirs(UPLOAD_DIR, exist_ok=True)

ALERT_THEMES = [
    {"id": "gold", "name": "Gold Card", "blurb": "Warm navy card, gold glow, crown for #1 donor."},
    {"id": "neon", "name": "Neon Pulse", "blurb": "Dark cyberpunk strip with animated neon edges."},
    {"id": "minimal", "name": "Minimal Ticket", "blurb": "Clean paper-ticket style, quiet and fast."},
    {"id": "cute", "name": "Cute Pastel", "blurb": "Rounded pastel card with sparkles — soft & friendly."},
    {"id": "esports", "name": "Esports", "blurb": "Angled red/black tournament-style banner."},
]
LEADERBOARD_THEMES = [
    {"id": "gold", "name": "Gold Rows", "blurb": "Ranked rows with crown / diamond / star icons."},
    {"id": "neon", "name": "Neon Panel", "blurb": "Vertical neon-bar ranking panel."},
    {"id": "cute", "name": "Cute Pastel", "blurb": "Rounded pastel ranking cards with emoji medals."},
    {"id": "esports", "name": "Esports", "blurb": "Angled red/black tournament-style ranking panel."},
]

VOICES = [
    ("en-US-JennyNeural", "🇺🇸 English (US) — Jenny (Female)"),
    ("en-US-ChristopherNeural", "🇺🇸 English (US) — Christopher (Male)"),
    ("en-US-AriaNeural", "🇺🇸 English (US) — Aria (Female)"),
    ("en-GB-SoniaNeural", "🇬🇧 English (UK) — Sonia (Female)"),
    ("en-GB-RyanNeural", "🇬🇧 English (UK) — Ryan (Male)"),
    ("en-AU-NatashaNeural", "🇦🇺 English (AU) — Natasha (Female)"),
    ("km-KH-SreymomNeural", "🇰🇭 Khmer — Sreymom (Female)"),
    ("km-KH-PisethNeural", "🇰🇭 Khmer — Piseth (Male)"),
    ("th-TH-PremwadeeNeural", "🇹🇭 Thai — Premwadee (Female)"),
    ("th-TH-NiwatNeural", "🇹🇭 Thai — Niwat (Male)"),
    ("vi-VN-HoaiMyNeural", "🇻🇳 Vietnamese — HoaiMy (Female)"),
    ("vi-VN-NamMinhNeural", "🇻🇳 Vietnamese — NamMinh (Male)"),
    ("zh-CN-XiaoxiaoNeural", "🇨🇳 Chinese — Xiaoxiao (Female)"),
    ("zh-CN-YunxiNeural", "🇨🇳 Chinese — Yunxi (Male)"),
    ("ja-JP-NanamiNeural", "🇯🇵 Japanese — Nanami (Female)"),
    ("ko-KR-SunHiNeural", "🇰🇷 Korean — SunHi (Female)"),
    ("fr-FR-DeniseNeural", "🇫🇷 French — Denise (Female)"),
    ("de-DE-KatjaNeural", "🇩🇪 German — Katja (Female)"),
]

app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "aba-stream-alert-dev-key")
socketio = SocketIO(app, async_mode="threading", cors_allowed_origins="*")


def emit_callback(event, payload):
    socketio.emit(event, payload)


def log_callback(msg):
    print(msg, flush=True)
    socketio.emit("log", {"msg": msg, "ts": int(time.time() * 1000)})


tg = TelegramManager(emit_callback=emit_callback, log_callback=log_callback)


# ── dashboard / login pages ──────────────────────────────────────────

@app.route("/")
def dashboard():
    cfg = storage.load_config()
    return render_template(
        "dashboard.html", cfg=cfg, status=tg.status, me=tg.me_label,
        alert_themes=ALERT_THEMES, leaderboard_themes=LEADERBOARD_THEMES,
        voices=VOICES, edge_tts_available=EDGE_TTS_AVAILABLE,
        recent=storage.load_recent(20), donors=storage.load_donors(),
        host_url=request.host_url.rstrip("/"),
    )


@app.route("/login")
def login_page():
    if tg.status not in ("logged_out", "code_needed", "password_needed", "qr_pending", "qr_expired"):
        return redirect(url_for("dashboard"))
    return render_template("login.html", status=tg.status)


# ── auth API (phone) ─────────────────────────────────────────────────

@app.post("/api/auth/phone/start")
def api_phone_start():
    phone = (request.json or {}).get("phone", "").strip()
    if not phone:
        return jsonify({"ok": False, "error": "Phone number required."}), 400
    return jsonify(tg.start_phone_login(phone))


@app.post("/api/auth/phone/code")
def api_phone_code():
    code = (request.json or {}).get("code", "").strip()
    return jsonify(tg.submit_code(code))


@app.post("/api/auth/phone/password")
def api_phone_password():
    pw = (request.json or {}).get("password", "")
    return jsonify(tg.submit_password(pw))


# ── auth API (QR) ────────────────────────────────────────────────────

@app.post("/api/auth/qr/start")
def api_qr_start():
    return jsonify(tg.start_qr_login())


@app.get("/api/auth/qr/status")
def api_qr_status():
    return jsonify(tg.qr_status())


@app.post("/api/auth/logout")
def api_logout():
    tg.logout()
    return jsonify({"ok": True})


# ── groups ────────────────────────────────────────────────────────────

@app.get("/api/groups")
def api_groups():
    try:
        groups = tg.list_groups()
        return jsonify({"ok": True, "groups": groups})
    except Exception as e:
        return jsonify({"ok": False, "error": str(e)}), 500


# ── listener control ─────────────────────────────────────────────────

@app.post("/api/listener/start")
def api_listener_start():
    data = request.json or {}
    group_id = str(data.get("group_id", "")).strip()
    group_title = data.get("group_title", "")
    source_username = data.get("source_username", "PayWayByABA_bot")
    if not group_id:
        return jsonify({"ok": False, "error": "Choose a group first."}), 400

    cfg = storage.save_config({
        "group_id": group_id, "group_title": group_title,
        "source_username": source_username,
    })
    result = tg.start_listener(group_id, source_username, cfg.get("khr_rate", 4000), cfg.get("debug", True))
    return jsonify(result)


@app.post("/api/listener/stop")
def api_listener_stop():
    return jsonify(tg.stop_listener())


@app.get("/api/status")
def api_status():
    return jsonify({
        "status": tg.status, "me": tg.me_label,
        "group_id": storage.load_config().get("group_id"),
    })


# ── settings ──────────────────────────────────────────────────────────

@app.post("/api/settings")
def api_settings():
    data = request.json or {}
    allowed = {
        "khr_rate", "alert_delay", "alert_duration", "alert_theme", "leaderboard_theme",
        "debug", "source_username", "sound_volume", "tts_enabled", "tts_voice",
        "tts_format", "tts_rate", "tts_volume", "tts_pitch",
    }
    patch = {k: v for k, v in data.items() if k in allowed}
    cfg = storage.save_config(patch)
    return jsonify({"ok": True, "config": cfg})


@app.post("/api/upload/logo")
def api_upload_logo():
    f = request.files.get("file")
    if not f:
        return jsonify({"ok": False, "error": "No file."}), 400
    fname = "logo_" + secure_filename(f.filename)
    path = os.path.join(UPLOAD_DIR, fname)
    f.save(path)
    storage.save_config({"logo_file": fname})
    return jsonify({"ok": True, "url": f"/static/uploads/{fname}"})


@app.post("/api/upload/sound")
def api_upload_sound():
    f = request.files.get("file")
    if not f:
        return jsonify({"ok": False, "error": "No file."}), 400
    fname = "sound_" + secure_filename(f.filename)
    path = os.path.join(UPLOAD_DIR, fname)
    f.save(path)
    storage.save_config({"sound_file": fname})
    return jsonify({"ok": True, "url": f"/static/uploads/{fname}"})


# ── test / leaderboard utilities ────────────────────────────────────

@app.post("/api/test-alert")
def api_test_alert():
    data = request.json or {}
    tg.queue_test_alert(
        sender=data.get("sender", "MEN SOKRAYUK"),
        amount=data.get("amount", "$1.00"),
        is_top=bool(data.get("is_top", False)),
    )
    return jsonify({"ok": True})


@app.post("/api/tts/preview")
def api_tts_preview():
    data = request.json or {}
    text = data.get("text", "Thank you for your donation!")
    voice = data.get("voice", "en-US-JennyNeural")
    rate = int(data.get("rate", 0))
    volume = int(data.get("volume", 10))
    pitch = int(data.get("pitch", 0))
    return jsonify(tg.preview_tts(text, voice, rate, volume, pitch))


@app.post("/api/leaderboard/reset")
def api_leaderboard_reset():
    storage.reset_donors()
    socketio.emit("leaderboard_update", {"donors": []})
    return jsonify({"ok": True})


@app.get("/api/leaderboard")
def api_leaderboard():
    return jsonify({"donors": storage.load_donors()})


@app.get("/api/recent")
def api_recent():
    return jsonify({"items": storage.load_recent(20)})


# ── overlay pages (add these URLs as OBS Browser Sources) ──────────

@app.route("/overlay/alert/<theme>")
def overlay_alert(theme):
    cfg = storage.load_config()
    valid = {t["id"] for t in ALERT_THEMES}
    theme = theme if theme in valid else "gold"
    return render_template(f"overlay_alert_{theme}.html", cfg=cfg)


@app.route("/overlay/leaderboard/<theme>")
def overlay_leaderboard(theme):
    cfg = storage.load_config()
    valid = {t["id"] for t in LEADERBOARD_THEMES}
    theme = theme if theme in valid else "gold"
    return render_template(f"overlay_leaderboard_{theme}.html", cfg=cfg,
                            donors=storage.load_donors())


@app.get("/static/uploads/<path:filename>")
def uploaded_file(filename):
    return send_from_directory(UPLOAD_DIR, filename)


if __name__ == "__main__":
    print("=" * 60)
    print(" ABA PayWay Stream Alert — Web Edition")
    print(" Dashboard:   http://127.0.0.1:5000/")
    print(" Alert URL:   http://127.0.0.1:5000/overlay/alert/gold")
    print(" Leaderboard: http://127.0.0.1:5000/overlay/leaderboard/gold")
    print("=" * 60)
    socketio.run(app, host="0.0.0.0", port=5000, debug=True, use_reloader=False, allow_unsafe_werkzeug=True)
