"""Script download endpoints — generates and serves PowerShell scripts for a printer."""
import json

from fastapi import APIRouter
from fastapi.responses import PlainTextResponse

from imptune.db.models import Printer
from imptune.generators.script_generator import render_detect, render_install, render_uninstall

router = APIRouter(prefix="/printers")


def _get_printer_and_driver(printer_id: int):
    """Fetch printer and validate driver — returns (printer, driver_name) or PlainTextResponse error."""
    printer = Printer.get_or_none(Printer.id == printer_id)
    if printer is None:
        return None, PlainTextResponse("Printer not found", status_code=404)

    driver = printer.driver
    if driver is None:
        return None, PlainTextResponse("No driver assigned", status_code=422)

    if not driver.inf_filename:
        return None, PlainTextResponse("Driver has no INF file", status_code=422)

    if not driver.driver_desc:
        return None, PlainTextResponse("Driver has no description", status_code=422)

    try:
        desc_list = json.loads(driver.driver_desc)
        driver_name = desc_list[0]
    except (json.JSONDecodeError, IndexError, TypeError):
        return None, PlainTextResponse("Driver description is invalid", status_code=422)

    return (printer, driver, driver_name), None


def _install_response(printer_id: int):
    result, error = _get_printer_and_driver(printer_id)
    if error is not None:
        return error
    printer, driver, driver_name = result
    rendered = render_install(
        printer_name=printer.name,
        ip_address=printer.ip_address,
        port_name=printer.port_name,
        driver_name=driver_name,
        inf_filename=driver.inf_filename,
        duplex_mode=printer.duplex_mode,
        color_mode=printer.color_mode,
        paper_size=printer.paper_size,
        collate=printer.collate,
    )
    return PlainTextResponse(
        content=rendered,
        headers={"Content-Disposition": 'attachment; filename="install.ps1"'},
    )


def _uninstall_response(printer_id: int):
    result, error = _get_printer_and_driver(printer_id)
    if error is not None:
        return error
    printer, driver, driver_name = result
    rendered = render_uninstall(
        printer_name=printer.name,
        driver_name=driver_name,
        port_name=printer.port_name,
    )
    return PlainTextResponse(
        content=rendered,
        headers={"Content-Disposition": 'attachment; filename="uninstall.ps1"'},
    )


def _detect_response(printer_id: int):
    result, error = _get_printer_and_driver(printer_id)
    if error is not None:
        return error
    printer, driver, driver_name = result
    rendered = render_detect(printer_name=printer.name)
    return PlainTextResponse(
        content=rendered,
        headers={"Content-Disposition": 'attachment; filename="detect.ps1"'},
    )


@router.get("/{printer_id}/scripts/install")
def get_install_script(printer_id: int):
    """Download the PowerShell install script for a printer."""
    return _install_response(printer_id)


@router.get("/{printer_id}/scripts/install.ps1")
def get_install_script_ps1(printer_id: int):
    """Download the PowerShell install script for a printer (.ps1 alias)."""
    return _install_response(printer_id)


@router.get("/{printer_id}/scripts/uninstall")
def get_uninstall_script(printer_id: int):
    """Download the PowerShell uninstall script for a printer."""
    return _uninstall_response(printer_id)


@router.get("/{printer_id}/scripts/uninstall.ps1")
def get_uninstall_script_ps1(printer_id: int):
    """Download the PowerShell uninstall script for a printer (.ps1 alias)."""
    return _uninstall_response(printer_id)


@router.get("/{printer_id}/scripts/detect")
def get_detect_script(printer_id: int):
    """Download the PowerShell detection script for a printer."""
    return _detect_response(printer_id)


@router.get("/{printer_id}/scripts/detect.ps1")
def get_detect_script_ps1(printer_id: int):
    """Download the PowerShell detection script for a printer (.ps1 alias)."""
    return _detect_response(printer_id)
