"""Organization management endpoints."""
from typing import List
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.core.database import get_db
from app.models.user import User
from app.models.organization import Organization, OrganizationMember, MemberRole
from app.schemas.organization import OrganizationCreate, OrganizationRead, OrganizationUpdate, MemberCreate, MemberRead
from app.api.deps import get_current_user, require_role
from app.services.email import EmailService

router = APIRouter()

@router.get("/", response_model=List[OrganizationRead])
async def list_organizations(
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """List organizations user belongs to."""
    result = await db.execute(
        select(Organization)
        .join(OrganizationMember)
        .where(OrganizationMember.user_id == user.id)
    )
    return result.scalars().all()

@router.post("/", response_model=OrganizationRead, status_code=status.HTTP_201_CREATED)
async def create_organization(
    org_in: OrganizationCreate,
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """Create a new organization."""
    import re
    
    # Auto-generate slug if not provided
    if not org_in.slug:
        base_slug = re.sub(r'[^\w\s-]', '', org_in.name.lower())
        base_slug = re.sub(r'[-\s]+', '-', base_slug).strip('-')
        
        # Check uniqueness and add number if needed
        slug = base_slug
        counter = 1
        while True:
            result = await db.execute(select(Organization).where(Organization.slug == slug))
            if not result.scalar_one_or_none():
                break
            counter += 1
            slug = f"{base_slug}-{counter}"
    else:
        slug = org_in.slug
        # Check slug uniqueness
        result = await db.execute(select(Organization).where(Organization.slug == slug))
        if result.scalar_one_or_none():
            raise HTTPException(status_code=400, detail="Slug already exists")
    
    # Create org
    org = Organization(
        name=org_in.name,
        slug=slug
    )
    db.add(org)
    await db.flush()
    
    # Add creator as owner
    member = OrganizationMember(
        organization_id=org.id,
        user_id=user.id,
        role=MemberRole.OWNER
    )
    db.add(member)
    
    return org

@router.get("/{org_id}", response_model=OrganizationRead)
async def get_organization(
    org_id: int,
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """Get organization details."""
    result = await db.execute(select(Organization).where(Organization.id == org_id))
    org = result.scalar_one_or_none()
    if not org:
        raise HTTPException(status_code=404, detail="Organization not found")
    return org

@router.patch("/{org_id}", response_model=OrganizationRead)
async def update_organization(
    org_id: int,
    org_update: OrganizationUpdate,
    member: OrganizationMember = Depends(require_role("admin")),
    db: AsyncSession = Depends(get_db)
):
    """Update organization (admin only)."""
    result = await db.execute(select(Organization).where(Organization.id == org_id))
    org = result.scalar_one_or_none()
    if not org:
        raise HTTPException(status_code=404, detail="Organization not found")
    
    for field, value in org_update.dict(exclude_unset=True).items():
        setattr(org, field, value)
    
    return org

@router.get("/{org_id}/members", response_model=List[MemberRead])
async def list_members(
    org_id: int,
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """List organization members."""
    result = await db.execute(
        select(OrganizationMember)
        .where(OrganizationMember.organization_id == org_id)
    )
    return result.scalars().all()

@router.post("/{org_id}/members", response_model=MemberRead, status_code=status.HTTP_201_CREATED)
async def invite_member(
    org_id: int,
    member_in: MemberCreate,
    current_member: OrganizationMember = Depends(require_role("admin")),
    db: AsyncSession = Depends(get_db)
):
    """Invite a new member (admin only)."""
    # Find or create user
    result = await db.execute(select(User).where(User.email == member_in.email))
    user = result.scalar_one_or_none()
    
    if not user:
        # Create placeholder user
        from app.core.security import get_password_hash
        import secrets
        user = User(
            email=member_in.email,
            hashed_password=get_password_hash(secrets.token_urlsafe(32)),
            is_active=False  # Will activate on first login
        )
        db.add(user)
        await db.flush()
    
    # Check if already member
    result = await db.execute(
        select(OrganizationMember)
        .where(OrganizationMember.organization_id == org_id)
        .where(OrganizationMember.user_id == user.id)
    )
    if result.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="User is already a member")
    
    # Add member
    member = OrganizationMember(
        organization_id=org_id,
        user_id=user.id,
        role=member_in.role,
        invited_by_id=current_member.user_id
    )
    db.add(member)
    
    # Get org name for email
    org_result = await db.execute(select(Organization).where(Organization.id == org_id))
    org = org_result.scalar_one()
    
    # Send welcome email
    await EmailService.send_welcome(user.email, user.full_name or user.email, org.name)
    
    return member
