"""Catalog routes: /api/catalog/species + /api/catalog/varieties.

Thin + sync per standards: parse params, call the service, return its
payload. All behavior (v1 parity, validation, audit) lives in
services/catalog.py. Auth is the default-deny middleware — nothing here is
public.
"""
from __future__ import annotations

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from ..db import get_db
from ..deps import current_garden_id
from ..schemas.catalog import (
    SpacingUpdate,
    SpeciesCreate,
    SpeciesCreateResult,
    SpeciesDetail,
    SpeciesOut,
    SpeciesPatch,
    VarietyCreate,
    VarietyCreateResult,
    VarietyDetail,
    VarietyOut,
    VarietyPatch,
)
from ..services import catalog

router = APIRouter(prefix="/api/catalog", tags=["catalog"])


# --- species -----------------------------------------------------------------

@router.get("/species", response_model=list[SpeciesOut])
def species_list(
    archived: int = Query(0),
    type_filter: str = Query("", alias="type"),
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.list_species(
        db, garden_id, include_archived=bool(archived), type_filter=type_filter
    )


@router.post("/species", response_model=SpeciesCreateResult)
def species_create(
    body: SpeciesCreate,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.create_species(
        db,
        garden_id,
        name=body.name,
        common_name=body.common_name,
        description=body.description,
        plants_per_unit=body.plants_per_unit,
        space_per_unit_sqft=body.space_per_unit_sqft,
        type_=body.type,
        primary_function=body.primary_function,
    )


@router.get("/species/{species_id}", response_model=SpeciesDetail)
def species_detail(
    species_id: int,
    archived: int = Query(0),
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.get_species(
        db, garden_id, species_id, include_archived=bool(archived)
    )


@router.patch("/species/{species_id}", response_model=SpeciesOut)
def species_update(
    species_id: int,
    body: SpeciesPatch,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.update_species(
        db, garden_id, species_id, body.model_dump(exclude_unset=True)
    )


@router.post("/species/{species_id}/spacing", response_model=SpeciesOut)
def species_set_spacing(
    species_id: int,
    body: SpacingUpdate,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.update_species_spacing(
        db,
        garden_id,
        species_id,
        plants_per_unit=body.plants_per_unit,
        space_per_unit_sqft=body.space_per_unit_sqft,
    )


# --- varieties -----------------------------------------------------------------

@router.get("/varieties", response_model=list[VarietyOut])
def variety_list(
    archived: int = Query(0),
    species_id: int | None = Query(None),
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.list_varieties(
        db, garden_id, include_archived=bool(archived), species_id=species_id
    )


@router.post("/varieties", response_model=VarietyCreateResult)
def variety_create(
    body: VarietyCreate,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.create_variety(
        db,
        garden_id,
        name=body.name,
        species_id=body.species_id,
        description=body.description,
        plants_per_unit=body.plants_per_unit,
        space_per_unit_sqft=body.space_per_unit_sqft,
    )


@router.get("/varieties/{variety_id}", response_model=VarietyDetail)
def variety_detail(
    variety_id: int,
    archived: int = Query(0),
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.get_variety(
        db, garden_id, variety_id, include_archived=bool(archived)
    )


@router.patch("/varieties/{variety_id}", response_model=VarietyOut)
def variety_update(
    variety_id: int,
    body: VarietyPatch,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.update_variety(
        db, garden_id, variety_id, body.model_dump(exclude_unset=True)
    )


@router.post("/varieties/{variety_id}/spacing", response_model=VarietyOut)
def variety_set_spacing(
    variety_id: int,
    body: SpacingUpdate,
    db: Session = Depends(get_db),
    garden_id: int = Depends(current_garden_id),
):
    return catalog.update_variety_spacing(
        db,
        garden_id,
        variety_id,
        plants_per_unit=body.plants_per_unit,
        space_per_unit_sqft=body.space_per_unit_sqft,
    )
