"""Panorama CRUD router."""

from datetime import datetime
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query, status
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session

from app.database import get_db
from app.models.hotspot import Hotspot
from app.models.panorama import Panorama
from app.models.room import Room
from app.models.user import User
from app.schemas.panorama import PanoramaCreate, PanoramaRead, PanoramaUpdate
from app.services.auth_service import get_current_user
from app.utils.helpers import generate_uuid, paginate

router = APIRouter()


# ── Custom schemas ─────────────────────────────────────────────────────── #

class ReorderBody(BaseModel):
    sequence: int = Field(..., ge=0)


# ── Helpers ────────────────────────────────────────────────────────────── #

def get_panorama_or_404(pano_id: str, db: Session) -> Panorama:
    pano = db.query(Panorama).filter(Panorama.id == pano_id).first()
    if not pano:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="全景图不存在",
        )
    return pano


# ── Endpoints ──────────────────────────────────────────────────────────── #

@router.get(
    "/api/rooms/{rid}/panoramas",
    response_model=dict,
    summary="获取房间全景图列表",
)
def list_panoramas(
    rid: str,
    page: int = Query(1, ge=1),
    size: int = Query(50, ge=1, le=200),
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """List all panoramas for a room (paginated)."""
    room = db.query(Room).filter(Room.id == rid).first()
    if not room:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="房间不存在",
        )

    query = (
        db.query(Panorama)
        .filter(Panorama.room_id == rid)
        .order_by(Panorama.sequence, Panorama.capture_order)
    )
    result = paginate(query, page=page, size=size)

    return {
        "items": [PanoramaRead.model_validate(p) for p in result["items"]],
        "total": result["total"],
        "page": result["page"],
        "size": result["size"],
        "pages": result["pages"],
    }


@router.get("/api/panoramas/{id}", response_model=dict, summary="获取全景图详情（含热点）")
def get_panorama_detail(
    id: str,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """Get a panorama including its hotspots."""
    pano = get_panorama_or_404(id, db)

    # Fetch hotspots
    hotspots_from = (
        db.query(Hotspot)
        .filter(Hotspot.from_pano_id == id)
        .order_by(Hotspot.created_at)
        .all()
    )
    hotspots_to = (
        db.query(Hotspot)
        .filter(Hotspot.to_pano_id == id)
        .order_by(Hotspot.created_at)
        .all()
    )

    hotspot_schemas = []
    for h in hotspots_from + hotspots_to:
        hotspot_schemas.append(
            {
                "id": h.id,
                "from_pano_id": h.from_pano_id,
                "to_pano_id": h.to_pano_id,
                "yaw": h.yaw,
                "pitch": h.pitch,
                "type": h.type,
                "label": h.label,
                "confidence": h.confidence,
                "status": h.status,
                "created_by": h.created_by,
                "metadata": h.metadata,
                "created_at": h.created_at.isoformat() if h.created_at else None,
                "updated_at": h.updated_at.isoformat() if h.updated_at else None,
            }
        )

    return {
        **PanoramaRead.model_validate(pano).model_dump(),
        "hotspots": hotspot_schemas,
    }


@router.post(
    "/api/rooms/{rid}/panoramas",
    response_model=PanoramaRead,
    status_code=status.HTTP_201_CREATED,
    summary="创建全景图",
)
def create_panorama(
    rid: str,
    body: PanoramaCreate,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """Create a new panorama in a room."""
    room = db.query(Room).filter(Room.id == rid).first()
    if not room:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="房间不存在",
        )

    pano = Panorama(
        id=generate_uuid(),
        room_id=rid,
        image_url=body.image_url,
        thumbnail_url=body.thumbnail_url,
        sequence=body.sequence,
        default_yaw=body.default_yaw,
        default_pitch=body.default_pitch,
        capture_order=body.capture_order,
        position_x=body.position_x,
        position_y=body.position_y,
        position_z=body.position_z,
        metadata=body.metadata,
        created_at=datetime.utcnow(),
        updated_at=datetime.utcnow(),
    )
    db.add(pano)
    db.commit()
    db.refresh(pano)

    return PanoramaRead.model_validate(pano)


@router.put("/api/panoramas/{id}", response_model=PanoramaRead, summary="更新全景图")
def update_panorama(
    id: str,
    body: PanoramaUpdate,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """Update a panorama."""
    pano = get_panorama_or_404(id, db)

    update_data = body.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(pano, field, value)
    pano.updated_at = datetime.utcnow()

    db.commit()
    db.refresh(pano)
    return PanoramaRead.model_validate(pano)


@router.delete("/api/panoramas/{id}", status_code=status.HTTP_200_OK, summary="删除全景图")
def delete_panorama(
    id: str,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """Delete a panorama."""
    pano = get_panorama_or_404(id, db)
    db.delete(pano)
    db.commit()

    return {"message": "全景图已删除", "panorama_id": id}


@router.put("/api/panoramas/{id}/reorder", response_model=PanoramaRead, summary="重排全景图")
def reorder_panorama(
    id: str,
    body: ReorderBody,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_user),
):
    """Update the sequence of a panorama."""
    pano = get_panorama_or_404(id, db)
    pano.sequence = body.sequence
    db.commit()
    db.refresh(pano)
    return PanoramaRead.model_validate(pano)
