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

from app.database.main.mysql import get_db
from app.dependency.authantication import JWTPayloadSchema, get_current_student
from app.api.module_5_report.service import Module5ReportService
from app.api.module_5_report.schema import Module5ReportPreview

module_5_report_router = APIRouter()


@module_5_report_router.get("/preview5/{group_id}", response_model=Module5ReportPreview)
async def get_module5_report_preview(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    """Preview Module 5 report data"""
    try:
        service = Module5ReportService(db, token)
        return await service.get_report_preview(group_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@module_5_report_router.get("/download5/{group_id}")
async def download_module5_report(
    group_id: int,
    db: Session = Depends(get_db),
    token: JWTPayloadSchema = Depends(get_current_student)
):
    """Download Module 5 report as PDF"""
    try:
        service = Module5ReportService(db, token)
        report = await service._fetch_module5_data(group_id)

        buffer = BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=A4,
                                leftMargin=50, rightMargin=50,
                                topMargin=50, bottomMargin=50)
        styles = getSampleStyleSheet()
        story = []

        # Title
        title_style = ParagraphStyle(
            'CustomTitle', parent=styles['Heading1'],
            fontSize=16, spaceAfter=20,
            alignment=1, fontName='Helvetica-Bold')
        
        # Section style
        section_style = ParagraphStyle(
            'SectionHeader', parent=styles['Heading2'],
            fontSize=12, spaceAfter=10,
            fontName='Helvetica-Bold')
        
        # Logo
        try:
            logo = Image("TS Logo.png", width=150, height=75)
            logo.hAlign = 'LEFT'
            story.append(logo)
            story.append(Spacer(1, 10))
        except:
            pass  # Continue without logo if file not found
        
        story.append(Paragraph("Module 5: Vendor Management ", title_style))
        story.append(Spacer(1, 12))

        # Create flexible paragraph style for table content
        flexible_style = ParagraphStyle(
            'FlexibleStyle', parent=styles['Normal'],
            fontSize=9, leading=11, wordWrap='CJK',
            alignment=1  # Center alignment
        )
        
        # Vendor Management Priority Matrix
        story.append(Paragraph("Vendor Management Priority Matrix", section_style))
        
        priority_data = [[
            Paragraph('Priority', flexible_style),
            Paragraph('Area', flexible_style),
            Paragraph('Metrics', flexible_style),
            Paragraph('Remarks', flexible_style)
        ]]
        for item in report.vendor_priority_matrix:
            priority_data.append([
                Paragraph(str(item.priority or 'N/A'), flexible_style),
                Paragraph(item.area or 'N/A', flexible_style),
                Paragraph(item.metrics or 'N/A', flexible_style),
                Paragraph(item.remarks or 'N/A', flexible_style)
            ])
        
        if len(priority_data) == 1:  # Only headers
            priority_data.append([
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style)
            ])
        
        priority_table = Table(priority_data, colWidths=[60, 120, 150, 150])
        priority_table.setStyle(TableStyle([
            ('GRID', (0, 0), (-1, -1), 1, 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'),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
            ('LEFTPADDING', (0, 0), (-1, -1), 6),
            ('RIGHTPADDING', (0, 0), (-1, -1), 6)
        ]))
        story.append(priority_table)
        story.append(Spacer(1, 15))

        # Vendor Management Scorecard
        story.append(Paragraph("Vendor Management Scorecard", section_style))
        
        # Header row with wrapped text
        header_style = ParagraphStyle(
            'HeaderStyle', parent=styles['Normal'],
            fontSize=9, fontName='Helvetica-Bold',
            alignment=1, leading=11, wordWrap='CJK'
        )
        
        scorecard_data = [[
            Paragraph('Metric', header_style),
            Paragraph('Weightage', header_style), 
            Paragraph('Importance', header_style),
            Paragraph('Best Alternative To A Negotiated Agreement (BATNA)', header_style)
        ]]
        
        # Scorecard metrics with instructions
        default_metrics = [
            ['Margin %', '', '', '(Percentage) [num]'],
            ['Credit Period', '', '', '(Days) [num]'],
            ['Expected Stock Holding', '', '', '(Days) [num]'],
            ['Promo Support', '', '', '(Percentage per Year) [num]'],
            ['New SKU Introduction Charges', '', '', '(Rupees per Store) [num]'],
            ['Display Income', '', '', '(___ unit in ___ stores)\n(Also define the units – text) [num, num, text]'],
            ['Frequency Of Supply', '', '', '(per Week) [num]'],
            ['Lead Time', '', '', '(Days) [num]']
        ]
        
        # Use database data if available, otherwise use default
        if report.vendor_scorecard:
            for item in report.vendor_scorecard:
                weightage_str = f"{item.weightage}%" if item.weightage else ''
                scorecard_data.append([
                    Paragraph(item.metric or 'N/A', flexible_style),
                    Paragraph(weightage_str or 'N/A', flexible_style),
                    Paragraph(item.importance or 'N/A', flexible_style),
                    Paragraph(item.batna or 'N/A', flexible_style)
                ])
        else:
            for metric_row in default_metrics:
                scorecard_data.append([
                    Paragraph(metric_row[0], flexible_style),
                    Paragraph(metric_row[1] or 'N/A', flexible_style),
                    Paragraph(metric_row[2] or 'N/A', flexible_style),
                    Paragraph(metric_row[3], flexible_style)
                ])
        
        scorecard_table = Table(scorecard_data, colWidths=[120, 80, 80, 200])
        scorecard_table.setStyle(TableStyle([
            ('GRID', (0, 0), (-1, -1), 1, 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'),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
            ('LEFTPADDING', (0, 0), (-1, -1), 6),
            ('RIGHTPADDING', (0, 0), (-1, -1), 6)
        ]))
        story.append(scorecard_table)
        story.append(Spacer(1, 15))

       

        # Private Labelling - Start on new page
        story.append(PageBreak())
        story.append(Paragraph("Private Labelling", section_style))
        
        private_data = [[
            Paragraph('Category Name', flexible_style),
            Paragraph('Private Label', flexible_style),
            Paragraph('Rationale', flexible_style)
        ]]
        for item in report.private_labelling:
            private_data.append([
                Paragraph(item.category_name or 'N/A', flexible_style),
                Paragraph(item.private_label or 'N/A', flexible_style),
                Paragraph(item.rational or 'N/A', flexible_style)
            ])
        
        if len(private_data) == 1:  # Only headers
            private_data.append([
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style)
            ])
        
        private_table = Table(private_data, colWidths=[120, 80, 280])
        private_table.setStyle(TableStyle([
            ('GRID', (0, 0), (-1, -1), 1, 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'),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
            ('LEFTPADDING', (0, 0), (-1, -1), 6),
            ('RIGHTPADDING', (0, 0), (-1, -1), 6)
        ]))
        story.append(private_table)
        story.append(Spacer(1, 15))

        # Category Captainship
        story.append(Paragraph("Category Captainship", section_style))
        
        captainship_data = [[
            Paragraph('Category Name', flexible_style),
            Paragraph('Category Captainship', flexible_style),
            Paragraph('Rationale', flexible_style)
        ]]
        for item in report.category_captainship:
            captainship_data.append([
                Paragraph(item.category_name or 'N/A', flexible_style),
                Paragraph(item.category_captinship or 'N/A', flexible_style),
                Paragraph(item.rational or 'N/A', flexible_style)
            ])
        
        if len(captainship_data) == 1:  # Only headers
            captainship_data.append([
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style),
                Paragraph('N/A', flexible_style)
            ])
        
        captainship_table = Table(captainship_data, colWidths=[100, 140, 240])
        captainship_table.setStyle(TableStyle([
            ('GRID', (0, 0), (-1, -1), 1, 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'),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
            ('LEFTPADDING', (0, 0), (-1, -1), 6),
            ('RIGHTPADDING', (0, 0), (-1, -1), 6)
        ]))
        story.append(captainship_table)
        story.append(Spacer(1, 15))

        doc.build(story)
        buffer.seek(0)

        return StreamingResponse(
            BytesIO(buffer.read()),
            media_type="application/pdf",
            headers={"Content-Disposition": f"attachment; filename=module_5_report_group_{group_id}.pdf"}
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@module_5_report_router.get("/{group_id}/preview-report-pdf5")
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 = Module5ReportService(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)}")