"""
Endpoints API pour l'éditeur d'architecture
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional, Dict, Any
from uuid import uuid4
from datetime import datetime
import json
from pathlib import Path

from backend.app.core.database import get_arch_db
from backend.app.models.architecture import ArchitectureNode

router = APIRouter(prefix="/api/architecture", tags=["Architecture"])
DATA_DIR = Path(__file__).resolve().parents[3] / "data"
WORLD_FILE = DATA_DIR / "architecture.json"


class ArchitectureNodeCreate(BaseModel):
    id: Optional[str] = None
    type: str
    x: int
    y: int
    width: int
    height: int
    rotation: int = 0
    payload: Dict[str, Any]


class ArchitectureNodeResponse(BaseModel):
    id: str
    type: str
    x: int
    y: int
    width: int
    height: int
    rotation: int
    payload: Dict[str, Any]
    created_at: datetime

    class Config:
        from_attributes = True


class ArchitectureWorldPayload(BaseModel):
    items: List[Dict[str, Any]]
    splines: Optional[List[Dict[str, Any]]] = None


@router.get("/nodes", response_model=List[ArchitectureNodeResponse])
async def list_nodes(db: Session = Depends(get_arch_db)):
    """Liste tous les noeuds d'architecture"""
    nodes = db.query(ArchitectureNode).order_by(ArchitectureNode.created_at.asc()).all()
    results = []
    for node in nodes:
        try:
            payload = json.loads(node.payload or "{}")
        except json.JSONDecodeError:
            payload = {}
        results.append(ArchitectureNodeResponse(
            id=node.id,
            type=node.type,
            x=node.x,
            y=node.y,
            width=node.width,
            height=node.height,
            rotation=node.rotation,
            payload=payload,
            created_at=node.created_at
        ))
    return results


@router.post("/nodes", response_model=ArchitectureNodeResponse)
async def create_node(payload: ArchitectureNodeCreate, db: Session = Depends(get_arch_db)):
    """Créer un noeud d'architecture"""
    node_id = payload.id or str(uuid4())
    node = ArchitectureNode(
        id=node_id,
        type=payload.type,
        x=payload.x,
        y=payload.y,
        width=payload.width,
        height=payload.height,
        rotation=payload.rotation,
        payload=json.dumps(payload.payload)
    )
    db.add(node)
    db.commit()
    db.refresh(node)
    return ArchitectureNodeResponse(
        id=node.id,
        type=node.type,
        x=node.x,
        y=node.y,
        width=node.width,
        height=node.height,
        rotation=node.rotation,
        payload=payload.payload,
        created_at=node.created_at
    )


def ensure_world_file() -> None:
    DATA_DIR.mkdir(parents=True, exist_ok=True)
    if not WORLD_FILE.exists():
        WORLD_FILE.write_text(json.dumps({"items": [], "splines": []}, indent=2), encoding="utf-8")


@router.get("/world")
async def get_world():
    """Charge le fichier architecture.json, le crée si absent."""
    ensure_world_file()
    try:
        data = json.loads(WORLD_FILE.read_text(encoding="utf-8"))
    except json.JSONDecodeError:
        data = {"items": [], "splines": []}
    return data


@router.post("/world")
async def save_world(payload: ArchitectureWorldPayload):
    """Sauvegarde les éléments du world dans architecture.json."""
    ensure_world_file()
    splines = payload.splines or []
    WORLD_FILE.write_text(
        json.dumps({"items": payload.items, "splines": splines}, indent=2),
        encoding="utf-8"
    )
    return {"status": "ok", "count": len(payload.items), "splines": len(splines)}
