from __future__ import annotations from uuid import UUID from fastapi import APIRouter, Depends, Query from fastapi import HTTPException from sqlalchemy.orm import Session from app.db.session import get_db from app.models import Area from app.schemas import Envelope from app.schemas.area import AreaCreate, AreaList, AreaRead, AreaUpdate, MunicipalitySearchList from app.services.area_service import AreaService from app.utils.response import envelope router = APIRouter(prefix="/projects/{project_id}/areas", tags=["areas"]) @router.get("", response_model=Envelope[AreaList]) def list_areas( project_id: UUID, limit: int = Query(default=50, ge=1, le=200), offset: int = Query(default=0, ge=0), db: Session = Depends(get_db), ): areas, total = AreaService.list_areas(db, project_id=project_id, limit=limit, offset=offset) return envelope({"items": [AreaService.serialize_area(area) for area in areas], "total": total, "limit": limit, "offset": offset}) @router.post("", status_code=201, response_model=Envelope[AreaRead]) def create_area(project_id: UUID, payload: AreaCreate, db: Session = Depends(get_db)): area = AreaService.create_area(db, project_id, payload) return envelope(AreaService.serialize_area(area)) @router.get("/municipalities", response_model=Envelope[MunicipalitySearchList]) def search_municipalities( project_id: UUID, query: str = Query(default="", max_length=120), limit: int = Query(default=20, ge=1, le=50), db: Session = Depends(get_db), ): items, total = AreaService.search_municipalities(db, project_id, query, limit) return envelope({"items": items, "total": total}) @router.post("/municipalities/{niscode}/activate", response_model=Envelope[AreaRead]) def activate_municipality(project_id: UUID, niscode: str, db: Session = Depends(get_db)): area = AreaService.activate_municipality(db, project_id, niscode) return envelope(AreaService.serialize_area(area)) @router.get("/{area_id}", response_model=Envelope[AreaRead]) def get_area( project_id: UUID, area_id: UUID, db: Session = Depends(get_db), ): area = AreaService.get_area(db, area_id) if area.project_id != project_id: raise HTTPException(status_code=404, detail="Area not found") return envelope(AreaService.serialize_area(area)) @router.patch("/{area_id}", response_model=Envelope[AreaRead]) def update_area( project_id: UUID, area_id: UUID, payload: AreaUpdate, db: Session = Depends(get_db), ): existing = db.get(Area, area_id) if not existing or existing.project_id != project_id: raise HTTPException(status_code=404, detail="Area not found") area = AreaService.update_area(db, area_id, payload) return envelope(AreaService.serialize_area(area))