"""
Prep Zones router.

GET    /api/prep-zones              list all prep zones (with printer ids)
POST   /api/prep-zones              create a prep zone
PUT    /api/prep-zones/{id}         update name / description / printer assignments / all settings
DELETE /api/prep-zones/{id}         delete a prep zone
"""
import json
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional

from database import get_db
from models.prep_zone import PrepZone
from models.printer import Printer
from routers.deps import require_manager
from models.user import User

router = APIRouter()


class PrepZoneCreate(BaseModel):
    name: str
    description: Optional[str] = None
    notification_name: Optional[str] = None

    # Printer routing
    printer_ids: List[int] = []          # all printers (master + secondary)
    master_printer_id: Optional[int] = None
    auto_print: str = 'none'             # 'none' | 'master' | 'all'
    master_copies: int = 1
    secondary_copies: int = 1

    # Ticket formatting
    sort_items_by: str = 'order_time'    # 'order_time' | 'item_count' | 'alpha'
    group_by_category: bool = False
    category_order: List[int] = []
    print_checkboxes: bool = False

    # KDS bypass / auto-progression
    bypass_pending: bool = False
    bypass_kds: bool = False
    auto_ready_to_served: bool = False


class PrepZoneUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    notification_name: Optional[str] = None

    # Printer routing
    printer_ids: Optional[List[int]] = None
    master_printer_id: Optional[int] = None
    auto_print: Optional[str] = None
    master_copies: Optional[int] = None
    secondary_copies: Optional[int] = None

    # Ticket formatting
    sort_items_by: Optional[str] = None
    group_by_category: Optional[bool] = None
    category_order: Optional[List[int]] = None
    print_checkboxes: Optional[bool] = None

    # KDS bypass / auto-progression
    bypass_pending: Optional[bool] = None
    bypass_kds: Optional[bool] = None
    auto_ready_to_served: Optional[bool] = None


def _zone_out(zone: PrepZone) -> dict:
    all_printer_ids = [p.id for p in zone.printers]
    secondary_ids = [pid for pid in all_printer_ids if pid != zone.master_printer_id]
    return {
        "id":                  zone.id,
        "name":                zone.name,
        "description":         zone.description,
        "notification_name":   zone.notification_name,

        # Printer routing
        "printer_ids":         all_printer_ids,
        "printers":            [{"id": p.id, "name": p.name} for p in zone.printers],
        "master_printer_id":   zone.master_printer_id,
        "secondary_printer_ids": secondary_ids,
        "auto_print":          zone.auto_print or 'none',
        "master_copies":       zone.master_copies or 1,
        "secondary_copies":    zone.secondary_copies or 1,

        # Ticket formatting
        "sort_items_by":       zone.sort_items_by or 'order_time',
        "group_by_category":   bool(zone.group_by_category),
        "category_order":      json.loads(zone.category_order) if zone.category_order else [],
        "print_checkboxes":    bool(zone.print_checkboxes),

        # KDS bypass / auto-progression
        "bypass_pending":      bool(zone.bypass_pending),
        "bypass_kds":          bool(zone.bypass_kds),
        "auto_ready_to_served": bool(zone.auto_ready_to_served),
    }


@router.get("")
def list_prep_zones(
    db: Session = Depends(get_db),
    user: User = Depends(require_manager),
):
    zones = db.query(PrepZone).order_by(PrepZone.id).all()
    return [_zone_out(z) for z in zones]


@router.post("")
def create_prep_zone(
    body: PrepZoneCreate,
    db: Session = Depends(get_db),
    user: User = Depends(require_manager),
):
    zone = PrepZone(
        name=body.name,
        description=body.description,
        notification_name=body.notification_name,
        master_printer_id=body.master_printer_id,
        auto_print=body.auto_print,
        master_copies=max(1, body.master_copies),
        secondary_copies=max(1, body.secondary_copies),
        print_copies=max(1, body.master_copies),  # keep legacy field in sync
        sort_items_by=body.sort_items_by,
        group_by_category=1 if body.group_by_category else 0,
        category_order=json.dumps(body.category_order),
        print_checkboxes=1 if body.print_checkboxes else 0,
        bypass_pending=1 if (body.bypass_pending or body.bypass_kds) else 0,
        bypass_kds=1 if body.bypass_kds else 0,
        auto_ready_to_served=1 if body.auto_ready_to_served else 0,
    )
    if body.printer_ids:
        printers = db.query(Printer).filter(Printer.id.in_(body.printer_ids)).all()
        zone.printers = printers
    db.add(zone)
    db.commit()
    db.refresh(zone)
    return _zone_out(zone)


@router.put("/{zone_id}")
def update_prep_zone(
    zone_id: int,
    body: PrepZoneUpdate,
    db: Session = Depends(get_db),
    user: User = Depends(require_manager),
):
    zone = db.query(PrepZone).filter(PrepZone.id == zone_id).first()
    if not zone:
        raise HTTPException(status_code=404, detail="Prep zone not found")

    if body.name is not None:
        zone.name = body.name
    if body.description is not None:
        zone.description = body.description
    if body.notification_name is not None:
        zone.notification_name = body.notification_name

    # Printer routing
    if body.printer_ids is not None:
        printers = db.query(Printer).filter(Printer.id.in_(body.printer_ids)).all()
        zone.printers = printers
    # master_printer_id: always write if field present in request body (null = clear)
    if 'master_printer_id' in (body.model_fields_set if hasattr(body, 'model_fields_set') else {}):
        zone.master_printer_id = body.master_printer_id
    elif body.master_printer_id is not None:
        zone.master_printer_id = body.master_printer_id
    if body.auto_print is not None:
        zone.auto_print = body.auto_print
    if body.master_copies is not None:
        zone.master_copies = max(1, body.master_copies)
        zone.print_copies = zone.master_copies  # keep legacy in sync
    if body.secondary_copies is not None:
        zone.secondary_copies = max(1, body.secondary_copies)

    # Ticket formatting
    if body.sort_items_by is not None:
        zone.sort_items_by = body.sort_items_by
    if body.group_by_category is not None:
        zone.group_by_category = 1 if body.group_by_category else 0
    if body.category_order is not None:
        zone.category_order = json.dumps(body.category_order)
    if body.print_checkboxes is not None:
        zone.print_checkboxes = 1 if body.print_checkboxes else 0

    # KDS bypass — bypass_kds implies bypass_pending
    if body.bypass_kds is not None:
        zone.bypass_kds = 1 if body.bypass_kds else 0
        if body.bypass_kds:
            zone.bypass_pending = 1
    if body.bypass_pending is not None:
        zone.bypass_pending = 1 if body.bypass_pending else 0
    if body.auto_ready_to_served is not None:
        zone.auto_ready_to_served = 1 if body.auto_ready_to_served else 0

    db.commit()
    db.refresh(zone)
    return _zone_out(zone)


@router.delete("/{zone_id}")
def delete_prep_zone(
    zone_id: int,
    db: Session = Depends(get_db),
    user: User = Depends(require_manager),
):
    zone = db.query(PrepZone).filter(PrepZone.id == zone_id).first()
    if not zone:
        raise HTTPException(status_code=404, detail="Prep zone not found")
    db.delete(zone)
    db.commit()
    return {"ok": True}
