import os
import asyncio
from dotenv import load_dotenv
from fastapi import FastAPI, Request, Form, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from bot.database import (
    init_db, get_chats_by_status, get_chat_with_messages,
    update_chat_status, save_message,
)

load_dotenv()

app = FastAPI(title="AsakaBank Admin")
templates = Jinja2Templates(directory="admin/templates")

try:
    app.mount("/static", StaticFiles(directory="admin/static"), name="static")
except Exception:
    pass


@app.on_event("startup")
async def startup():
    await init_db()


# ── Bot instance for sending messages ─────────────────
def get_bot():
    from aiogram import Bot
    return Bot(token=os.getenv("BOT_TOKEN"))


# ── Pages ──────────────────────────────────────────────
@app.get("/", response_class=HTMLResponse)
async def index(request: Request, status: str = "all"):
    chats = await get_chats_by_status(status)
    return templates.TemplateResponse("index.html", {
        "request": request,
        "chats": chats,
        "active_filter": status,
    })


@app.get("/chat/{chat_id}", response_class=HTMLResponse)
async def chat_view(request: Request, chat_id: int):
    chat, messages = await get_chat_with_messages(chat_id)
    if not chat:
        raise HTTPException(404, "Chat not found")
    return templates.TemplateResponse("chat.html", {
        "request": request,
        "chat": chat,
        "messages": messages,
    })


# ── API endpoints ──────────────────────────────────────
@app.post("/api/reply/{chat_id}")
async def api_reply(chat_id: int, request: Request):
    data = await request.json()
    text = data.get("text", "").strip()
    if not text:
        raise HTTPException(400, "Empty message")

    chat_data, _ = await get_chat_with_messages(chat_id)
    if not chat_data:
        raise HTTPException(404, "Chat not found")

    await save_message(chat_id, "staff", text)

    # Update status to active if new
    if chat_data["status"] == "new":
        await update_chat_status(chat_id, "active")

    # Send via Telegram
    user_id = chat_data["uid"]
    from bot.texts import t
    lang = chat_data.get("language", "uz")
    try:
        b = get_bot()
        await b.send_message(user_id, f"{t(lang, 'staff_replied')}\n\n{text}")
        await b.session.close()
    except Exception as e:
        print(f"Telegram send error: {e}")

    return JSONResponse({"ok": True, "text": text})


@app.post("/api/close/{chat_id}")
async def api_close(chat_id: int):
    chat_data, _ = await get_chat_with_messages(chat_id)
    if not chat_data:
        raise HTTPException(404)

    await update_chat_status(chat_id, "closed")

    user_id = chat_data["uid"]
    from bot.texts import t
    lang = chat_data.get("language", "uz")
    try:
        b = get_bot()
        await b.send_message(user_id, t(lang, "chat_closed_user"))
        await b.session.close()
    except Exception as e:
        print(f"Telegram send error: {e}")

    return JSONResponse({"ok": True})


@app.get("/api/chats")
async def api_chats(status: str = "all"):
    chats = await get_chats_by_status(status)
    # Convert datetime to string for JSON
    for c in chats:
        for k, v in c.items():
            if hasattr(v, "isoformat"):
                c[k] = v.isoformat()
    return JSONResponse(chats)


@app.get("/api/chat/{chat_id}/messages")
async def api_messages(chat_id: int):
    _, messages = await get_chat_with_messages(chat_id)
    for m in messages:
        for k, v in m.items():
            if hasattr(v, "isoformat"):
                m[k] = v.isoformat()
    return JSONResponse(messages)
