"""Admin router for client management."""
import re
from typing import List, Optional
import uuid

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

from models.sql.client import ClientModel
from models.sql.team import TeamModel
from models.sql.user import UserModel
from services.database import get_async_session
from services.access_service import get_accessible_clients
from api.middlewares.rbac_middleware import check_client_access
from utils.auth_dependencies import require_super_admin, require_client_admin

CLIENTS_ROUTER = APIRouter(prefix="/clients", tags=["Admin - Clients"])


def _slugify(name: str) -> str:
    slug = name.lower().strip()
    slug = re.sub(r"[^a-z0-9]+", "-", slug)
    return slug.strip("-")


@CLIENTS_ROUTER.post("", status_code=201)
async def create_client(
    name: str = Body(..., embed=True),
    review_policy: str = Body("self_approve", embed=True),
    _: UserModel = Depends(require_super_admin),
    session: AsyncSession = Depends(get_async_session),
):
    slug = _slugify(name)

    # Check slug uniqueness
    result = await session.execute(
        select(ClientModel).where(ClientModel.slug == slug)
    )
    if result.scalar_one_or_none():
        raise HTTPException(status_code=409, detail="A client with this name already exists")

    client = ClientModel(name=name, slug=slug, review_policy=review_policy)
    session.add(client)
    await session.flush()

    # Auto-create a team for this client
    team = TeamModel(name=f"{name} Team", client_id=client.id, is_default=False)
    session.add(team)
    await session.commit()

    return {
        "id": str(client.id),
        "name": client.name,
        "slug": client.slug,
        "review_policy": client.review_policy,
        "team_id": str(team.id),
    }


@CLIENTS_ROUTER.get("", response_model=List[dict])
async def list_clients(
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    clients = await get_accessible_clients(admin, session)
    return [
        {
            "id": str(c.id),
            "name": c.name,
            "slug": c.slug,
            "logo_path": c.logo_path,
            "retention_days": c.retention_days,
            "review_policy": c.review_policy,
            "is_active": c.is_active,
            "created_at": c.created_at.isoformat() if c.created_at else None,
        }
        for c in clients
    ]


@CLIENTS_ROUTER.get("/{client_id}")
async def get_client(
    client_id: uuid.UUID,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_client_access(admin, client_id, session)

    client = await session.get(ClientModel, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")

    return {
        "id": str(client.id),
        "name": client.name,
        "slug": client.slug,
        "logo_path": client.logo_path,
        "retention_days": client.retention_days,
        "review_policy": client.review_policy,
        "is_active": client.is_active,
        "created_at": client.created_at.isoformat() if client.created_at else None,
    }


@CLIENTS_ROUTER.put("/{client_id}")
async def update_client(
    client_id: uuid.UUID,
    name: Optional[str] = Body(None, embed=True),
    review_policy: Optional[str] = Body(None, embed=True),
    retention_days: Optional[int] = Body(None, embed=True),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_client_access(admin, client_id, session)

    client = await session.get(ClientModel, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")

    if name is not None:
        client.name = name
        client.slug = _slugify(name)
    if review_policy is not None:
        client.review_policy = review_policy
    if retention_days is not None:
        client.retention_days = retention_days

    session.add(client)
    await session.commit()

    return {
        "id": str(client.id),
        "name": client.name,
        "slug": client.slug,
        "review_policy": client.review_policy,
        "retention_days": client.retention_days,
    }


@CLIENTS_ROUTER.delete("/{client_id}")
async def deactivate_client(
    client_id: uuid.UUID,
    _: UserModel = Depends(require_super_admin),
    session: AsyncSession = Depends(get_async_session),
):
    client = await session.get(ClientModel, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")

    client.is_active = False
    session.add(client)
    await session.commit()
    return {"message": "Client deactivated", "client_id": str(client.id)}
