"""
Internal Demo Cloning API
Service-to-service endpoint for cloning tenant data
"""

from fastapi import APIRouter, Depends, HTTPException, Header
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
import structlog
import uuid
from datetime import datetime, timezone
from typing import Optional
import os

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

logger = structlog.get_logger()
router = APIRouter(prefix="/internal/demo", tags=["internal"])

# Internal API key for service-to-service auth
INTERNAL_API_KEY = os.getenv("INTERNAL_API_KEY", "dev-internal-key-change-in-production")

# Base demo tenant IDs
DEMO_TENANT_SAN_PABLO = "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6"
DEMO_TENANT_LA_ESPIGA = "b2c3d4e5-f6a7-48b9-c0d1-e2f3a4b5c6d7"


def verify_internal_api_key(x_internal_api_key: Optional[str] = Header(None)):
    """Verify internal API key for service-to-service communication"""
    if x_internal_api_key != INTERNAL_API_KEY:
        logger.warning("Unauthorized internal API access attempted")
        raise HTTPException(status_code=403, detail="Invalid internal API key")
    return True


@router.post("/clone")
async def clone_demo_data(
    base_tenant_id: str,
    virtual_tenant_id: str,
    demo_account_type: str,
    session_id: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    _: bool = Depends(verify_internal_api_key)
):
    """
    Clone tenant service data for a virtual demo tenant

    This endpoint creates the virtual tenant record that will be used
    for the demo session. No actual data cloning is needed in tenant service
    beyond creating the tenant record itself.

    Args:
        base_tenant_id: Template tenant UUID (not used, for consistency)
        virtual_tenant_id: Target virtual tenant UUID
        demo_account_type: Type of demo account
        session_id: Originating session ID for tracing

    Returns:
        Cloning status and record count
    """
    start_time = datetime.now(timezone.utc)

    logger.info(
        "Starting tenant data cloning",
        virtual_tenant_id=virtual_tenant_id,
        demo_account_type=demo_account_type,
        session_id=session_id
    )

    try:
        # Validate UUIDs
        virtual_uuid = uuid.UUID(virtual_tenant_id)

        # Check if tenant already exists
        result = await db.execute(
            select(Tenant).where(Tenant.id == virtual_uuid)
        )
        existing_tenant = result.scalars().first()

        if existing_tenant:
            logger.info(
                "Virtual tenant already exists",
                virtual_tenant_id=virtual_tenant_id,
                tenant_name=existing_tenant.name
            )

            # Ensure the tenant has a subscription (copy from template if missing)
            from app.models.tenants import Subscription
            from datetime import timedelta

            result = await db.execute(
                select(Subscription).where(
                    Subscription.tenant_id == virtual_uuid,
                    Subscription.status == "active"
                )
            )
            existing_subscription = result.scalars().first()

            if not existing_subscription:
                logger.info("Creating missing subscription for existing virtual tenant by copying from template",
                           virtual_tenant_id=virtual_tenant_id,
                           base_tenant_id=base_tenant_id)

                # Get subscription from template tenant
                base_uuid = uuid.UUID(base_tenant_id)
                result = await db.execute(
                    select(Subscription).where(
                        Subscription.tenant_id == base_uuid,
                        Subscription.status == "active"
                    )
                )
                template_subscription = result.scalars().first()

                if template_subscription:
                    # Clone subscription from template
                    subscription = Subscription(
                        tenant_id=virtual_uuid,
                        plan=template_subscription.plan,
                        status=template_subscription.status,
                        monthly_price=template_subscription.monthly_price,
                        max_users=template_subscription.max_users,
                        max_locations=template_subscription.max_locations,
                        max_products=template_subscription.max_products,
                        features=template_subscription.features.copy() if template_subscription.features else {},
                        trial_ends_at=template_subscription.trial_ends_at,
                        next_billing_date=datetime.now(timezone.utc) + timedelta(days=90) if template_subscription.next_billing_date else None
                    )

                    db.add(subscription)
                    await db.commit()

                    logger.info("Subscription cloned successfully",
                               virtual_tenant_id=virtual_tenant_id,
                               plan=subscription.plan)
                else:
                    logger.warning("No subscription found on template tenant",
                                  base_tenant_id=base_tenant_id)

            # Return success - idempotent operation
            duration_ms = int((datetime.now(timezone.utc) - start_time).total_seconds() * 1000)
            return {
                "service": "tenant",
                "status": "completed",
                "records_cloned": 0 if existing_subscription else 1,
                "duration_ms": duration_ms,
                "details": {
                    "tenant_already_exists": True,
                    "tenant_id": str(virtual_uuid),
                    "subscription_created": not existing_subscription
                }
            }

        # Create virtual tenant record with required fields
        # Note: Use the actual demo user IDs from seed_demo_users.py
        # These match the demo users created in the auth service
        DEMO_OWNER_IDS = {
            "individual_bakery": "c1a2b3c4-d5e6-47a8-b9c0-d1e2f3a4b5c6",  # María García López (San Pablo)
            "central_baker": "d2e3f4a5-b6c7-48d9-e0f1-a2b3c4d5e6f7"      # Carlos Martínez Ruiz (La Espiga)
        }
        demo_owner_uuid = uuid.UUID(DEMO_OWNER_IDS.get(demo_account_type, DEMO_OWNER_IDS["individual_bakery"]))

        tenant = Tenant(
            id=virtual_uuid,
            name=f"Demo Tenant - {demo_account_type.replace('_', ' ').title()}",
            address="Calle Demo 123",  # Required field - provide demo address
            city="Madrid",
            postal_code="28001",
            business_type="bakery",
            is_demo=True,
            is_demo_template=False,
            business_model=demo_account_type,
            is_active=True,
            timezone="Europe/Madrid",
            owner_id=demo_owner_uuid  # Required field - matches seed_demo_users.py
        )

        db.add(tenant)
        await db.flush()  # Flush to get the tenant ID

        # Create demo subscription (enterprise tier for full access)
        from app.models.tenants import Subscription
        demo_subscription = Subscription(
            tenant_id=tenant.id,
            plan="enterprise",  # Demo gets full access
            status="active",
            monthly_price=0.0,  # Free for demo
            billing_cycle="monthly",
            max_users=-1,  # Unlimited
            max_locations=-1,
            max_products=-1,
            features={}
        )
        db.add(demo_subscription)

        # Create tenant member records for demo owner and staff
        from app.models.tenants import TenantMember
        import json

        # Helper function to get permissions for role
        def get_permissions_for_role(role: str) -> str:
            permission_map = {
                "owner": ["read", "write", "admin", "delete"],
                "admin": ["read", "write", "admin"],
                "production_manager": ["read", "write"],
                "baker": ["read", "write"],
                "sales": ["read", "write"],
                "quality_control": ["read", "write"],
                "warehouse": ["read", "write"],
                "logistics": ["read", "write"],
                "procurement": ["read", "write"],
                "maintenance": ["read", "write"],
                "member": ["read", "write"],
                "viewer": ["read"]
            }
            permissions = permission_map.get(role, ["read"])
            return json.dumps(permissions)

        # Define staff users for each demo account type (must match seed_demo_tenant_members.py)
        STAFF_USERS = {
            "individual_bakery": [
                # Owner
                {
                    "user_id": uuid.UUID("c1a2b3c4-d5e6-47a8-b9c0-d1e2f3a4b5c6"),
                    "role": "owner"
                },
                # Staff
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000001"),
                    "role": "baker"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000002"),
                    "role": "sales"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000003"),
                    "role": "quality_control"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000004"),
                    "role": "admin"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000005"),
                    "role": "warehouse"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000006"),
                    "role": "production_manager"
                }
            ],
            "central_baker": [
                # Owner
                {
                    "user_id": uuid.UUID("d2e3f4a5-b6c7-48d9-e0f1-a2b3c4d5e6f7"),
                    "role": "owner"
                },
                # Staff
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000011"),
                    "role": "production_manager"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000012"),
                    "role": "quality_control"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000013"),
                    "role": "logistics"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000014"),
                    "role": "sales"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000015"),
                    "role": "procurement"
                },
                {
                    "user_id": uuid.UUID("50000000-0000-0000-0000-000000000016"),
                    "role": "maintenance"
                }
            ]
        }

        # Get staff users for this demo account type
        staff_users = STAFF_USERS.get(demo_account_type, [])

        # Create tenant member records for all users (owner + staff)
        members_created = 0
        for staff_member in staff_users:
            tenant_member = TenantMember(
                tenant_id=virtual_uuid,
                user_id=staff_member["user_id"],
                role=staff_member["role"],
                permissions=get_permissions_for_role(staff_member["role"]),
                is_active=True,
                invited_by=demo_owner_uuid,
                invited_at=datetime.now(timezone.utc),
                joined_at=datetime.now(timezone.utc),
                created_at=datetime.now(timezone.utc)
            )
            db.add(tenant_member)
            members_created += 1

        logger.info(
            "Created tenant members for virtual tenant",
            virtual_tenant_id=virtual_tenant_id,
            members_created=members_created
        )

        # Clone subscription from template tenant
        from app.models.tenants import Subscription
        from datetime import timedelta

        # Get subscription from template tenant
        base_uuid = uuid.UUID(base_tenant_id)
        result = await db.execute(
            select(Subscription).where(
                Subscription.tenant_id == base_uuid,
                Subscription.status == "active"
            )
        )
        template_subscription = result.scalars().first()

        subscription_plan = "unknown"
        if template_subscription:
            # Clone subscription from template
            subscription = Subscription(
                tenant_id=virtual_uuid,
                plan=template_subscription.plan,
                status=template_subscription.status,
                monthly_price=template_subscription.monthly_price,
                max_users=template_subscription.max_users,
                max_locations=template_subscription.max_locations,
                max_products=template_subscription.max_products,
                features=template_subscription.features.copy() if template_subscription.features else {},
                trial_ends_at=template_subscription.trial_ends_at,
                next_billing_date=datetime.now(timezone.utc) + timedelta(days=90) if template_subscription.next_billing_date else None
            )

            db.add(subscription)
            subscription_plan = subscription.plan

            logger.info(
                "Cloning subscription from template tenant",
                template_tenant_id=base_tenant_id,
                virtual_tenant_id=virtual_tenant_id,
                plan=subscription_plan
            )
        else:
            logger.warning(
                "No subscription found on template tenant - virtual tenant will have no subscription",
                base_tenant_id=base_tenant_id
            )

        await db.commit()
        await db.refresh(tenant)

        duration_ms = int((datetime.now(timezone.utc) - start_time).total_seconds() * 1000)

        logger.info(
            "Virtual tenant created successfully with cloned subscription",
            virtual_tenant_id=virtual_tenant_id,
            tenant_name=tenant.name,
            subscription_plan=subscription_plan,
            duration_ms=duration_ms
        )

        records_cloned = 1 + members_created  # Tenant + TenantMembers
        if template_subscription:
            records_cloned += 1  # Subscription

        return {
            "service": "tenant",
            "status": "completed",
            "records_cloned": records_cloned,
            "duration_ms": duration_ms,
            "details": {
                "tenant_id": str(tenant.id),
                "tenant_name": tenant.name,
                "business_model": tenant.business_model,
                "owner_id": str(demo_owner_uuid),
                "members_created": members_created,
                "subscription_plan": subscription_plan,
                "subscription_cloned": template_subscription is not None
            }
        }

    except ValueError as e:
        logger.error("Invalid UUID format", error=str(e), virtual_tenant_id=virtual_tenant_id)
        raise HTTPException(status_code=400, detail=f"Invalid UUID: {str(e)}")

    except Exception as e:
        logger.error(
            "Failed to clone tenant data",
            error=str(e),
            virtual_tenant_id=virtual_tenant_id,
            exc_info=True
        )

        # Rollback on error
        await db.rollback()

        return {
            "service": "tenant",
            "status": "failed",
            "records_cloned": 0,
            "duration_ms": int((datetime.now(timezone.utc) - start_time).total_seconds() * 1000),
            "error": str(e)
        }


@router.get("/clone/health")
async def clone_health_check(_: bool = Depends(verify_internal_api_key)):
    """
    Health check for internal cloning endpoint
    Used by orchestrator to verify service availability
    """
    return {
        "service": "tenant",
        "clone_endpoint": "available",
        "version": "2.0.0"
    }
