"""
Demo Operations API - Business operations for demo session management
"""

from fastapi import APIRouter, Depends, HTTPException, Path
import structlog
import jwt
from datetime import datetime, timezone

from app.api.schemas import DemoSessionResponse, DemoSessionStats
from app.services import DemoSessionManager, DemoCleanupService
from app.core import get_db, get_redis, DemoRedisWrapper
from sqlalchemy.ext.asyncio import AsyncSession
from shared.routing import RouteBuilder

router = APIRouter(tags=["demo-operations"])
logger = structlog.get_logger()

route_builder = RouteBuilder('demo')


@router.post(
    route_builder.build_resource_action_route("sessions", "session_id", "extend", include_tenant_prefix=False),
    response_model=DemoSessionResponse
)
async def extend_demo_session(
    session_id: str = Path(...),
    db: AsyncSession = Depends(get_db),
    redis: DemoRedisWrapper = Depends(get_redis)
):
    """Extend demo session expiration (BUSINESS OPERATION)"""
    try:
        session_manager = DemoSessionManager(db, redis)
        session = await session_manager.extend_session(session_id)

        session_token = jwt.encode(
            {
                "session_id": session.session_id,
                "virtual_tenant_id": str(session.virtual_tenant_id),
                "demo_account_type": session.demo_account_type,
                "exp": session.expires_at.timestamp()
            },
            "demo-secret-key",
            algorithm="HS256"
        )

        return {
            "session_id": session.session_id,
            "virtual_tenant_id": str(session.virtual_tenant_id),
            "demo_account_type": session.demo_account_type,
            "status": session.status.value,
            "created_at": session.created_at,
            "expires_at": session.expires_at,
            "demo_config": session.session_metadata.get("demo_config", {}),
            "session_token": session_token
        }

    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Failed to extend session", error=str(e))
        raise HTTPException(status_code=500, detail=str(e))


@router.get(
    route_builder.build_base_route("stats", include_tenant_prefix=False),
    response_model=DemoSessionStats
)
async def get_demo_stats(
    db: AsyncSession = Depends(get_db),
    redis: DemoRedisWrapper = Depends(get_redis)
):
    """Get demo session statistics (BUSINESS OPERATION)"""
    session_manager = DemoSessionManager(db, redis)
    stats = await session_manager.get_session_stats()
    return stats


@router.post(
    route_builder.build_operations_route("cleanup", include_tenant_prefix=False),
    response_model=dict
)
async def run_cleanup(
    db: AsyncSession = Depends(get_db),
    redis: DemoRedisWrapper = Depends(get_redis)
):
    """
    Trigger session cleanup via background worker (async via Redis queue)

    Returns immediately after enqueuing work - does not block
    """
    from datetime import timedelta
    from sqlalchemy import select
    from app.models.demo_session import DemoSession, DemoSessionStatus
    import uuid
    import json

    logger.info("Starting demo session cleanup enqueue")

    now = datetime.now(timezone.utc)
    stuck_threshold = now - timedelta(minutes=5)

    # Find expired sessions
    result = await db.execute(
        select(DemoSession).where(
            DemoSession.status.in_([
                DemoSessionStatus.PENDING,
                DemoSessionStatus.READY,
                DemoSessionStatus.PARTIAL,
                DemoSessionStatus.FAILED,
                DemoSessionStatus.ACTIVE
            ]),
            DemoSession.expires_at < now
        )
    )
    expired_sessions = result.scalars().all()

    # Find stuck sessions
    stuck_result = await db.execute(
        select(DemoSession).where(
            DemoSession.status == DemoSessionStatus.PENDING,
            DemoSession.created_at < stuck_threshold
        )
    )
    stuck_sessions = stuck_result.scalars().all()

    all_sessions = list(expired_sessions) + list(stuck_sessions)

    if not all_sessions:
        return {
            "status": "no_sessions",
            "message": "No sessions to cleanup",
            "total_expired": 0,
            "total_stuck": 0
        }

    # Create cleanup job
    job_id = str(uuid.uuid4())
    session_ids = [s.session_id for s in all_sessions]

    job_data = {
        "job_id": job_id,
        "session_ids": session_ids,
        "created_at": now.isoformat(),
        "retry_count": 0
    }

    # Enqueue job
    client = await redis.get_client()
    await client.lpush("cleanup:queue", json.dumps(job_data))

    logger.info(
        "Cleanup job enqueued",
        job_id=job_id,
        session_count=len(session_ids),
        expired_count=len(expired_sessions),
        stuck_count=len(stuck_sessions)
    )

    return {
        "status": "enqueued",
        "job_id": job_id,
        "session_count": len(session_ids),
        "total_expired": len(expired_sessions),
        "total_stuck": len(stuck_sessions),
        "message": f"Cleanup job enqueued for {len(session_ids)} sessions"
    }


@router.get(
    route_builder.build_operations_route("cleanup/{job_id}", include_tenant_prefix=False),
    response_model=dict
)
async def get_cleanup_status(
    job_id: str,
    redis: DemoRedisWrapper = Depends(get_redis)
):
    """Get status of cleanup job"""
    import json

    client = await redis.get_client()
    status_key = f"cleanup:job:{job_id}:status"

    status_data = await client.get(status_key)
    if not status_data:
        return {
            "status": "not_found",
            "message": "Job not found or expired (jobs expire after 1 hour)"
        }

    return json.loads(status_data)


@router.post(
    "/demo/sessions/{session_id}/seed-alerts",
    response_model=dict
)
async def seed_demo_alerts(
    session_id: str = Path(...),
    db: AsyncSession = Depends(get_db),
    redis: DemoRedisWrapper = Depends(get_redis)
):
    """Seed enriched demo alerts for a demo session (DEMO OPERATION)"""
    try:
        import subprocess
        import os

        # Get session to validate and get tenant_id
        session_manager = DemoSessionManager(db, redis)
        session = await session_manager.get_session(session_id)

        if not session:
            raise HTTPException(status_code=404, detail="Demo session not found")

        # Set environment variables for seeding script
        env = os.environ.copy()
        env['DEMO_TENANT_ID'] = str(session.virtual_tenant_id)

        # Determine script path based on environment
        # In container: /app/scripts/seed_enriched_alert_demo.py
        # In development: services/demo_session/scripts/seed_enriched_alert_demo.py
        script_path = '/app/scripts/seed_enriched_alert_demo.py' if os.path.exists('/app/scripts') else 'services/demo_session/scripts/seed_enriched_alert_demo.py'

        # Run the seeding script
        result = subprocess.run(
            ['python3', script_path],
            env=env,
            capture_output=True,
            text=True,
            timeout=30
        )

        if result.returncode != 0:
            logger.error("Alert seeding failed",
                        stdout=result.stdout,
                        stderr=result.stderr)
            raise HTTPException(status_code=500, detail=f"Alert seeding failed: {result.stderr}")

        logger.info("Demo alerts seeded successfully", session_id=session_id)

        return {
            "status": "success",
            "session_id": session_id,
            "tenant_id": str(session.virtual_tenant_id),
            "alerts_seeded": 5,
            "message": "Demo alerts published and will be enriched automatically"
        }

    except subprocess.TimeoutExpired:
        raise HTTPException(status_code=504, detail="Alert seeding timeout")
    except Exception as e:
        logger.error("Failed to seed alerts", error=str(e), session_id=session_id)
        raise HTTPException(status_code=500, detail=str(e))
