"""组织管理 API — /api/v1/organization/*"""
import uuid
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, EmailStr, Field
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user
from app.database import get_db
from app.models.organization import Organization, OrgMember
from app.models.user import User

router = APIRouter(prefix="/api/v1/organization", tags=["组织管理"])


class OrgInfoResponse(BaseModel):
    id: str
    name: str
    slug: str
    description: Optional[str] = None
    logo_url: Optional[str] = None
    plan: str
    max_members: int
    member_count: int = 0

    model_config = {"from_attributes": True}


class MemberResponse(BaseModel):
    id: str
    user_id: str
    name: str
    email: str
    role: str
    joined_at: str
    invited_by: Optional[str] = None

    model_config = {"from_attributes": True}


class InviteMemberRequest(BaseModel):
    email: EmailStr
    role: str = Field(default="viewer", pattern="^(owner|admin|editor|viewer)$")


class UpdateMemberRoleRequest(BaseModel):
    role: str = Field(..., pattern="^(owner|admin|editor|viewer)$")


class InviteResponse(BaseModel):
    id: str
    email: str
    role: str
    message: str


@router.get("/info", response_model=OrgInfoResponse)
async def get_org_info(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取当前用户所属组织的基本信息"""
    if not current_user.organization_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未加入任何组织",
        )

    stmt = select(Organization).where(Organization.id == current_user.organization_id)
    result = await db.execute(stmt)
    org = result.scalar_one_or_none()

    if not org:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="组织不存在",
        )

    count_stmt = select(func.count(OrgMember.id)).where(
        OrgMember.organization_id == org.id
    )
    count_result = await db.execute(count_stmt)
    member_count = count_result.scalar() or 0

    return OrgInfoResponse(
        id=str(org.id),
        name=org.name,
        slug=org.slug,
        description=org.description,
        logo_url=org.logo_url,
        plan=org.plan,
        max_members=org.max_members,
        member_count=member_count,
    )


@router.get("/members", response_model=list[MemberResponse])
async def list_members(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取当前用户所属组织的所有成员"""
    if not current_user.organization_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未加入任何组织",
        )

    stmt = (
        select(OrgMember, User)
        .join(User, User.id == OrgMember.user_id)
        .where(OrgMember.organization_id == current_user.organization_id)
        .order_by(OrgMember.joined_at.desc())
    )
    result = await db.execute(stmt)
    rows = result.all()

    members = []
    for member, user in rows:
        members.append(
            MemberResponse(
                id=str(member.id),
                user_id=str(member.user_id),
                name=user.name or "",
                email=user.email,
                role=member.role,
                joined_at=member.joined_at.isoformat() if member.joined_at else "",
                invited_by=str(member.invited_by) if member.invited_by else None,
            )
        )
    return members


@router.post("/members/invite", response_model=InviteResponse, status_code=status.HTTP_201_CREATED)
async def invite_member(
    body: InviteMemberRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """邀请新成员加入组织"""
    if not current_user.organization_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未加入任何组织",
        )

    current_membership_stmt = select(OrgMember).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == current_user.id,
    )
    current_membership_result = await db.execute(current_membership_stmt)
    current_membership = current_membership_result.scalar_one_or_none()

    if not current_membership or current_membership.role not in ["owner", "admin"]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="仅管理员可以邀请新成员",
        )

    target_user_stmt = select(User).where(User.email == body.email)
    target_user_result = await db.execute(target_user_stmt)
    target_user = target_user_result.scalar_one_or_none()

    if not target_user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户不存在",
        )

    existing_stmt = select(OrgMember).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == target_user.id,
    )
    existing_result = await db.execute(existing_stmt)
    existing_membership = existing_result.scalar_one_or_none()

    if existing_membership:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="该用户已经是组织成员",
        )

    count_stmt = select(func.count(OrgMember.id)).where(
        OrgMember.organization_id == current_user.organization_id
    )
    count_result = await db.execute(count_stmt)
    current_member_count = count_result.scalar() or 0

    org_stmt = select(Organization).where(Organization.id == current_user.organization_id)
    org_result = await db.execute(org_stmt)
    org = org_result.scalar_one_or_none()

    if org and current_member_count >= org.max_members:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"成员数量已达上限（{org.max_members}人）",
        )

    new_membership = OrgMember(
        id=uuid.uuid4(),
        organization_id=current_user.organization_id,
        user_id=target_user.id,
        role=body.role,
        invited_by=current_user.id,
    )
    db.add(new_membership)
    await db.commit()
    await db.refresh(new_membership)

    return InviteResponse(
        id=str(new_membership.id),
        email=target_user.email,
        role=new_membership.role,
        message=f"成功邀请 {target_user.email} 加入组织",
    )


@router.put("/members/{user_id}/role", response_model=MemberResponse)
async def update_member_role(
    user_id: uuid.UUID,
    body: UpdateMemberRoleRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """更新成员角色"""
    if not current_user.organization_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未加入任何组织",
        )

    current_membership_stmt = select(OrgMember).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == current_user.id,
    )
    current_membership_result = await db.execute(current_membership_stmt)
    current_membership = current_membership_result.scalar_one_or_none()

    if not current_membership or current_membership.role not in ["owner", "admin"]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="仅管理员可以修改成员角色",
        )

    target_membership_stmt = select(OrgMember, User).join(
        User, User.id == OrgMember.user_id
    ).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == user_id,
    )
    target_result = await db.execute(target_membership_stmt)
    target_row = target_result.first()

    if not target_row:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="成员不存在",
        )

    target_membership, target_user = target_row

    if target_membership.role == "owner":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能修改所有者角色",
        )

    if body.role == "owner":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能将成员设为所有者",
        )

    target_membership.role = body.role
    await db.commit()
    await db.refresh(target_membership)

    return MemberResponse(
        id=str(target_membership.id),
        user_id=str(target_membership.user_id),
        name=target_user.name or "",
        email=target_user.email,
        role=target_membership.role,
        joined_at=target_membership.joined_at.isoformat() if target_membership.joined_at else "",
        invited_by=str(target_membership.invited_by) if target_membership.invited_by else None,
    )


@router.delete("/members/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def remove_member(
    user_id: uuid.UUID,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """移除组织成员"""
    if not current_user.organization_id:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户未加入任何组织",
        )

    current_membership_stmt = select(OrgMember).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == current_user.id,
    )
    current_membership_result = await db.execute(current_membership_stmt)
    current_membership = current_membership_result.scalar_one_or_none()

    if not current_membership or current_membership.role not in ["owner", "admin"]:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="仅管理员可以移除成员",
        )

    target_membership_stmt = select(OrgMember).where(
        OrgMember.organization_id == current_user.organization_id,
        OrgMember.user_id == user_id,
    )
    target_result = await db.execute(target_membership_stmt)
    target_membership = target_result.scalar_one_or_none()

    if not target_membership:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="成员不存在",
        )

    if target_membership.role == "owner":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能移除所有者",
        )

    if user_id == current_user.id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能移除自己",
        )

    await db.delete(target_membership)
    await db.commit()
