from datetime import datetime
from decimal import Decimal
from typing import Optional
from uuid import UUID

from pydantic import BaseModel

from src.core.utils.geometry import geometry_to_geojson


class SectionResponse(BaseModel):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    description: Optional[str] = None
    is_religious: bool
    religious_denomination: Optional[str] = None

    # Cemetery-map fields (INDL-49)
    display_color: Optional[str] = None
    plot_number_prefix: Optional[str] = None
    next_plot_seq: int = 1
    area_m2: Optional[Decimal] = None
    plot_count: Optional[int] = None
    total_count: Optional[int] = None       # alias of plot_count (INDL-41 AC-29)
    available_count: Optional[int] = None   # vacant plots (INDL-41 AC-29)
    boundary: Optional[dict] = None  # GeoJSON Polygon (assembled by serializer)

    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


def serialize_section(
    section,
    plot_count: Optional[int] = None,
    available_count: Optional[int] = None,
) -> dict:
    """Serialise a Section ORM row to a plain dict, converting the geography
    ``boundary`` (WKBElement) to GeoJSON without letting Pydantic try to coerce it."""
    return {
        "id": section.id,
        "tenant_id": section.tenant_id,
        "code": section.code,
        "name": section.name,
        "description": section.description,
        "is_religious": section.is_religious,
        "religious_denomination": section.religious_denomination,
        "display_color": section.display_color,
        "plot_number_prefix": section.plot_number_prefix,
        "next_plot_seq": section.next_plot_seq,
        "area_m2": section.area_m2,
        "plot_count": plot_count,
        "total_count": plot_count,
        "available_count": available_count,
        "boundary": geometry_to_geojson(section.boundary),
        "created_at": section.created_at,
        "updated_at": section.updated_at,
    }


class AutogenerateGridResponse(BaseModel):
    created: int
    section_id: UUID
    plot_ref_range: Optional[str] = None  # e.g. "A-1 … A-20"
    plot_refs: list[str] = []
