from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import select

from app.core.database import session_scope
from app.modules.sync.tenant import TenantContext, get_tenant_context, require_enterprise_zootech
from app.modules.zootech.catalog_apply import load_catalog_row
from app.modules.zootech import service as zootech_service
from app.modules.zootech.service import ZootechServiceError
from app.modules.zootech.models import ZootechComponent, ZootechRecipe

router = APIRouter()


def _list_components(enterprise_id: str) -> list[dict]:
    with session_scope() as db:
        rows = list(
            db.scalars(
                select(ZootechComponent).where(
                    ZootechComponent.enterprise_id == enterprise_id,
                    ZootechComponent.is_deleted.is_(False),
                )
            )
        )
        return [
            {
                "id": row.id,
                "name": row.name,
                "type": row.type,
                "is_active": row.is_active,
                "dry_matter": row.dry_matter,
                "protein": row.protein,
                "energy": row.energy,
                "price": row.price,
                "external_no": row.external_no,
                "version": row.version,
                "content_hash": row.content_hash,
            }
            for row in rows
        ]


def _list_recipes(enterprise_id: str) -> list[dict]:
    with session_scope() as db:
        rows = list(
            db.scalars(
                select(ZootechRecipe).where(
                    ZootechRecipe.enterprise_id == enterprise_id,
                    ZootechRecipe.is_deleted.is_(False),
                )
            )
        )
        return [
            {
                "id": row.id,
                "name": row.name,
                "heads_per_trip": row.heads_per_trip,
                "mixing_time": row.mixing_time,
                "trip_percent": row.trip_percent,
                "dry_matter_locked": row.dry_matter_locked,
                "version": row.version,
                "content_hash": row.content_hash,
            }
            for row in rows
        ]


@router.get("/components")
def list_components(
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    return {"components": _list_components(enterprise_id)}


@router.get("/components/{component_id}")
def get_component(
    component_id: str,
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    row = load_catalog_row(enterprise_id, "component", component_id)
    if not row:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="NOT_FOUND")
    return row


@router.post("/components")
def create_component(
    body: dict,
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    return zootech_service.upsert_component(enterprise_id, None, body)


@router.patch("/components/{component_id}")
def update_component(
    component_id: str,
    body: dict,
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    try:
        return zootech_service.patch_component(enterprise_id, component_id, body)
    except ZootechServiceError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="NOT_FOUND") from None


@router.post("/recipes")
def create_recipe(
    body: dict,
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    return zootech_service.upsert_recipe(enterprise_id, None, body)


@router.get("/recipes")
def list_recipes(
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    return {"recipes": _list_recipes(enterprise_id)}


@router.get("/recipes/{recipe_id}")
def get_recipe(
    recipe_id: str,
    enterprise_id: str = Query(...),
    tenant: TenantContext = Depends(require_enterprise_zootech),
):
    if tenant.enterprise_id != enterprise_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    row = load_catalog_row(enterprise_id, "recipe", recipe_id)
    if not row:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="NOT_FOUND")
    return row
