"""Sanctuary router: IPFS + on-chain anchoring entries."""

from __future__ import annotations

import uuid

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.models.sanctuary import SanctuaryEntry
from app.models.user import DuniterIdentity
from app.schemas.sanctuary import SanctuaryEntryCreate, SanctuaryEntryOut
from app.services import sanctuary_service
from app.services.auth_service import get_current_identity

router = APIRouter()


@router.get("/", response_model=list[SanctuaryEntryOut])
async def list_entries(
    db: AsyncSession = Depends(get_db),
    entry_type: str | None = Query(default=None, description="Filtrer par type (document, decision, vote_result)"),
    skip: int = Query(default=0, ge=0),
    limit: int = Query(default=50, ge=1, le=200),
) -> list[SanctuaryEntryOut]:
    """List all sanctuary entries with optional type filter."""
    stmt = select(SanctuaryEntry)

    if entry_type is not None:
        stmt = stmt.where(SanctuaryEntry.entry_type == entry_type)

    stmt = stmt.order_by(SanctuaryEntry.created_at.desc()).offset(skip).limit(limit)
    result = await db.execute(stmt)
    entries = result.scalars().all()

    return [SanctuaryEntryOut.model_validate(e) for e in entries]


@router.post("/", response_model=SanctuaryEntryOut, status_code=status.HTTP_201_CREATED)
async def create_entry(
    payload: SanctuaryEntryCreate,
    db: AsyncSession = Depends(get_db),
    identity: DuniterIdentity = Depends(get_current_identity),
) -> SanctuaryEntryOut:
    """Create a new sanctuary entry.

    This endpoint is typically called by internal services after:
    1. Content is hashed (SHA-256)
    2. Content is pinned to IPFS
    3. Hash is anchored on-chain via system.remark

    The IPFS CID and chain TX hash can be added later via updates.
    """
    entry = SanctuaryEntry(**payload.model_dump())
    db.add(entry)
    await db.commit()
    await db.refresh(entry)

    return SanctuaryEntryOut.model_validate(entry)


@router.get("/by-reference/{reference_id}", response_model=list[SanctuaryEntryOut])
async def get_entries_by_reference(
    reference_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
) -> list[SanctuaryEntryOut]:
    """Get all sanctuary entries for a given reference ID.

    Useful for finding all sanctuary entries associated with a document,
    decision, or vote result.
    """
    entries = await sanctuary_service.get_entries_by_reference(reference_id, db)
    return [SanctuaryEntryOut.model_validate(e) for e in entries]


@router.get("/{id}/verify")
async def verify_entry(
    id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
) -> dict:
    """Verify integrity of a sanctuary entry.

    Re-fetches the content (from IPFS if available), re-hashes it,
    and compares with the stored content_hash.
    """
    try:
        result = await sanctuary_service.verify_entry(id, db)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc))
    return result


@router.get("/{id}", response_model=SanctuaryEntryOut)
async def get_entry(
    id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
) -> SanctuaryEntryOut:
    """Get a single sanctuary entry by ID."""
    result = await db.execute(select(SanctuaryEntry).where(SanctuaryEntry.id == id))
    entry = result.scalar_one_or_none()
    if entry is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Entree sanctuaire introuvable")
    return SanctuaryEntryOut.model_validate(entry)
