import logging
import uuid
from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi.responses import StreamingResponse
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from starlette.responses import Response

from app.api.deps import get_current_user
from app.database import get_db
from app.models.brand import Brand
from app.models.user import User
from app.schemas.scoring import CitationResult
from app.services.citation.citation import export_citations_csv, export_citations_pdf
from app.services.scoring.scoring_service import ScoringService, ScoringResultV2

logger = logging.getLogger(__name__)

router = APIRouter()


async def _compute_v2_scores(
    db: AsyncSession,
    user_id: uuid.UUID,
    brand_id: uuid.UUID,
) -> ScoringResultV2 | None:
    try:
        from app.api.scoring import (
            _get_citations_for_brand,
            _analyze_sentiments_for_citations,
        )

        total_queries, brand_citations, _, competitor_mentions = (
            await _get_citations_for_brand(db, user_id, brand_id)
        )

        if total_queries == 0:
            return None

        brand_stmt = select(Brand).where(
            Brand.id == brand_id, Brand.user_id == user_id
        )
        brand_result = await db.execute(brand_stmt)
        brand = brand_result.scalar_one_or_none()
        if not brand:
            return None

        sentiment_counts = await _analyze_sentiments_for_citations(
            brand_name=brand.name,
            brand_citations=brand_citations,
        )

        citation_results = [
            CitationResult(
                cited=c.cited,
                position=c.citation_position,
                citation_text=c.citation_text,
                sentiment=c.sentiment or "neutral",
                confidence=c.confidence or 0.0,
            )
            for c in brand_citations
        ]

        positions = [c.citation_position for c in brand_citations if c.cited]

        scoring_service = ScoringService()
        return scoring_service.calculate_v2(
            mentioned_count=len(brand_citations),
            total_queries=total_queries,
            positions=positions,
            sentiment_counts=sentiment_counts,
            citations=citation_results,
            brand_mentions=len(brand_citations),
            competitor_mentions=competitor_mentions,
        )
    except Exception:
        logger.warning("V2 scoring failed for brand %s", brand_id, exc_info=True)
        return None


@router.get("/export/csv")
async def export_report(
    query_id: uuid.UUID = Query(...),
    brand_id: Optional[uuid.UUID] = Query(None),
    format: str = Query("csv"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    if format != "csv":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Only CSV format is supported",
        )

    try:
        v2_result = None
        if brand_id is not None:
            v2_result = await _compute_v2_scores(db, current_user.id, brand_id)

        csv_content = await export_citations_csv(
            db, current_user.id, query_id, v2_result=v2_result
        )
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=str(e),
        )

    date_str = datetime.now().strftime("%Y%m%d")
    filename = f"geo-report-{date_str}.csv"

    return StreamingResponse(
        iter([csv_content]),
        media_type="text/csv",
        headers={
            "Content-Disposition": f'attachment; filename="{filename}"',
        },
    )


@router.get("/export/pdf")
async def export_pdf(
    query_id: Optional[uuid.UUID] = None,
    brand_id: Optional[uuid.UUID] = Query(None),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    try:
        v2_result = None
        if brand_id is not None:
            v2_result = await _compute_v2_scores(db, current_user.id, brand_id)

        pdf_bytes = await export_citations_pdf(
            db, current_user.id, query_id, v2_result=v2_result
        )
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=str(e),
        )

    date_str = datetime.now().strftime("%Y%m%d")
    filename = f"geo-report-{date_str}.pdf"

    return Response(
        content=pdf_bytes,
        media_type="application/pdf",
        headers={
            "Content-Disposition": f'attachment; filename="{filename}"',
        },
    )
