"""Norms API Routes"""
import uuid
from typing import List, Optional
from fastapi import APIRouter, Depends, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from normbase.db.connection import get_db
from normbase.schemas import (
    NormCreate,
    NormUpdate,
    NormResponse,
    NormListResponse,
    NormVersionResponse,
)
from normbase.services.norm_service import NormService

router = APIRouter(prefix="/norms", tags=["norms"])
_norm_service = NormService()


@router.post("", response_model=NormResponse, status_code=status.HTTP_201_CREATED)
async def create_norm(
    norm_data: NormCreate,
    db: AsyncSession = Depends(get_db)
):
    """Create a new norm"""
    created = await _norm_service.create_norm(db, norm_data)
    return NormResponse.model_validate(created)


@router.get("", response_model=NormListResponse)
async def list_norms(
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(20, ge=1, le=100, description="Page size"),
    norm_type: Optional[str] = Query(None, description="Filter by norm type"),
    status: Optional[str] = Query(None, description="Filter by status"),
    authority_level: Optional[str] = Query(None, description="Filter by authority level"),
    formality_level: Optional[str] = Query(None, description="Filter by formality level"),
    field_id: Optional[uuid.UUID] = Query(None, description="Filter by information field"),
    db: AsyncSession = Depends(get_db)
):
    """List all norms with pagination"""
    total, norms = await _norm_service.list_norms(
        db,
        page=page,
        page_size=page_size,
        norm_type=norm_type,
        status_filter=status,
        authority_level=authority_level,
        formality_level=formality_level,
        field_id=field_id,
    )
    return NormListResponse(
        total=total,
        items=[NormResponse.model_validate(n) for n in norms],
        page=page,
        page_size=page_size
    )


@router.get("/{norm_id}", response_model=NormResponse)
async def get_norm(
    norm_id: uuid.UUID,
    db: AsyncSession = Depends(get_db)
):
    """Get a norm by ID"""
    norm = await _norm_service.get_norm(db, norm_id=norm_id)
    return NormResponse.model_validate(norm)


@router.put("/{norm_id}", response_model=NormResponse)
async def update_norm(
    norm_id: uuid.UUID,
    norm_data: NormUpdate,
    db: AsyncSession = Depends(get_db)
):
    """Update a norm"""
    norm = await _norm_service.update_norm(db, norm_id=norm_id, norm_data=norm_data)
    return NormResponse.model_validate(norm)


@router.delete("/{norm_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_norm(
    norm_id: uuid.UUID,
    db: AsyncSession = Depends(get_db)
):
    """Soft delete a norm by archiving it."""
    await _norm_service.delete_norm(db, norm_id=norm_id)


@router.get("/{norm_id}/versions", response_model=List[NormVersionResponse])
async def list_norm_versions(
    norm_id: uuid.UUID,
    db: AsyncSession = Depends(get_db)
):
    """Get version history for a norm"""
    versions = await _norm_service.list_norm_versions(db, norm_id=norm_id)
    return [NormVersionResponse.model_validate(v) for v in versions]


@router.post("/{norm_id}/versions", response_model=NormVersionResponse)
async def create_norm_version(
    norm_id: uuid.UUID,
    change_note: str,
    db: AsyncSession = Depends(get_db)
):
    """Create a new version snapshot for a norm"""
    version = await _norm_service.create_norm_version(
        db,
        norm_id=norm_id,
        change_note=change_note,
    )
    return NormVersionResponse.model_validate(version)
