"""Reports and analytics endpoints."""
from typing import List, Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_
from app.core.database import get_db
from app.models.issue import Issue, IssueStatus
from app.models.organization import OrganizationMember
from app.api.deps import require_role
from pydantic import BaseModel

router = APIRouter()

class DailyStats(BaseModel):
    date: str
    total: int
    analyzed: int
    prs_created: int
    avg_confidence: float

class ReportSummary(BaseModel):
    period_start: datetime
    period_end: datetime
    total_issues: int
    analyzed_issues: int
    prs_created: int
    avg_confidence: float
    avg_analysis_time_hours: Optional[float]
    top_sources: List[dict]
    daily_breakdown: List[DailyStats]

@router.get("/summary", response_model=ReportSummary)
async def get_report_summary(
    org_id: int,
    days: int = 30,
    member: OrganizationMember = Depends(require_role("viewer")),
    db: AsyncSession = Depends(get_db)
):
    """Get summary report for organization."""
    end_date = datetime.utcnow()
    start_date = end_date - timedelta(days=days)
    
    # Total issues
    total_result = await db.execute(
        select(func.count(Issue.id))
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
    )
    total = total_result.scalar() or 0
    
    # Analyzed
    analyzed_result = await db.execute(
        select(func.count(Issue.id))
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
        .where(Issue.status.in_([IssueStatus.ANALYZED, IssueStatus.PR_CREATED, IssueStatus.COMPLETED]))
    )
    analyzed = analyzed_result.scalar() or 0
    
    # PRs created
    prs_result = await db.execute(
        select(func.count(Issue.id))
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
        .where(Issue.pr_url.isnot(None))
    )
    prs = prs_result.scalar() or 0
    
    # Avg confidence
    avg_conf_result = await db.execute(
        select(func.avg(Issue.confidence))
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
        .where(Issue.confidence.isnot(None))
    )
    avg_confidence = avg_conf_result.scalar() or 0
    
    # Top sources
    sources_result = await db.execute(
        select(Issue.source, func.count(Issue.id).label("count"))
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
        .group_by(Issue.source)
        .order_by(func.count(Issue.id).desc())
        .limit(5)
    )
    top_sources = [{"source": r[0] or "unknown", "count": r[1]} for r in sources_result.all()]
    
    # Daily breakdown (simplified)
    daily_breakdown = []
    for i in range(min(days, 30)):
        day_start = start_date + timedelta(days=i)
        day_end = day_start + timedelta(days=1)
        
        day_total = await db.execute(
            select(func.count(Issue.id))
            .where(Issue.organization_id == org_id)
            .where(Issue.created_at >= day_start)
            .where(Issue.created_at < day_end)
        )
        day_analyzed = await db.execute(
            select(func.count(Issue.id))
            .where(Issue.organization_id == org_id)
            .where(Issue.created_at >= day_start)
            .where(Issue.created_at < day_end)
            .where(Issue.status.in_([IssueStatus.ANALYZED, IssueStatus.PR_CREATED, IssueStatus.COMPLETED]))
        )
        day_prs = await db.execute(
            select(func.count(Issue.id))
            .where(Issue.organization_id == org_id)
            .where(Issue.created_at >= day_start)
            .where(Issue.created_at < day_end)
            .where(Issue.pr_url.isnot(None))
        )
        day_conf = await db.execute(
            select(func.avg(Issue.confidence))
            .where(Issue.organization_id == org_id)
            .where(Issue.created_at >= day_start)
            .where(Issue.created_at < day_end)
            .where(Issue.confidence.isnot(None))
        )
        
        daily_breakdown.append(DailyStats(
            date=day_start.strftime("%Y-%m-%d"),
            total=day_total.scalar() or 0,
            analyzed=day_analyzed.scalar() or 0,
            prs_created=day_prs.scalar() or 0,
            avg_confidence=day_conf.scalar() or 0
        ))
    
    return ReportSummary(
        period_start=start_date,
        period_end=end_date,
        total_issues=total,
        analyzed_issues=analyzed,
        prs_created=prs,
        avg_confidence=avg_confidence,
        avg_analysis_time_hours=None,  # TODO: calculate
        top_sources=top_sources,
        daily_breakdown=daily_breakdown
    )

@router.get("/export/csv")
async def export_csv(
    org_id: int,
    days: int = 30,
    member: OrganizationMember = Depends(require_role("manager")),
    db: AsyncSession = Depends(get_db)
):
    """Export issues as CSV."""
    from fastapi.responses import StreamingResponse
    import io
    import csv
    
    start_date = datetime.utcnow() - timedelta(days=days)
    
    result = await db.execute(
        select(Issue)
        .where(Issue.organization_id == org_id)
        .where(Issue.created_at >= start_date)
        .order_by(Issue.created_at.desc())
    )
    issues = result.scalars().all()
    
    output = io.StringIO()
    writer = csv.writer(output)
    writer.writerow([
        "ID", "Key", "Title", "Source", "Status", "Priority",
        "Confidence", "PR URL", "Created At", "Analyzed At"
    ])
    
    for issue in issues:
        writer.writerow([
            issue.id,
            issue.external_key,
            issue.title,
            issue.source,
            issue.status.value if issue.status else "",
            issue.priority.value if issue.priority else "",
            f"{issue.confidence:.0%}" if issue.confidence else "",
            issue.pr_url or "",
            issue.created_at.isoformat() if issue.created_at else "",
            issue.analysis_completed_at.isoformat() if issue.analysis_completed_at else ""
        ])
    
    output.seek(0)
    return StreamingResponse(
        iter([output.getvalue()]),
        media_type="text/csv",
        headers={"Content-Disposition": f"attachment; filename=issues-{datetime.utcnow().strftime('%Y%m%d')}.csv"}
    )
