"""
Internal Demo Cloning API for Auth Service
Service-to-service endpoint for cloning authentication and user 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
import sys
from pathlib import Path
import json

# Add shared path
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent.parent))

from app.core.database import get_db
from app.models.users import User

from app.core.config import settings

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

# Base demo tenant IDs
DEMO_TENANT_PROFESSIONAL = "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6"


@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,
    session_created_at: Optional[str] = None,
    db: AsyncSession = Depends(get_db)
):
    """
    Clone auth service data for a virtual demo tenant

    Clones:
    - Demo users (owner and staff)

    Note: Tenant memberships are handled by the tenant service's internal_demo endpoint

    Args:
        base_tenant_id: Template tenant UUID to clone from
        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 counts
    """
    start_time = datetime.now(timezone.utc)

    # Parse session creation time
    if session_created_at:
        try:
            session_time = datetime.fromisoformat(session_created_at.replace('Z', '+00:00'))
        except (ValueError, AttributeError):
            session_time = start_time
    else:
        session_time = start_time

    logger.info(
        "Starting auth data cloning",
        base_tenant_id=base_tenant_id,
        virtual_tenant_id=virtual_tenant_id,
        demo_account_type=demo_account_type,
        session_id=session_id,
        session_created_at=session_created_at
    )

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

        # Note: We don't check for existing users since User model doesn't have demo_session_id
        # Demo users are identified by their email addresses from the seed data
        # Idempotency is handled by checking if each user email already exists below

        # Load demo users from JSON seed file
        from shared.utils.seed_data_paths import get_seed_data_path

        if demo_account_type == "professional":
            json_file = get_seed_data_path("professional", "02-auth.json")
        elif demo_account_type == "enterprise":
            json_file = get_seed_data_path("enterprise", "02-auth.json")
        elif demo_account_type == "enterprise_child":
            # Child locations don't have separate auth data - they share parent's users
            logger.info("enterprise_child uses parent tenant auth, skipping user cloning", virtual_tenant_id=virtual_tenant_id)
            return {
                "service": "auth",
                "status": "completed",
                "records_cloned": 0,
                "duration_ms": int((datetime.now(timezone.utc) - start_time).total_seconds() * 1000),
                "details": {"users": 0, "note": "Child locations share parent auth"}
            }
        else:
            raise ValueError(f"Invalid demo account type: {demo_account_type}")

        # Load JSON data
        import json
        with open(json_file, 'r', encoding='utf-8') as f:
            seed_data = json.load(f)

        # Get demo users for this account type
        demo_users_data = seed_data.get("users", [])

        records_cloned = 0

        # Create users and tenant memberships
        for user_data in demo_users_data:
            user_id = uuid.UUID(user_data["id"])

            # Create user if not exists
            user_result = await db.execute(
                select(User).where(User.id == user_id)
            )
            existing_user = user_result.scalars().first()

            if not existing_user:
                # Apply date adjustments to created_at and updated_at
                from shared.utils.demo_dates import adjust_date_for_demo

                # Adjust created_at date
                created_at_str = user_data.get("created_at", session_time.isoformat())
                if isinstance(created_at_str, str):
                    try:
                        original_created_at = datetime.fromisoformat(created_at_str.replace('Z', '+00:00'))
                        adjusted_created_at = adjust_date_for_demo(original_created_at, session_time)
                    except ValueError:
                        adjusted_created_at = session_time
                else:
                    adjusted_created_at = session_time

                # Adjust updated_at date (same as created_at for demo users)
                adjusted_updated_at = adjusted_created_at

                # Get full_name from either "name" or "full_name" field
                full_name = user_data.get("full_name") or user_data.get("name", "Demo User")

                # For demo users, use a placeholder hashed password (they won't actually log in)
                # In production, this would be properly hashed
                demo_hashed_password = "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYqNlI.eFKW"  # "demo_password"

                user = User(
                    id=user_id,
                    email=user_data["email"],
                    full_name=full_name,
                    hashed_password=demo_hashed_password,
                    is_active=user_data.get("is_active", True),
                    is_verified=True,
                    role=user_data.get("role", "member"),
                    language=user_data.get("language", "es"),
                    timezone=user_data.get("timezone", "Europe/Madrid"),
                    created_at=adjusted_created_at,
                    updated_at=adjusted_updated_at
                )
                db.add(user)
                records_cloned += 1

            # Note: Tenant memberships are handled by tenant service
            # Only create users in auth service

        await db.commit()

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

        logger.info(
            "Auth data cloning completed",
            virtual_tenant_id=virtual_tenant_id,
            session_id=session_id,
            records_cloned=records_cloned,
            duration_ms=duration_ms
        )

        return {
            "service": "auth",
            "status": "completed",
            "records_cloned": records_cloned,
            "base_tenant_id": str(base_tenant_id),
            "virtual_tenant_id": str(virtual_tenant_id),
            "session_id": session_id,
            "demo_account_type": demo_account_type,
            "duration_ms": duration_ms
        }

    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 auth data",
            error=str(e),
            virtual_tenant_id=virtual_tenant_id,
            exc_info=True
        )

        # Rollback on error
        await db.rollback()

        return {
            "service": "auth",
            "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():
    """
    Health check for internal cloning endpoint
    Used by orchestrator to verify service availability
    """
    return {
        "service": "auth",
        "clone_endpoint": "available",
        "version": "1.0.0"
    }