from __future__ import annotations

import uuid

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

from aif_platform.server.models.persistence import (
    PlatformOrganization,
    PlatformOrgMembership,
)


async def list_memberships_for_user(
    db: AsyncSession,
    user_id: uuid.UUID,
) -> list[tuple[PlatformOrgMembership, PlatformOrganization]]:
    q = (
        select(PlatformOrgMembership, PlatformOrganization)
        .join(
            PlatformOrganization,
            PlatformOrganization.id == PlatformOrgMembership.org_id,
        )
        .where(PlatformOrgMembership.user_id == user_id)
        .order_by(PlatformOrganization.created_at.asc())
    )
    rows = (await db.execute(q)).all()
    return [(m, o) for m, o in rows]


async def resolve_org_id_for_user(
    db: AsyncSession,
    *,
    user_id: uuid.UUID,
    requested_org_id: uuid.UUID | None,
) -> uuid.UUID:
    rows = await list_memberships_for_user(db, user_id)
    if not rows:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="User has no organization.",
        )
    org_ids = [o.id for _m, o in rows]
    if requested_org_id is None:
        return org_ids[0]
    if requested_org_id not in org_ids:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not a member of this organization.",
        )
    return requested_org_id


async def get_org_if_member(
    db: AsyncSession,
    *,
    user_id: uuid.UUID,
    org_id: uuid.UUID,
) -> PlatformOrganization | None:
    m = (
        await db.execute(
            select(PlatformOrgMembership).where(
                PlatformOrgMembership.user_id == user_id,
                PlatformOrgMembership.org_id == org_id,
            )
        )
    ).scalar_one_or_none()
    if not m:
        return None
    return (
        await db.execute(select(PlatformOrganization).where(PlatformOrganization.id == org_id))
    ).scalar_one_or_none()


async def update_org_name(
    db: AsyncSession,
    *,
    user_id: uuid.UUID,
    org_id: uuid.UUID,
    name: str,
) -> PlatformOrganization:
    org = await get_org_if_member(db, user_id=user_id, org_id=org_id)
    if not org:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Organization not found.")
    org.name = name.strip() or org.name
    await db.commit()
    await db.refresh(org)
    return org
