from typing import Optional

from db.db import get_db
from db.models import FundTable, InvestorTable, ProjectTable
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import Response
from services.report_gen import ReportGenerator
from sqlalchemy.orm import Session, selectinload

router = APIRouter(tags=["Report Generation"])


@router.get("/report/investor/{investor_id}")
async def generate_investor_report(
    investor_id: int,
    project_id: Optional[int] = Query(
        None, description="Optional project ID for compatibility analysis"
    ),
    db: Session = Depends(get_db),
):
    """
    Generate a PDF report for an investor profile.

    Args:
        investor_id: The ID of the investor to generate a report for
        project_id: Optional project ID to include mandate match analysis

    Returns:
        PDF file as a downloadable response
    """
    # Fetch investor data with all relationships
    investor = (
        db.query(InvestorTable)
        .options(
            selectinload(InvestorTable.portfolio_companies),
            selectinload(InvestorTable.team_members),
            selectinload(InvestorTable.sectors),
            selectinload(InvestorTable.funds).selectinload(FundTable.investment_stages),
            selectinload(InvestorTable.funds).selectinload(FundTable.sectors),
        )
        .filter(InvestorTable.id == investor_id)
        .first()
    )

    if not investor:
        raise HTTPException(status_code=404, detail="Investor not found")

    # Prepare investor data dictionary
    investor_data = {
        "name": investor.name,
        "description": investor.description,
        "website": investor.website,
        "headquarters": investor.headquarters,
        "aum": investor.aum,
        "geographic_focus": investor.geographic_focus,
        "portfolio_highlights": investor.portfolio_highlights or [],
        "investment_thesis": investor.investment_thesis or [],
        "sectors": [sector.name for sector in investor.sectors],
        "team_members": [
            {
                "name": member.name,
                "role": member.role,
                "title": member.title,
                "email": member.email,
            }
            for member in investor.team_members
        ],
        "check_size_lower": None,
        "check_size_upper": None,
        "investment_stages": [],
    }

    # Get check sizes and stages from funds
    if investor.funds:
        # Use the first fund's data or aggregate
        fund = investor.funds[0]
        investor_data["check_size_lower"] = fund.check_size_lower
        investor_data["check_size_upper"] = fund.check_size_upper

        # Aggregate all investment stages from all funds
        stages = set()
        for fund in investor.funds:
            for stage in fund.investment_stages:
                stages.add(stage.name)
        investor_data["investment_stages"] = list(stages)

    # Fetch project data if project_id is provided
    project_data = None
    if project_id:
        project = (
            db.query(ProjectTable)
            .options(selectinload(ProjectTable.sector))
            .filter(ProjectTable.id == project_id)
            .first()
        )

        if not project:
            raise HTTPException(status_code=404, detail="Project not found")

        project_data = {
            "name": project.name,
            "description": project.description,
            "location": project.location,
            "valuation": project.valuation,
            "stage": project.stage.name if project.stage else None,
            "sectors": [sector.name for sector in project.sector],
        }

    # Generate PDF report
    report_generator = ReportGenerator()
    pdf_bytes = await report_generator.generate_investor_report(
        investor_data, project_data
    )

    # Return PDF as downloadable file
    filename = f"{investor.name.replace(' ', '_')}_Report.pdf"
    return Response(
        content=pdf_bytes,
        media_type="application/pdf",
        headers={"Content-Disposition": f'attachment; filename="{filename}"'},
    )
