from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import StreamingResponse, JSONResponse
from sqlalchemy.orm import Session
from typing import Optional
import json
from datetime import datetime

from app.database.main.mysql import get_db
from app.dependency.authantication import JWTPayloadSchema, get_current_user
from app.locale.messages import Messages

from .service import PDFReportService
from .schemas import ComprehensiveReportRequest, PDFReportResponse

pdf_reports_router = APIRouter()

# Comprehensive Group Report
@pdf_reports_router.get("/group/{group_id}/comprehensive")
async def generate_group_comprehensive_report(
    group_id: int, 
    include_charts: bool = Query(True, description="Include charts and graphs"),
    include_analysis: bool = Query(True, description="Include detailed analysis"),
    db: Session = Depends(get_db), 
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Generate comprehensive PDF report for a specific group with KPIs and performance metrics"""
    try:
        service = PDFReportService(db)
        
        request = ComprehensiveReportRequest(
            group_id=group_id,
            report_type="comprehensive",
            include_charts=include_charts,
            include_detailed_analysis=include_analysis
        )
        
        pdf_buffer = service.generate_comprehensive_report(request)
        response_data = service.create_report_response(pdf_buffer, "group_comprehensive")
        
        return StreamingResponse(
            iter([pdf_buffer.getvalue()]), 
            media_type="application/pdf",
            headers={
                "Content-Disposition": f"attachment; filename={response_data.file_name}",
                "Content-Length": str(response_data.file_size)
            }
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating report: {str(e)}")

# Financial Performance Report
@pdf_reports_router.get("/group/{group_id}/financial")
async def generate_group_financial_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Generate financial performance report with KPIs for a specific group"""
    try:
        service = PDFReportService(db)
        
        request = ComprehensiveReportRequest(
            group_id=group_id,
            report_type="financial",
            include_charts=True,
            include_detailed_analysis=True
        )
        
        pdf_buffer = service.generate_comprehensive_report(request)
        response_data = service.create_report_response(pdf_buffer, "group_financial")
        
        return StreamingResponse(
            iter([pdf_buffer.getvalue()]), 
            media_type="application/pdf",
            headers={
                "Content-Disposition": f"attachment; filename={response_data.file_name}"
            }
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating financial report: {str(e)}")

# Simulation-wide Report
@pdf_reports_router.get("/simulation/{simulation_id}/comprehensive")
async def generate_simulation_comprehensive_report(
    simulation_id: int,
    include_leaderboard: bool = Query(True, description="Include group performance leaderboard"),
    include_statistics: bool = Query(True, description="Include simulation statistics"),
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Generate comprehensive simulation report with all groups performance comparison"""
    try:
        service = PDFReportService(db)
        
        request = ComprehensiveReportRequest(
            simulation_id=simulation_id,
            report_type="simulation_comprehensive",
            include_charts=include_leaderboard,
            include_detailed_analysis=include_statistics
        )
        
        pdf_buffer = service.generate_comprehensive_report(request)
        response_data = service.create_report_response(pdf_buffer, "simulation_comprehensive")
        
        return StreamingResponse(
            iter([pdf_buffer.getvalue()]), 
            media_type="application/pdf",
            headers={
                "Content-Disposition": f"attachment; filename={response_data.file_name}"
            }
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating simulation report: {str(e)}")

# Student Individual Report
@pdf_reports_router.get("/student/{student_id}/performance")
async def generate_student_performance_report(
    student_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Generate individual student performance report"""
    try:
        service = PDFReportService(db)
        pdf_buffer = service.generate_student_report(student_id)
        
        response_data = service.create_report_response(pdf_buffer, "student_performance")
        
        return StreamingResponse(
            iter([pdf_buffer.getvalue()]), 
            media_type="application/pdf",
            headers={
                "Content-Disposition": f"attachment; filename={response_data.file_name}"
            }
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating student report: {str(e)}")

# Group Performance Summary (JSON)
@pdf_reports_router.get("/group/{group_id}/summary")
async def get_group_performance_summary(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Get group performance summary as JSON for dashboard display"""
    try:
        service = PDFReportService(db)
        
        financial_metrics = service.calculate_financial_metrics(group_id)
        operational_metrics = service.calculate_operational_metrics(group_id)
        
        summary = {
            "group_id": group_id,
            "financial_performance": {
                "revenue": financial_metrics.revenue,
                "gross_profit": financial_metrics.gross_profit,
                "net_profit": financial_metrics.net_profit,
                "gross_margin_percentage": financial_metrics.gross_margin_percentage,
                "net_margin_percentage": financial_metrics.net_margin_percentage,
                "roi": financial_metrics.roi,
                "total_investment": financial_metrics.total_investment
            },
            "operational_performance": {
                "total_stores": operational_metrics.total_stores,
                "sales_per_sqft": operational_metrics.sales_per_sqft,
                "inventory_turnover": operational_metrics.inventory_turnover,
                "customer_footfall": operational_metrics.customer_footfall,
                "average_transaction_value": operational_metrics.average_transaction_value,
                "conversion_rate": operational_metrics.conversion_rate
            },
            "overall_score": service._calculate_overall_score(financial_metrics, operational_metrics),
            "generated_at": datetime.now().isoformat()
        }
        
        return JSONResponse(content=summary)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error getting performance summary: {str(e)}")

# Simulation Leaderboard (JSON)
@pdf_reports_router.get("/simulation/{simulation_id}/leaderboard")
async def get_simulation_leaderboard(
    simulation_id: int,
    limit: int = Query(10, description="Number of top groups to return"),
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Get simulation leaderboard as JSON"""
    try:
        from app.models.main.group import TblGroup
        
        service = PDFReportService(db)
        
        # Get simulation first to get simulation_code
        from app.models.main.simulation import TblSimulation
        simulation = db.query(TblSimulation).filter(TblSimulation.simulation_id == simulation_id).first()
        if not simulation:
            raise HTTPException(status_code=404, detail="Simulation not found")
        
        # Get all groups in simulation using simulation_code
        groups = db.query(TblGroup).filter(TblGroup.simulation_code == simulation.simulation_code).all()
        
        leaderboard = []
        for group in groups:
            financial_metrics = service.calculate_financial_metrics(group.group_id)
            operational_metrics = service.calculate_operational_metrics(group.group_id)
            overall_score = service._calculate_overall_score(financial_metrics, operational_metrics)
            
            leaderboard.append({
                "group_id": group.group_id,
                "group_name": group.group_name or f"Group {group.group_id}",
                "participants": group.number_of_members or 0,
                "overall_score": round(overall_score, 2),
                "roi": round(financial_metrics.roi, 2),
                "revenue": financial_metrics.revenue,
                "net_profit": financial_metrics.net_profit,
                "category": group.category
            })
        
        # Sort by overall score
        leaderboard.sort(key=lambda x: x['overall_score'], reverse=True)
        
        # Add ranking
        for i, entry in enumerate(leaderboard[:limit], 1):
            entry['rank'] = i
        
        return JSONResponse(content={
            "simulation_id": simulation_id,
            "total_groups": len(groups),
            "leaderboard": leaderboard[:limit],
            "generated_at": datetime.now().isoformat()
        })
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error getting leaderboard: {str(e)}")

# KPI Dashboard Data
@pdf_reports_router.get("/group/{group_id}/kpis")
async def get_group_kpis(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_user)
):
    """Get key performance indicators for dashboard display"""
    try:
        service = PDFReportService(db)
        
        financial_metrics = service.calculate_financial_metrics(group_id)
        operational_metrics = service.calculate_operational_metrics(group_id)
        
        kpis = [
            {
                "name": "Revenue",
                "value": financial_metrics.revenue,
                "unit": "Rs",
                "target": 5000000,
                "status": service._get_kpi_status(financial_metrics.revenue, 5000000),
                "category": "financial"
            },
            {
                "name": "ROI",
                "value": financial_metrics.roi,
                "unit": "%",
                "target": 20,
                "status": service._get_kpi_status(financial_metrics.roi, 20),
                "category": "financial"
            },
            {
                "name": "Gross Margin",
                "value": financial_metrics.gross_margin_percentage,
                "unit": "%",
                "target": 25,
                "status": service._get_kpi_status(financial_metrics.gross_margin_percentage, 25),
                "category": "financial"
            },
            {
                "name": "Sales per Sq.Ft",
                "value": operational_metrics.sales_per_sqft,
                "unit": "Rs",
                "target": 2500,
                "status": service._get_kpi_status(operational_metrics.sales_per_sqft, 2500),
                "category": "operational"
            },
            {
                "name": "Conversion Rate",
                "value": operational_metrics.conversion_rate,
                "unit": "%",
                "target": 15,
                "status": service._get_kpi_status(operational_metrics.conversion_rate, 15),
                "category": "operational"
            },
            {
                "name": "Inventory Turnover",
                "value": operational_metrics.inventory_turnover,
                "unit": "x",
                "target": 12,
                "status": service._get_kpi_status(operational_metrics.inventory_turnover, 12),
                "category": "operational"
            }
        ]
        
        return JSONResponse(content={
            "group_id": group_id,
            "kpis": kpis,
            "overall_score": service._calculate_overall_score(financial_metrics, operational_metrics),
            "generated_at": datetime.now().isoformat()
        })
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error getting KPIs: {str(e)}")

# Health Check
@pdf_reports_router.get("/health")
async def health_check():
    """Health check endpoint for PDF reports service"""
    return {
        "status": "healthy",
        "service": "pdf_reports",
        "timestamp": datetime.now().isoformat(),
        "version": "1.0.0"
    }