from fastapi import APIRouter, Request, Form, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.core.database import get_db
from app.models.models import VoucherAgent
from app.core.security import require_roles
import os
import math

router = APIRouter(dependencies=[Depends(require_roles("agen_voucher", "admin_cs"))])
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "app/templates"))


def _agent_form_error(message, name, phone, area, nama_isp, domain_isp, prefix):
    """Kembalikan URL halaman agen dengan pesan error dan isian yang tadi diketik."""
    from urllib.parse import urlencode
    params = {
        "error": message,
        "name": name or "",
        "phone": phone or "",
        "area": area or "",
        "nama_isp": nama_isp or "",
        "domain_isp": domain_isp or "",
        "prefix": prefix or "",
    }
    return "/voucher-agents?" + urlencode(params)

@router.get("/voucher-agents", response_class=HTMLResponse)
async def voucher_agents(request: Request, db: AsyncSession = Depends(get_db), page: int = 1):
    per_page = 5
    total_count = await db.scalar(select(func.count(VoucherAgent.id)).where(VoucherAgent.is_active == True))
    total_pages = math.ceil(total_count / per_page)
    
    result = await db.execute(
        select(VoucherAgent)
        .where(VoucherAgent.is_active == True)
        .order_by(VoucherAgent.area, VoucherAgent.name)
        .limit(per_page)
        .offset((page - 1) * per_page)
    )
    agents = result.scalars().all()
    
    return templates.TemplateResponse(request=request, name="voucher_agents.html", context={
        "agents": agents, 
        "page": page, 
        "total_pages": total_pages,
        "error": request.query_params.get("error"),
        "old": {
            "name": request.query_params.get("name", ""),
            "phone": request.query_params.get("phone", ""),
            "area": request.query_params.get("area", ""),
            "nama_isp": request.query_params.get("nama_isp", ""),
            "domain_isp": request.query_params.get("domain_isp", ""),
            "prefix": request.query_params.get("prefix", ""),
        },
        "taken_prefixes": [a.prefix for a in agents if a.prefix],
    })

@router.post("/voucher-agents")
async def add_voucher_agent(
    name: str = Form(...),
    phone: str = Form(...),
    area: str = Form(...),
    nama_isp: str = Form(None),
    domain_isp: str = Form(None),
    prefix: str = Form(None),
    db: AsyncSession = Depends(get_db)
):
    clean_prefix = prefix.strip() if prefix and prefix.strip() else None

    # Prefiks bersifat unik (case-insensitive) dan dipakai untuk mengenali
    # voucher agen. Tolak lebih awal dengan pesan jelas, bukan IntegrityError 500.
    if clean_prefix:
        clash = await db.scalar(
            select(VoucherAgent).where(func.lower(VoucherAgent.prefix) == clean_prefix.lower())
        )
        if clash:
            return RedirectResponse(
                url=_agent_form_error(
                    f"Prefix '{clean_prefix}' sudah dipakai agen {clash.name}. Gunakan prefix lain.",
                    name, phone, area, nama_isp, domain_isp, clean_prefix,
                ),
                status_code=303,
            )

    db.add(VoucherAgent(
        name=name.strip(),
        phone=phone.strip(),
        area=area.strip(),
        nama_isp=nama_isp.strip() if nama_isp else None,
        domain_isp=domain_isp.strip() if domain_isp else None,
        prefix=clean_prefix,
        commission_rate=20
    ))
    await db.commit()
    return RedirectResponse(url="/voucher-agents", status_code=303)

@router.post("/voucher-agents/{agent_id}/delete")
async def delete_voucher_agent(
    agent_id: int,
    db: AsyncSession = Depends(get_db)
):
    agent = await db.get(VoucherAgent, agent_id)
    if agent:
        agent.is_active = False
        await db.commit()
    return RedirectResponse(url="/voucher-agents", status_code=303)
