import json
from collections import defaultdict
from pathlib import Path

from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from peewee import JOIN


router = APIRouter()

templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates"))


@router.get("/", response_class=HTMLResponse)
def dashboard(request: Request):
    from imptune.db.models import Printer

    recent_printers = list(
        Printer.select().order_by(Printer.created_at.desc()).limit(5)
    )
    recent_packages = list(
        Printer.select()
        .where(Printer.driver.is_null(False))
        .order_by(Printer.created_at.desc())
        .limit(5)
    )
    return templates.TemplateResponse(
        request=request,
        name="dashboard.html",
        context={
            "recent_printers": recent_printers,
            "recent_packages": recent_packages,
        },
    )


@router.get("/drivers", response_class=HTMLResponse)
def drivers_page(request: Request):
    from imptune.db.models import Driver

    drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
    driver_data = []
    for d in drivers:
        names = json.loads(d.driver_desc) if d.driver_desc else []
        driver_data.append({"driver": d, "names": names})
    return templates.TemplateResponse(
        request=request,
        name="drivers.html",
        context={"driver_data": driver_data},
    )


@router.get("/printers", response_class=HTMLResponse)
def printers_page(request: Request):
    from imptune.db.models import Client, Driver, Printer

    query = (
        Printer.select(Printer, Client)
        .join(Client, JOIN.LEFT_OUTER)
        .order_by(Client.name, Printer.name)
    )
    grouped: dict[str, list] = defaultdict(list)
    for p in query:
        client_name = p.client.name if p.client_id else "Unassigned"
        grouped[client_name].append(p)

    clients = list(Client.select().order_by(Client.name))

    all_drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
    driver_data = []
    for d in all_drivers:
        names = json.loads(d.driver_desc) if d.driver_desc else []
        driver_data.append({"driver": d, "names": names})

    return templates.TemplateResponse(
        request=request,
        name="printers.html",
        context={
            "grouped": grouped,
            "clients": clients,
            "driver_data": driver_data,
        },
    )


@router.get("/printers/{printer_id}", response_class=HTMLResponse)
def printer_detail(request: Request, printer_id: int):
    from imptune.db.models import Client, Driver, Icon, Printer

    printer = (
        Printer.select(Printer, Client, Driver)
        .join(Client, JOIN.LEFT_OUTER)
        .switch(Printer)
        .join(Driver, JOIN.LEFT_OUTER)
        .where(Printer.id == printer_id)
        .first()
    )
    if printer is None:
        return HTMLResponse(
            content="<h1>404 Not Found</h1><p>Printer not found.</p>",
            status_code=404,
        )

    driver_names: list[str] = []
    if printer.driver_id and printer.driver.driver_desc:
        driver_names = json.loads(printer.driver.driver_desc)

    has_driver = printer.driver_id is not None and bool(driver_names)
    icon = Icon.get_or_none(Icon.printer == printer_id)

    install_cmd = "powershell.exe -ExecutionPolicy Bypass -File install.ps1"
    uninstall_cmd = "powershell.exe -ExecutionPolicy Bypass -File uninstall.ps1"

    return templates.TemplateResponse(
        request=request,
        name="printer_detail.html",
        context={
            "printer": printer,
            "driver_names": driver_names,
            "has_driver": has_driver,
            "has_icon": icon is not None,
            "install_cmd": install_cmd,
            "uninstall_cmd": uninstall_cmd,
        },
    )


@router.get("/clients", response_class=HTMLResponse)
def clients_page(request: Request):
    from imptune.db.models import Client

    clients = list(Client.select().order_by(Client.name))
    return templates.TemplateResponse(
        request=request,
        name="clients.html",
        context={"clients": clients},
    )


@router.get("/packages", response_class=HTMLResponse)
def packages_page(request: Request):
    from imptune.db.models import Client, Driver, Printer

    printers = list(
        Printer.select(Printer, Client, Driver)
        .join(Client, JOIN.LEFT_OUTER)
        .switch(Printer)
        .join(Driver, JOIN.LEFT_OUTER)
        .where(Printer.driver.is_null(False))
        .order_by(Printer.name)
    )
    return templates.TemplateResponse(
        request=request,
        name="packages.html",
        context={"printers": printers},
    )
