"""Organizations router: list, create, membership."""

from __future__ import annotations

import uuid

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

from app.database import get_db
from app.models.user import DuniterIdentity
from app.schemas.organization import OrgMemberOut, OrganizationCreate, OrganizationOut
from app.services.auth_service import get_current_identity
from app.services.org_service import (
    add_member,
    create_organization,
    get_organization,
    get_organization_by_slug,
    is_member,
    list_members,
    list_organizations,
)

router = APIRouter()


@router.get("/", response_model=list[OrganizationOut])
async def get_organizations(db: AsyncSession = Depends(get_db)) -> list[OrganizationOut]:
    """List all organizations (public — transparent ones need no auth)."""
    orgs = await list_organizations(db)
    return [OrganizationOut.model_validate(o) for o in orgs]


@router.post("/", response_model=OrganizationOut, status_code=status.HTTP_201_CREATED)
async def post_organization(
    payload: OrganizationCreate,
    db: AsyncSession = Depends(get_db),
    identity: DuniterIdentity = Depends(get_current_identity),
) -> OrganizationOut:
    """Create a new organization (authenticated users only)."""
    existing = await get_organization_by_slug(db, payload.slug)
    if existing:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Slug '{payload.slug}' déjà utilisé",
        )
    org = await create_organization(db, **payload.model_dump())
    # Creator becomes admin
    await add_member(db, org.id, identity.id, role="admin")
    return OrganizationOut.model_validate(org)


@router.get("/{org_id}", response_model=OrganizationOut)
async def get_organization_detail(
    org_id: uuid.UUID, db: AsyncSession = Depends(get_db)
) -> OrganizationOut:
    org = await get_organization(db, org_id)
    if not org:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Organisation introuvable")
    return OrganizationOut.model_validate(org)


@router.get("/{org_id}/members", response_model=list[OrgMemberOut])
async def get_members(
    org_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    identity: DuniterIdentity = Depends(get_current_identity),
) -> list[OrgMemberOut]:
    org = await get_organization(db, org_id)
    if not org:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Organisation introuvable")
    if not org.is_transparent and not await is_member(db, org_id, identity.id):
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Accès refusé")
    members = await list_members(db, org_id)
    return [OrgMemberOut.model_validate(m) for m in members]


@router.post("/{org_id}/join", response_model=OrgMemberOut, status_code=status.HTTP_201_CREATED)
async def join_organization(
    org_id: uuid.UUID,
    db: AsyncSession = Depends(get_db),
    identity: DuniterIdentity = Depends(get_current_identity),
) -> OrgMemberOut:
    """Join a transparent organization."""
    org = await get_organization(db, org_id)
    if not org:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Organisation introuvable")
    if not org.is_transparent:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Rejoindre cette organisation nécessite une invitation",
        )
    if await is_member(db, org_id, identity.id):
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Déjà membre")
    member = await add_member(db, org_id, identity.id)
    return OrgMemberOut.model_validate(member)
