"""
PlantPlan FastAPI Backend
- Symbolbibliothek ausliefern
- Koordinaten normalisieren
- JSON/SVG Export
- Shape-Änderungen empfangen (Puffer + Kreisel)
"""

import json
from pathlib import Path
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

app = FastAPI(title="PlantPlan API")

# CORS: Erlaubt Zugriff vom lokalen Frontend Dev-Server
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_methods=["*"],
    allow_headers=["*"],
)

CATALOG_DIR = Path(__file__).parent / "catalog"


# ---------------------------------------------------------------------------
# Pydantic Models
# ---------------------------------------------------------------------------

class SketchPayload(BaseModel):
    shapes: list[dict]
    grid_size: int = 10


class PufferUpdate(BaseModel):
    """Puffer-Symbol: Rechteck mit Breite und Höhe."""
    id: str
    x: float
    y: float
    w: float   # Breite
    h: float   # Höhe


class KreiselUpdate(BaseModel):
    """Kreisel-Symbol: Zwei Kreise mit Abstand und Radius."""
    id: str
    x: float
    y: float
    abstand: float   # Abstand zwischen den Kreismittelpunkten
    radius: float    # Radius beider Kreise


class ShapeUpdatePayload(BaseModel):
    """Payload für Shape-Änderungen vom Client."""
    puffer: list[PufferUpdate] = []
    kreisel: list[KreiselUpdate] = []


# ---------------------------------------------------------------------------
# Endpoints
# ---------------------------------------------------------------------------

@app.get("/symbols")
async def get_symbols():
    """Symbolbibliothek als JSON ausliefern."""
    catalog_file = CATALOG_DIR / "symbols.json"
    with open(catalog_file, encoding="utf-8") as f:
        return json.load(f)


@app.post("/normalize")
async def normalize(payload: SketchPayload):
    """Koordinaten auf Grid snappen und SVG-Pfade normalisieren."""
    cleaned = []
    for shape in payload.shapes:
        s = dict(shape)
        if "x" in s:
            s["x"] = round(s["x"] / payload.grid_size) * payload.grid_size
        if "y" in s:
            s["y"] = round(s["y"] / payload.grid_size) * payload.grid_size
        cleaned.append(s)
    return {"shapes": cleaned}


@app.post("/export")
async def export_sketch(payload: SketchPayload):
    """Finales Projektfile als JSON exportieren."""
    return {
        "json": {
            "version": "1.0",
            "shapes": payload.shapes,
        }
    }


@app.post("/shapes/update")
async def update_shapes(payload: ShapeUpdatePayload):
    """
    Shape-Änderungen vom Client empfangen.

    Gibt für jeden Puffer Breite/Höhe und für jeden Kreisel
    Abstand/Radius + berechnete Gesamtlänge zurück.
    """
    result = {
        "received": {
            "puffer_count": len(payload.puffer),
            "kreisel_count": len(payload.kreisel),
        },
        "puffer": [],
        "kreisel": [],
    }

    for p in payload.puffer:
        result["puffer"].append({
            "id": p.id,
            "x": p.x,
            "y": p.y,
            "breite": p.w,
            "hoehe": p.h,
        })

    for k in payload.kreisel:
        result["kreisel"].append({
            "id": k.id,
            "x": k.x,
            "y": k.y,
            "abstand": k.abstand,
            "radius": k.radius,
            "gesamtlaenge": 2 * k.radius + k.abstand,
        })

    return result
