# src/fmatch/saas/api/v2/findings.py
"""
API endpoints for survey findings and actions.
"""

from fastapi import APIRouter, Depends, HTTPException, Query, BackgroundTasks
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional, List
import csv
import io
from datetime import datetime

from ...db import get_session
from ...auth import get_current_account
from ...auth.users import get_current_user
from ...services.survey_results_service import SurveyResultsService
from ...services.salesforce_gateway import SalesforceGateway, get_salesforce_gateway

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


@router.get("/survey/{survey_id}")
async def get_survey_findings(
    survey_id: str,
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=100),
    min_confidence: Optional[float] = Query(None, ge=0, le=1),
    finding_type: Optional[str] = Query(None),
    tier: Optional[str] = Query(None),
    object_type: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    db: AsyncSession = Depends(get_session),
    account_id: str = Depends(get_current_account),
):
    """Get paginated survey findings with filters."""
    service = SurveyResultsService(db)

    return await service.get_survey_with_findings(
        survey_id=survey_id,
        page=page,
        page_size=page_size,
        min_confidence=min_confidence,
        finding_type=finding_type,
        tier=tier,
        object_type=object_type,
        status=status,
    )


@router.post("/survey/{survey_id}/action-batch")
async def create_action_batch(
    survey_id: str,
    finding_ids: List[str],
    db: AsyncSession = Depends(get_session),
    user_id: str = Depends(get_current_user),
):
    """Convert findings to action batch."""
    service = SurveyResultsService(db)

    batch = await service.convert_to_action_batch(
        survey_id=survey_id, finding_ids=finding_ids, user_id=user_id
    )

    return {"batch_id": batch.id, "status": "created"}


@router.post("/{finding_id}/status")
async def update_finding_status(
    finding_id: str,
    status: str,
    notes: Optional[str] = None,
    db: AsyncSession = Depends(get_session),
    user_id: str = Depends(get_current_user),
):
    """Update finding status."""
    service = SurveyResultsService(db)

    await service.update_finding_status(
        finding_id=finding_id, status=status, user_id=user_id, notes=notes
    )

    return {"status": "updated"}


@router.post("/survey/{survey_id}/export")
async def export_findings(
    survey_id: str,
    finding_ids: Optional[List[str]] = None,
    db: AsyncSession = Depends(get_session),
    account_id: str = Depends(get_current_account),
):
    """Export findings to CSV."""
    service = SurveyResultsService(db)

    # Get findings
    data = await service.get_survey_with_findings(
        survey_id=survey_id,
        page=1,
        page_size=10000,  # Get all for export
    )

    # Filter by IDs if provided
    findings = data["findings"]
    if finding_ids:
        findings = [f for f in findings if f["id"] in finding_ids]

    # Generate CSV
    output = io.StringIO()
    writer = csv.DictWriter(
        output,
        fieldnames=[
            "id",
            "object_type",
            "confidence_score",
            "confidence_tier",
            "explanation",
            "record_ids",
            "status",
        ],
    )
    writer.writeheader()

    for finding in findings:
        writer.writerow(
            {
                "id": finding["id"],
                "object_type": finding["object_type"],
                "confidence_score": finding["confidence_score"],
                "confidence_tier": finding["confidence_tier"],
                "explanation": finding["explanation"],
                "record_ids": ",".join(finding["record_ids"]),
                "status": finding["status"],
            }
        )

    return {
        "csv": output.getvalue(),
        "filename": f"survey_{survey_id}_findings_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.csv",
    }


@router.post("/merge")
async def merge_records(
    merge_request: dict,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_session),
    account_id: str = Depends(get_current_account),
    sf: SalesforceGateway = Depends(get_salesforce_gateway),
):
    """Merge Salesforce records."""
    # Perform merge using native Salesforce merge
    master_id = merge_request["master_id"]
    victim_ids = merge_request["victim_ids"]
    object_type = merge_request["object_type"]

    # Extract field preservation preferences if provided
    preserve_fields = {}
    if "field_selections" in merge_request:
        # Map field selections to preservation format
        for victim_id in victim_ids:
            fields_to_preserve = []
            for field, source_id in merge_request["field_selections"].items():
                if source_id == victim_id:
                    fields_to_preserve.append(field)
            if fields_to_preserve:
                preserve_fields[victim_id] = fields_to_preserve

    # Use native Salesforce merge - preserves relationships and audit trail!
    merge_result = await sf.merge_records(
        object_type=object_type,
        master_id=master_id,
        duplicate_ids=victim_ids,
        preserve_fields=preserve_fields,
    )

    if not merge_result.get("success"):
        raise HTTPException(500, f"Merge failed: {merge_result.get('error')}")

    # Update finding status if provided
    if "finding_id" in merge_request:
        service = SurveyResultsService(db)
        await service.update_finding_status(
            merge_request["finding_id"],
            "merged",
            account_id,
            f"Merged into {master_id} using native Salesforce merge",
        )

    return {
        "status": "merged",
        "merged_record_id": master_id,
        "merged_records": victim_ids,
        "method": "native_salesforce_merge",
        "preserved_relationships": True,
        "audit_trail": True,
    }
