# services/tenant/app/api/whatsapp_admin.py
"""
WhatsApp Admin API Endpoints
Admin-only endpoints for managing WhatsApp phone number assignments
"""

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from uuid import UUID
from typing import List, Optional
from pydantic import BaseModel, Field
import httpx
import os

from app.core.database import get_db
from app.models.tenant_settings import TenantSettings
from app.models.tenants import Tenant

router = APIRouter()


# ================================================================
# SCHEMAS
# ================================================================

class WhatsAppPhoneNumberInfo(BaseModel):
    """Information about a WhatsApp phone number from Meta API"""
    id: str = Field(..., description="Phone Number ID")
    display_phone_number: str = Field(..., description="Display phone number (e.g., +34 612 345 678)")
    verified_name: str = Field(..., description="Verified business name")
    quality_rating: str = Field(..., description="Quality rating (GREEN, YELLOW, RED)")


class TenantWhatsAppStatus(BaseModel):
    """WhatsApp status for a tenant"""
    tenant_id: UUID
    tenant_name: str
    whatsapp_enabled: bool
    phone_number_id: Optional[str] = None
    display_phone_number: Optional[str] = None


class AssignPhoneNumberRequest(BaseModel):
    """Request to assign phone number to tenant"""
    phone_number_id: str = Field(..., description="Meta WhatsApp Phone Number ID")
    display_phone_number: str = Field(..., description="Display format (e.g., '+34 612 345 678')")


class AssignPhoneNumberResponse(BaseModel):
    """Response after assigning phone number"""
    success: bool
    message: str
    tenant_id: UUID
    phone_number_id: str
    display_phone_number: str


# ================================================================
# ENDPOINTS
# ================================================================

@router.get(
    "/admin/whatsapp/phone-numbers",
    response_model=List[WhatsAppPhoneNumberInfo],
    summary="List available WhatsApp phone numbers",
    description="Get all phone numbers available in the master WhatsApp Business Account"
)
async def list_available_phone_numbers():
    """
    List all phone numbers from the master WhatsApp Business Account

    Requires:
    - WHATSAPP_BUSINESS_ACCOUNT_ID environment variable
    - WHATSAPP_ACCESS_TOKEN environment variable

    Returns list of available phone numbers with their status
    """
    business_account_id = os.getenv("WHATSAPP_BUSINESS_ACCOUNT_ID")
    access_token = os.getenv("WHATSAPP_ACCESS_TOKEN")
    api_version = os.getenv("WHATSAPP_API_VERSION", "v18.0")

    if not business_account_id or not access_token:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="WhatsApp master account not configured. Set WHATSAPP_BUSINESS_ACCOUNT_ID and WHATSAPP_ACCESS_TOKEN environment variables."
        )

    try:
        # Fetch phone numbers from Meta Graph API
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.get(
                f"https://graph.facebook.com/{api_version}/{business_account_id}/phone_numbers",
                headers={"Authorization": f"Bearer {access_token}"},
                params={
                    "fields": "id,display_phone_number,verified_name,quality_rating"
                }
            )

            if response.status_code != 200:
                error_data = response.json()
                raise HTTPException(
                    status_code=status.HTTP_502_BAD_GATEWAY,
                    detail=f"Meta API error: {error_data.get('error', {}).get('message', 'Unknown error')}"
                )

            data = response.json()
            phone_numbers = data.get("data", [])

            return [
                WhatsAppPhoneNumberInfo(
                    id=phone.get("id"),
                    display_phone_number=phone.get("display_phone_number"),
                    verified_name=phone.get("verified_name", ""),
                    quality_rating=phone.get("quality_rating", "UNKNOWN")
                )
                for phone in phone_numbers
            ]

    except httpx.HTTPError as e:
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail=f"Failed to fetch phone numbers from Meta: {str(e)}"
        )


@router.get(
    "/admin/whatsapp/tenants",
    response_model=List[TenantWhatsAppStatus],
    summary="List all tenants with WhatsApp status",
    description="Get WhatsApp configuration status for all tenants"
)
async def list_tenant_whatsapp_status(
    db: AsyncSession = Depends(get_db)
):
    """
    List all tenants with their WhatsApp configuration status

    Returns:
    - tenant_id: Tenant UUID
    - tenant_name: Tenant name
    - whatsapp_enabled: Whether WhatsApp is enabled
    - phone_number_id: Assigned phone number ID (if any)
    - display_phone_number: Display format (if any)
    """
    # Query all tenants with their settings
    query = select(Tenant, TenantSettings).outerjoin(
        TenantSettings,
        Tenant.id == TenantSettings.tenant_id
    )

    result = await db.execute(query)
    rows = result.all()

    tenant_statuses = []
    for tenant, settings in rows:
        notification_settings = settings.notification_settings if settings else {}

        tenant_statuses.append(
            TenantWhatsAppStatus(
                tenant_id=tenant.id,
                tenant_name=tenant.name,
                whatsapp_enabled=notification_settings.get("whatsapp_enabled", False),
                phone_number_id=notification_settings.get("whatsapp_phone_number_id", ""),
                display_phone_number=notification_settings.get("whatsapp_display_phone_number", "")
            )
        )

    return tenant_statuses


@router.post(
    "/admin/whatsapp/tenants/{tenant_id}/assign-phone",
    response_model=AssignPhoneNumberResponse,
    summary="Assign phone number to tenant",
    description="Assign a WhatsApp phone number from the master account to a tenant"
)
async def assign_phone_number_to_tenant(
    tenant_id: UUID,
    request: AssignPhoneNumberRequest,
    db: AsyncSession = Depends(get_db)
):
    """
    Assign a WhatsApp phone number to a tenant

    - **tenant_id**: UUID of the tenant
    - **phone_number_id**: Meta Phone Number ID from master account
    - **display_phone_number**: Human-readable format (e.g., "+34 612 345 678")

    This will:
    1. Validate the tenant exists
    2. Check if phone number is already assigned to another tenant
    3. Update tenant's notification settings
    4. Enable WhatsApp for the tenant
    """
    # Verify tenant exists
    tenant_query = select(Tenant).where(Tenant.id == tenant_id)
    tenant_result = await db.execute(tenant_query)
    tenant = tenant_result.scalar_one_or_none()

    if not tenant:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tenant {tenant_id} not found"
        )

    # Check if phone number is already assigned to another tenant
    settings_query = select(TenantSettings).where(TenantSettings.tenant_id != tenant_id)
    settings_result = await db.execute(settings_query)
    all_settings = settings_result.scalars().all()

    for settings in all_settings:
        notification_settings = settings.notification_settings or {}
        if notification_settings.get("whatsapp_phone_number_id") == request.phone_number_id:
            # Get the other tenant's name
            other_tenant_query = select(Tenant).where(Tenant.id == settings.tenant_id)
            other_tenant_result = await db.execute(other_tenant_query)
            other_tenant = other_tenant_result.scalar_one_or_none()

            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=f"Phone number {request.display_phone_number} is already assigned to tenant '{other_tenant.name if other_tenant else 'Unknown'}'"
            )

    # Get or create tenant settings
    settings_query = select(TenantSettings).where(TenantSettings.tenant_id == tenant_id)
    settings_result = await db.execute(settings_query)
    settings = settings_result.scalar_one_or_none()

    if not settings:
        # Create default settings
        settings = TenantSettings(
            tenant_id=tenant_id,
            **TenantSettings.get_default_settings()
        )
        db.add(settings)

    # Update notification settings
    notification_settings = settings.notification_settings or {}
    notification_settings["whatsapp_enabled"] = True
    notification_settings["whatsapp_phone_number_id"] = request.phone_number_id
    notification_settings["whatsapp_display_phone_number"] = request.display_phone_number

    settings.notification_settings = notification_settings

    await db.commit()
    await db.refresh(settings)

    return AssignPhoneNumberResponse(
        success=True,
        message=f"Phone number {request.display_phone_number} assigned to tenant '{tenant.name}'",
        tenant_id=tenant_id,
        phone_number_id=request.phone_number_id,
        display_phone_number=request.display_phone_number
    )


@router.delete(
    "/admin/whatsapp/tenants/{tenant_id}/unassign-phone",
    response_model=AssignPhoneNumberResponse,
    summary="Unassign phone number from tenant",
    description="Remove WhatsApp phone number assignment from a tenant"
)
async def unassign_phone_number_from_tenant(
    tenant_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    Unassign WhatsApp phone number from a tenant

    - **tenant_id**: UUID of the tenant

    This will:
    1. Clear the phone number assignment
    2. Disable WhatsApp for the tenant
    """
    # Get tenant settings
    settings_query = select(TenantSettings).where(TenantSettings.tenant_id == tenant_id)
    settings_result = await db.execute(settings_query)
    settings = settings_result.scalar_one_or_none()

    if not settings:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Settings not found for tenant {tenant_id}"
        )

    # Get current values for response
    notification_settings = settings.notification_settings or {}
    old_phone_id = notification_settings.get("whatsapp_phone_number_id", "")
    old_display_phone = notification_settings.get("whatsapp_display_phone_number", "")

    # Update notification settings
    notification_settings["whatsapp_enabled"] = False
    notification_settings["whatsapp_phone_number_id"] = ""
    notification_settings["whatsapp_display_phone_number"] = ""

    settings.notification_settings = notification_settings

    await db.commit()

    return AssignPhoneNumberResponse(
        success=True,
        message=f"Phone number unassigned from tenant",
        tenant_id=tenant_id,
        phone_number_id=old_phone_id,
        display_phone_number=old_display_phone
    )
