from fastapi import APIRouter, Depends, Response
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 reportlab.lib.units import inch

from app.api.module_8_report.schema import Module8ReportPreview
from app.api.module_8_report.service import Module8ReportService
from app.database.main.mysql import get_db
from app.dependency.authantication import JWTPayloadSchema, get_current_student

module_8_report_router = APIRouter()


@module_8_report_router.get("/{group_id}/preview8", response_model=Module8ReportPreview)
async def preview_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    service = Module8ReportService(db, token)
    return await service._fetch_module8_data(group_id)


@module_8_report_router.get("/{group_id}/preview-report-pdf8")
async def preview_report_pdf(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    service = Module8ReportService(db, token)
    file_path = await service.generate_and_save_pdf(group_id)
    return {"group_id": group_id, "file_path": file_path}


@module_8_report_router.get("/{group_id}/download8")
async def download_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    service = Module8ReportService(db, token)
    report = await service._fetch_module8_data(group_id)

    buffer = BytesIO()
    pdf = SimpleDocTemplate(buffer, pagesize=A4, topMargin=0.5*inch, bottomMargin=0.5*inch)
    elements = []
    styles = getSampleStyleSheet()

    # Title
    elements.append(Paragraph("<b>Module 8: Services & Utilities</b>", styles["Title"]))
    elements.append(Spacer(1, 12))

    # Corporate & Concept Office Section
    elements.append(Paragraph("<b>Corporate & Concept Office</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    # Corporate Office Table
    elements.append(Paragraph("<b><i>Corporate Office</i></b>", styles["Heading3"]))
    header_style = ParagraphStyle("header_style", fontSize=9, fontName='Helvetica-Bold', alignment=1)
    corp_data = [["Role Category", Paragraph("Cost to<br/>Company (Y1)<br/>per Head", header_style), "Y1", "Y2", "Y3", "Y4", "Y5"]]
    for corp in report.corporate_concept_office:
        corp_data.append([
            corp.role_category or "N/A",
            f"Rs. {corp.cost_to_company:,.0f}" if corp.cost_to_company else "Rs. 0",
            str(corp.y1) if corp.y1 else "0",
            str(corp.y2) if corp.y2 else "0", 
            str(corp.y3) if corp.y3 else "0",
            str(corp.y4) if corp.y4 else "0",
            str(corp.y5) if corp.y5 else "0"
        ])

    corp_table = Table(corp_data, colWidths=[1.5*inch, 1.5*inch, 0.6*inch, 0.6*inch, 0.6*inch, 0.6*inch, 0.6*inch])
    corp_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ]))
    elements.append(corp_table)
    elements.append(Spacer(1, 12))

    # Concept Office Table
    elements.append(Paragraph("<b><i>Concept Office</i></b>", styles["Heading3"]))
    concept_data = [["Role Category", Paragraph("Cost to<br/>Company (Y1)<br/>per Head", header_style), "Y1", "Y2", "Y3", "Y4", "Y5"]]
    for concept in report.concept_office:
        concept_data.append([
            concept.role_category or "N/A",
            f"Rs. {concept.cost_to_company:,.0f}" if concept.cost_to_company else "Rs. 0",
            str(concept.y1) if concept.y1 else "0",
            str(concept.y2) if concept.y2 else "0",
            str(concept.y3) if concept.y3 else "0", 
            str(concept.y4) if concept.y4 else "0",
            str(concept.y5) if concept.y5 else "0"
        ])

    concept_table = Table(concept_data, colWidths=[1.5*inch, 1.5*inch, 0.6*inch, 0.6*inch, 0.6*inch, 0.6*inch, 0.6*inch])
    concept_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ]))
    elements.append(concept_table)
    elements.append(Spacer(1, 20))

    # Store Level Services Section
    elements.append(Paragraph("<b>Store Level Services</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    store_data = [["Designation", "Average Salary", "Format A\nCount", "Format B\nCount"]]
    for store in report.store_level_staff_needs:
        store_data.append([
            store.designation or "N/A",
            f"Rs. {store.average_salary:,.0f}" if store.average_salary else "Rs. 0",
            str(store.format_a_count) if store.format_a_count else "0",
            str(store.format_b_count) if store.format_b_count else "0"
        ])

    store_table = Table(store_data, colWidths=[2*inch, 1.5*inch, 1.2*inch, 1.2*inch])
    store_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
    ]))
    elements.append(store_table)
    elements.append(Spacer(1, 20))

    # Training & Talent Management Section
    elements.append(Paragraph("<b>Training & Talent Management</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    cell_style = ParagraphStyle("cell_style", fontSize=9, leading=11, wordWrap="CJK")
    training_data = [
        [Paragraph("Name of Reference Retailer", cell_style), 
         Paragraph(report.training_talent_management.name_of_reference_retailer or "N/A", cell_style)],
        [Paragraph("Provide a brief about chosen Human and Employee Management Activity", cell_style), 
         Paragraph(report.training_talent_management.employee_management_activity or "N/A", cell_style)],
        [Paragraph("How are your policies/plan/activities different from those of this retailer?", cell_style), 
         Paragraph(report.training_talent_management.policeis_plan_activities or "N/A", cell_style)]
    ]

    training_table = Table(training_data)
    training_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
        ('FONTNAME', (1, 0), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(training_table)
    elements.append(Spacer(1, 20))

    # Utilities Section
    elements.append(Paragraph("<b>Utilities</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    # Store Format A Utilities
    elements.append(Paragraph("<b>Store Format A Utilities</b>", styles["Heading3"]))
    util_a_data = [[Paragraph("Utility Type", cell_style), Paragraph("Cost per Month", cell_style), 
                    Paragraph("Key Usage Parameters", cell_style), Paragraph("Remarks", cell_style)]]
    total_cost_a = 0
    for util in report.utilities:
        if util.store_format_type == "Store Formate A":
            util_a_data.append([
                Paragraph(util.utility_name or "N/A", cell_style),
                Paragraph(f"Rs. {util.cost_per_month:,.0f}" if util.cost_per_month else "Rs. 0", cell_style),
                Paragraph(util.key_usage_parameters or "N/A", cell_style),
                Paragraph(util.remark or "N/A", cell_style)
            ])
            total_cost_a += util.cost_per_month or 0

    util_a_table = Table(util_a_data)
    util_a_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(util_a_table)
    
    # Total Cost for Format A
    total_a_data = [[Paragraph("<b>Total Cost</b>", cell_style), Paragraph(f"<b>Rs. {total_cost_a:,.0f}</b>", cell_style), 
                     Paragraph("", cell_style), Paragraph("", cell_style)]]
    total_a_table = Table(total_a_data)
    total_a_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(total_a_table)
    elements.append(Spacer(1, 12))

    # Store Format B Utilities
    elements.append(Paragraph("<b>Store Format B Utilities</b>", styles["Heading3"]))
    util_b_data = [[Paragraph("Utility Type", cell_style), Paragraph("Cost per Month", cell_style), 
                    Paragraph("Key Usage Parameters", cell_style), Paragraph("Remarks", cell_style)]]
    total_cost_b = 0
    for util in report.utilities:
        if util.store_format_type == "Store Formate B":
            util_b_data.append([
                Paragraph(util.utility_name or "N/A", cell_style),
                Paragraph(f"Rs. {util.cost_per_month:,.0f}" if util.cost_per_month else "Rs. 0", cell_style),
                Paragraph(util.key_usage_parameters or "N/A", cell_style),
                Paragraph(util.remark or "N/A", cell_style)
            ])
            total_cost_b += util.cost_per_month or 0

    util_b_table = Table(util_b_data)
    util_b_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(util_b_table)
    
    # Total Cost for Format B
    total_b_data = [[Paragraph("<b>Total Cost</b>", cell_style), Paragraph(f"<b>Rs. {total_cost_b:,.0f}</b>", cell_style), 
                     Paragraph("", cell_style), Paragraph("", cell_style)]]
    total_b_table = Table(total_b_data)
    total_b_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, -1), 'Helvetica-Bold'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(total_b_table)
    elements.append(Spacer(1, 20))

    # Other Operating Expenses Section
    elements.append(Paragraph("<b>Other Operating Expenses</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    # Store Format A Operating Expenses
    elements.append(Paragraph("<b>Store Format A Operating Expenses</b>", styles["Heading3"]))
    op_a_data = [[Paragraph("Expense Type", cell_style), Paragraph("Percentage of Sales per Year", cell_style), 
                  Paragraph("Remarks", cell_style)]]
    for op in report.operating_expenses:
        if op.store_format_type == "Store Format A":
            op_a_data.append([
                Paragraph(op.operating_expenses_type or "N/A", cell_style),
                Paragraph(f"{op.percentage_of_sales_per_year}%" if op.percentage_of_sales_per_year else "0%", cell_style),
                Paragraph(op.remark or "N/A", cell_style)
            ])

    op_a_table = Table(op_a_data)
    op_a_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(op_a_table)
    elements.append(Spacer(1, 12))

    # Store Format B Operating Expenses
    elements.append(Paragraph("<b>Store Format B Operating Expenses</b>", styles["Heading3"]))
    op_b_data = [[Paragraph("Expense Type", cell_style), Paragraph("Percentage of Sales per Year", cell_style), 
                  Paragraph("Remarks", cell_style)]]
    for op in report.operating_expenses:
        if op.store_format_type == "Store Format B":
            op_b_data.append([
                Paragraph(op.operating_expenses_type or "N/A", cell_style),
                Paragraph(f"{op.percentage_of_sales_per_year}%" if op.percentage_of_sales_per_year else "0%", cell_style),
                Paragraph(op.remark or "N/A", cell_style)
            ])

    op_b_table = Table(op_b_data)
    op_b_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
        ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(op_b_table)
    elements.append(Spacer(1, 20))

    # Summary Section
    elements.append(Paragraph("<b>Summary</b>", styles["Heading2"]))
    elements.append(Spacer(1, 8))

    summary_data = [
        [Paragraph("Service Submissions", cell_style), Paragraph(report.summary.service_submissions or "N/A", cell_style)],
        [Paragraph("Service Summarise", cell_style), Paragraph(report.summary.service_summarise or "N/A", cell_style)]
    ]

    summary_table = Table(summary_data)
    summary_table.setStyle(TableStyle([
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
        ('FONTNAME', (1, 0), (-1, -1), 'Helvetica'),
        ('FONTSIZE', (0, 0), (-1, -1), 9),
        ('ALIGN', (0, 0), (0, -1), 'LEFT'),
        ('ALIGN', (1, 0), (-1, -1), 'LEFT'),
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))
    elements.append(summary_table)

    # Build PDF
    pdf.build(elements)
    buffer.seek(0)
    filename = f"module8_report_{group_id}.pdf"

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