"""Admin router for team management."""
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.team import TeamModel
from models.sql.team_membership import TeamMembershipModel
from models.sql.user import UserModel
from services.database import get_async_session
from services.access_service import get_accessible_client_ids
from api.middlewares.rbac_middleware import check_team_admin
from utils.auth_dependencies import get_current_user, require_client_admin

TEAMS_ROUTER = APIRouter(prefix="/teams", tags=["Admin - Teams"])


@TEAMS_ROUTER.post("", status_code=201)
async def create_team(
    name: str = Body(..., embed=True),
    client_id: Optional[uuid.UUID] = Body(None, embed=True),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    if client_id:
        await check_team_admin(admin, client_id, session)

    team = TeamModel(name=name, client_id=client_id, is_default=False)
    session.add(team)
    await session.commit()
    return {
        "id": str(team.id),
        "name": team.name,
        "client_id": str(team.client_id) if team.client_id else None,
        "is_default": team.is_default,
    }


@TEAMS_ROUTER.get("", response_model=List[dict])
async def list_teams(
    client_id: Optional[uuid.UUID] = Query(None),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    query = select(TeamModel)

    if admin.role != "super_admin":
        accessible_ids = await get_accessible_client_ids(admin, session)
        query = query.where(
            (TeamModel.client_id.in_(accessible_ids)) | (TeamModel.is_default == True)  # noqa: E712
        )

    if client_id:
        query = query.where(TeamModel.client_id == client_id)

    result = await session.execute(query.order_by(TeamModel.created_at.desc()))
    teams = result.scalars().all()
    return [
        {
            "id": str(t.id),
            "name": t.name,
            "client_id": str(t.client_id) if t.client_id else None,
            "is_default": t.is_default,
            "created_at": t.created_at.isoformat() if t.created_at else None,
        }
        for t in teams
    ]


@TEAMS_ROUTER.get("/{team_id}")
async def get_team(
    team_id: uuid.UUID,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    team = await session.get(TeamModel, team_id)
    if not team:
        raise HTTPException(status_code=404, detail="Team not found")

    if team.client_id and admin.role != "super_admin":
        await check_team_admin(admin, team.client_id, session)

    # Get members
    result = await session.execute(
        select(UserModel)
        .join(TeamMembershipModel, TeamMembershipModel.user_id == UserModel.id)
        .where(TeamMembershipModel.team_id == team_id)
    )
    members = result.scalars().all()

    return {
        "id": str(team.id),
        "name": team.name,
        "client_id": str(team.client_id) if team.client_id else None,
        "is_default": team.is_default,
        "created_at": team.created_at.isoformat() if team.created_at else None,
        "members": [
            {
                "id": str(m.id),
                "email": m.email,
                "display_name": m.display_name,
                "role": m.role,
            }
            for m in members
        ],
    }


@TEAMS_ROUTER.post("/{team_id}/members", status_code=201)
async def add_team_member(
    team_id: uuid.UUID,
    user_id: uuid.UUID = Body(..., embed=True),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    team = await session.get(TeamModel, team_id)
    if not team:
        raise HTTPException(status_code=404, detail="Team not found")

    if team.client_id and admin.role != "super_admin":
        await check_team_admin(admin, team.client_id, session)

    user = await session.get(UserModel, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    # Check for existing membership
    result = await session.execute(
        select(TeamMembershipModel).where(
            TeamMembershipModel.user_id == user_id,
            TeamMembershipModel.team_id == team_id,
        )
    )
    if result.scalar_one_or_none():
        raise HTTPException(status_code=409, detail="User already in team")

    membership = TeamMembershipModel(
        user_id=user_id,
        team_id=team_id,
        assigned_by=admin.id,
    )
    session.add(membership)
    await session.commit()
    return {"message": "Member added", "user_id": str(user_id), "team_id": str(team_id)}


@TEAMS_ROUTER.delete("/{team_id}/members/{user_id}")
async def remove_team_member(
    team_id: uuid.UUID,
    user_id: uuid.UUID,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    team = await session.get(TeamModel, team_id)
    if not team:
        raise HTTPException(status_code=404, detail="Team not found")

    if team.client_id and admin.role != "super_admin":
        await check_team_admin(admin, team.client_id, session)

    result = await session.execute(
        select(TeamMembershipModel).where(
            TeamMembershipModel.user_id == user_id,
            TeamMembershipModel.team_id == team_id,
        )
    )
    membership = result.scalar_one_or_none()
    if not membership:
        raise HTTPException(status_code=404, detail="Membership not found")

    await session.delete(membership)
    await session.commit()
    return {"message": "Member removed"}


@TEAMS_ROUTER.delete("/{team_id}")
async def delete_team(
    team_id: uuid.UUID,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    team = await session.get(TeamModel, team_id)
    if not team:
        raise HTTPException(status_code=404, detail="Team not found")

    if team.is_default:
        raise HTTPException(status_code=400, detail="Cannot delete the default team")

    if team.client_id and admin.role != "super_admin":
        await check_team_admin(admin, team.client_id, session)

    # Remove all memberships first
    result = await session.execute(
        select(TeamMembershipModel).where(TeamMembershipModel.team_id == team_id)
    )
    memberships = result.scalars().all()
    for m in memberships:
        await session.delete(m)

    await session.delete(team)
    await session.commit()
    return {"message": "Team deleted"}
