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

from ...db import get_session
from ...auth import get_current_account
from ...services.roles import require_steward, require_viewer
from ...models import Investigation, Finding, User
from ...services.investigation_service import InvestigationService

router = APIRouter(prefix="/api/v2/investigations", tags=["investigations"])


class CreateInvestigation(BaseModel):
    objects: List[str] = ["Account", "Lead", "Contact"]
    schedule_cron: Optional[str] = None


@router.post("")
async def create_investigation(
    body: CreateInvestigation,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_session),
    account_id: UUID = Depends(get_current_account),
    user: User = Depends(require_steward),  # Stewards can run investigations
):
    """Create and optionally run an investigation"""
    investigation = Investigation(
        account_id=str(account_id),
        type="salesforce_scan",
        params={"objects": body.objects},
        schedule_cron=body.schedule_cron,
        created_by_user_id=str(user.id),  # Track who created it
    )
    db.add(investigation)
    await db.commit()
    await db.refresh(investigation)

    # Run immediately if not scheduled
    if not body.schedule_cron:
        service = InvestigationService(db)
        background_tasks.add_task(service.run_investigation, investigation.id)

    return {
        "id": investigation.id,
        "status": investigation.status,
        "message": "Investigation created",
    }


@router.get("")
async def list_investigations(
    limit: int = 20,
    offset: int = 0,
    db: AsyncSession = Depends(get_session),
    account_id: UUID = Depends(get_current_account),
    _user: User = Depends(require_viewer),  # Viewers can list investigations
):
    """List investigations for account"""
    stmt = (
        select(Investigation)
        .where(Investigation.account_id == str(account_id))
        .order_by(Investigation.created_at.desc())
        .limit(limit)
        .offset(offset)
    )

    result = await db.execute(stmt)
    investigations = result.scalars().all()

    return {
        "investigations": [
            {
                "id": inv.id,
                "status": inv.status,
                "stats": inv.stats,
                "created_at": inv.created_at.isoformat() if inv.created_at else None,
                "finished_at": inv.finished_at.isoformat() if inv.finished_at else None,
            }
            for inv in investigations
        ]
    }


@router.get("/{id}/findings")
async def get_findings(
    id: str,
    category: Optional[str] = None,
    limit: int = 100,
    offset: int = 0,
    db: AsyncSession = Depends(get_session),
    account_id: UUID = Depends(get_current_account),
    _user: User = Depends(require_viewer),  # Viewers can view findings
):
    """Get findings for an investigation"""
    # Verify investigation belongs to account
    investigation = await db.get(Investigation, id)
    if not investigation or investigation.account_id != str(account_id):
        raise HTTPException(404, "Investigation not found")

    # Build query
    stmt = select(Finding).where(Finding.investigation_id == id)
    if category:
        stmt = stmt.where(Finding.category == category)
    stmt = stmt.limit(limit).offset(offset)

    result = await db.execute(stmt)
    findings = result.scalars().all()

    return {
        "findings": [
            {
                "id": f.id,
                "object_type": f.object_type,
                "category": f.category,
                "score": f.score,
                "cluster_id": f.cluster_id,
                "records": f.records,
                "suggestion": f.suggestion,
            }
            for f in findings
        ]
    }
