from fastapi import APIRouter, Depends, Response, HTTPException
from sqlalchemy.orm import Session
from io import BytesIO
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle

from app.api.module_3.schema import Module3ReportPreview
from app.api.module_3.service import Module3ReportService
from app.database.main.mysql import get_db
from app.dependency.authantication import JWTPayloadSchema, get_current_student

module_3_report_router = APIRouter()


@module_3_report_router.get("/{group_id}/preview3", response_model=Module3ReportPreview)
async def preview_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    """Preview Module 3 Network Planning report data"""
    service = Module3ReportService(db, token)
    return await service._fetch_module3_data(group_id)


@module_3_report_router.get("/{group_id}/download3")
async def download_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    """Download Module 3 Network Planning report as PDF"""
    service = Module3ReportService(db, token)
    report = await service._fetch_module3_data(group_id)

    buffer = BytesIO()
    pdf = SimpleDocTemplate(buffer, pagesize=A4, leftMargin=40, rightMargin=40, topMargin=40, bottomMargin=40)
    elements = []
    styles = getSampleStyleSheet()
    title_style = styles['Heading2']
    section_style = styles['Heading4']
    normal = styles['Normal']

    # Module Title
    elements.append(Paragraph("Module 3: Network Planning", title_style))
    elements.append(Spacer(1, 20))

    # Location Selection Section
    elements.append(Paragraph("<i>Location Selection</i>", section_style))
    elements.append(Spacer(1, 12))
    
    if report.network_planning and any(n.location and n.location != "N/A" for n in report.network_planning):
        location_data = [["Location", "Area", "Population", "Rationale"]]
        for network in report.network_planning:
            if network.location and network.location != "N/A":
                rationale = f"Major metropolitan city with high retail potential" if "Mumbai" in network.location else f"Growing market with expansion opportunities"
                location_data.append([
                    network.location or "N/A",
                    f"{network.area or 0:.1f} sq km",
                    f"{network.total_hh or 0:,}",
                    rationale
                ])
        
        location_table = Table(location_data, colWidths=[100, 80, 100, 200])
        location_table.setStyle(TableStyle([
            ("GRID", (0, 0), (-1, -1), 1, colors.black),
            ("FONTNAME", (0, 0), (-1, -1), "Helvetica"),
            ("FONTSIZE", (0, 0), (-1, -1), 9),
            ("ALIGN", (0, 0), (-1, -1), "LEFT"),
            ("VALIGN", (0, 0), (-1, -1), "TOP"),
            ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ]))
        elements.append(location_table)
    else:
        elements.append(Paragraph("No location data available", normal))
    elements.append(Spacer(1, 24))

    # Store Investment Summary Section
    elements.append(Paragraph("<i>Store Investment Summary</i>", section_style))
    elements.append(Spacer(1, 12))
    
    investment_data = [
        ["Investment Component", "Format A", "Format B", "Source"],
        ["Capital Expenses (Excl. IT)", f"₹{report.store_investment_summary.capital_expenses_a or 0:,}", f"₹{report.store_investment_summary.capital_expenses_b or 0:,}", "Module 1"],
        ["IT Capital Expenses", f"₹{report.store_investment_summary.it_capital_expenses_a or 0:,}", f"₹{report.store_investment_summary.it_capital_expenses_b or 0:,}", "Module 1"],
        ["Rental Advance", f"₹{report.store_investment_summary.rental_advance_a or 0:,}", f"₹{report.store_investment_summary.rental_advance_b or 0:,}", "Module 2"],
        ["Pre-operating Expenses", f"₹{report.store_investment_summary.calculated_pre_operating_expenses_a:,}", f"₹{report.store_investment_summary.calculated_pre_operating_expenses_b:,}", "Module 3"],
        ["Total Store Investments", f"₹{report.store_investment_summary.calculated_total_store_investment_a:,}", f"₹{report.store_investment_summary.calculated_total_store_investment_b:,}", "Total"]
    ]
    
    investment_table = Table(investment_data, colWidths=[140, 100, 100, 80])
    investment_table.setStyle(TableStyle([
        ("GRID", (0, 0), (-1, -1), 1, colors.black),
        ("FONTNAME", (0, 0), (-1, -1), "Helvetica"),
        ("FONTSIZE", (0, 0), (-1, -1), 9),
        ("ALIGN", (0, 0), (-1, -1), "LEFT"),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("BACKGROUND", (0, -1), (-1, -1), colors.lightgrey),
        ("FONTNAME", (0, -1), (-1, -1), "Helvetica-Bold"),
    ]))
    elements.append(investment_table)
    elements.append(Spacer(1, 24))

    pdf.build(elements)
    buffer.seek(0)
    filename = f"module3_network_planning_{group_id}.pdf"

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


@module_3_report_router.get("/{group_id}/preview-report-pdf3")
async def generate_and_serve_pdf(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    """Generate PDF report and return file path information"""
    try:
        service = Module3ReportService(db, token)
        file_path = await service.generate_and_save_pdf(group_id)
        
        return {
            "group_id": group_id,
            "file_path": file_path,
        }
            
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error generating PDF: {str(e)}")