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

router = APIRouter(dependencies=[Depends(require_roles("super_admin", "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"))

@router.get("/service-packages", response_class=HTMLResponse)
async def service_packages_page(request: Request, db: AsyncSession = Depends(get_db)):
    packages = (await db.execute(select(ServicePackage).order_by(ServicePackage.is_active.desc(), ServicePackage.name))).scalars().all()
    return templates.TemplateResponse(request=request, name="service_packages.html", context={"packages": packages})

@router.post("/service-packages")
async def create_service_package(
    code: str = Form(...), name: str = Form(...), service_type: str = Form("bulanan_ppp"),
    service_mode: str = Form("private_pppoe"), price: int = Form(...),
    mikrotik_profile: str = Form(""), service_vlan: int = Form(175),
    pppoe_vlan: int = Form(100), hotspot_vlan: int = Form(150),
    iptv_vlan: int = Form(15), olt_vlan_profile: str = Form("bnbv1009"),
    db: AsyncSession = Depends(get_db),
):
    exists = await db.scalar(select(ServicePackage).where(ServicePackage.code == code.strip()))
    if not exists:
        db.add(ServicePackage(code=code.strip(), name=name.strip(), service_type=service_type,
            service_mode=service_mode, price=price, mikrotik_profile=mikrotik_profile.strip() or None,
            service_vlan=service_vlan, pppoe_vlan=pppoe_vlan, hotspot_vlan=hotspot_vlan,
            iptv_vlan=iptv_vlan, olt_vlan_profile=olt_vlan_profile.strip() or None))
        await db.commit()
    return RedirectResponse("/service-packages", status_code=303)

@router.post("/service-packages/{package_id}/edit")
async def edit_service_package(
    package_id: int, code: str = Form(...), name: str = Form(...), service_type: str = Form(...),
    service_mode: str = Form(...), price: int = Form(...), mikrotik_profile: str = Form(""),
    service_vlan: int = Form(175), pppoe_vlan: int = Form(100), hotspot_vlan: int = Form(150),
    iptv_vlan: int = Form(15),
    olt_vlan_profile: str = Form("bnbv1009"), is_active: str = Form("1"),
    db: AsyncSession = Depends(get_db),
):
    package = await db.get(ServicePackage, package_id)
    if not package:
        raise HTTPException(404, "Paket tidak ditemukan")
    normalized_code = code.strip()
    duplicate = await db.scalar(select(ServicePackage).where(ServicePackage.code == normalized_code, ServicePackage.id != package_id))
    if duplicate:
        raise HTTPException(409, "Kode paket sudah digunakan")
    package.code = normalized_code
    package.name = name.strip()
    package.service_type = service_type
    package.service_mode = service_mode
    package.price = price
    package.mikrotik_profile = mikrotik_profile.strip() or None
    package.service_vlan = service_vlan
    package.iptv_vlan = iptv_vlan
    package.olt_vlan_profile = olt_vlan_profile.strip() or None
    package.is_active = is_active == "1"
    await db.commit()
    return RedirectResponse("/service-packages", status_code=303)

@router.post("/service-packages/{package_id}/delete")
async def delete_service_package(package_id: int, db: AsyncSession = Depends(get_db)):
    package = await db.get(ServicePackage, package_id)
    if not package:
        raise HTTPException(404, "Paket tidak ditemukan")
    used = await db.scalar(select(func.count(Customer.id)).where(Customer.service_package_id == package_id)) or 0
    if used:
        package.is_active = False
    else:
        await db.delete(package)
    await db.commit()
    return RedirectResponse("/service-packages", status_code=303)
