import { Request, Response } from 'express';
import { CpcHistoryService } from '../services/cpc-cdc/CpcHistoryService';
import { CpcDocument } from '../models/CpcDocument';
import { appendCpcDocumentFilters, cpcWhereFromAndParts } from '../services/cpc-cdc/utils';
import ExcelJS from 'exceljs';
import { ResponseHandler } from '../utils/responseHandler';

import { Op } from 'sequelize';

export class CpcReportController {
    /**
     * Download Excel report for a specific claim
     */
    async downloadReport(req: Request, res: Response) {
        try {
            const { claimId } = req.params;
            const { attempt } = req.query;

            const where: any = {
                [Op.or]: [
                    { claimId: claimId },
                    { bookingId: claimId }
                ]
            };
            if (attempt) where.attemptNo = parseInt(attempt as string);

            const docs = await CpcDocument.findAll({
                where,
                order: [['createdAt', 'DESC']]
            });

            if (!docs || docs.length === 0) {
                return ResponseHandler.error(res, "No records found for this claim", 404);
            }

            const workbook = new ExcelJS.Workbook();
            const sheet = workbook.addWorksheet('Validation Report');

            // HEADERS
            const row1 = sheet.getRow(1);
            row1.values = [
                'Booking Type', 'Booking Number', 'Document Count', 'Document Name',
                'Customer Name', '', '', '', '',
                'PO Number /Authorisation Letter Number', '', '', '', '',
                'Aadhar Number', '', '', '', '',
                'PO Amount / Authorisation Letter Amount', '', '', '', '',
                'Signature & Stamp Availability', '', '', '', '',
                'Final Validation'
            ];

            const row2 = sheet.getRow(2);
            row2.values = [
                '', '', '', '',
                'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 
                'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 
                'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 
                'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 
                'Expected', 'OCR', 'Accuracy Matching Availability', 'Accuracy Criteria', 'Success Ratio', 
                ''
            ];

            sheet.mergeCells('E1:I1');
            sheet.mergeCells('J1:N1');
            sheet.mergeCells('O1:S1');
            sheet.mergeCells('T1:X1');
            sheet.mergeCells('Y1:AC1');
            sheet.mergeCells('A1:A2'); sheet.mergeCells('B1:B2'); sheet.mergeCells('C1:C2'); sheet.mergeCells('D1:D2');
            sheet.mergeCells('AD1:AD2');

            [row1, row2].forEach((r: any) => {
                r.font = { bold: true, size: 9 };
                r.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true };
                r.eachCell((cell: any) => {
                    cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFD9D9D9' } };
                    cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };
                });
            });

            docs.forEach((doc: any, idx: number) => {

                const rowData = CpcHistoryService.getSummaryRow(doc, idx);
                const values = [
                    rowData.booking_type,
                    rowData.booking_number,
                    rowData.document_count,
                    rowData.document_name,
                    rowData.customer_name_group.msd, rowData.customer_name_group.ocr, rowData.customer_name_group.accuracy_pct, rowData.customer_name_group.criteria, rowData.customer_name_group.is_match,
                    rowData.po_or_auth_number_group.msd, rowData.po_or_auth_number_group.ocr, rowData.po_or_auth_number_group.accuracy_pct, rowData.po_or_auth_number_group.criteria, rowData.po_or_auth_number_group.is_match,
                    rowData.aadhaar_number_group.msd, rowData.aadhaar_number_group.ocr, rowData.aadhaar_number_group.accuracy_pct, rowData.aadhaar_number_group.criteria, rowData.aadhaar_number_group.is_match,
                    rowData.amount_group.msd, rowData.amount_group.ocr, rowData.amount_group.accuracy_pct, rowData.amount_group.criteria, rowData.amount_group.is_match,
                    rowData.stamp_group.msd, rowData.stamp_group.ocr, rowData.stamp_group.accuracy_pct, rowData.stamp_group.criteria, rowData.stamp_group.is_match,
                    rowData.final_validation
                ];
                const row = sheet.addRow(values);
                row.eachCell((cell: any, colNum: number) => {
                    cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };
                    cell.font = { size: 8 };
                    cell.alignment = { vertical: 'middle', horizontal: 'center' };

                    if (cell.value === 'N.A.' && colNum > 4) {
                        cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFF0000' } };
                        cell.font = { color: { argb: 'FFFFFFFF' }, size: 8, bold: true };
                    }
                });
            });

            sheet.addRow([]);
            sheet.addRow([]);
            const detailHeader = sheet.addRow(['Detailed Field-Wise Comparison']);
            detailHeader.font = { bold: true, size: 12 };

            docs.forEach((doc: any) => {
                const docHeader = sheet.addRow([`Document: ${doc.documentType?.replace(/_/g, ' ')}`]);
                docHeader.font = { bold: true, size: 10 };

                
                const subHeader = sheet.addRow(['Field', 'Expected', 'Extracted (OCR)', 'Accuracy %', 'Criteria', 'Status', 'Message']);
                const finalResults = CpcHistoryService.getDetailedFieldResults(doc);
                
                finalResults.forEach((f: any) => {
                    sheet.addRow([
                        f.field.replace(/_/g, ' '),
                        f.expected || '-',
                        f.extracted || 'Not extracted',
                        f.accuracy,
                        f.criteria,
                        f.pass ? 'PASS' : 'FAIL',
                        f.message
                    ]);
                });

                sheet.addRow([]);
            });

            res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            res.setHeader('Content-Disposition', `attachment; filename=Report_${claimId}.xlsx`);
            await workbook.xlsx.write(res);
            res.end();
        } catch (error: any) {
            return ResponseHandler.error(res, error.message || "Report generation failed", 500);
        }
    }

    /**
     * Download Master Audit Report for all filtered documents
     */
    async downloadAllReport(req: Request, res: Response) {
        try {
            const { search, status, type } = req.query;
            const andParts: Record<string, unknown>[] = [];
            appendCpcDocumentFilters(andParts, {
                type: type as string,
                status: status as string,
                search: search as string,
                searchIncludeId: false
            });
            const where = cpcWhereFromAndParts(andParts);

            const docs = await CpcDocument.findAll({
                where,
                order: [['createdAt', 'DESC']]
            });

            const workbook = new ExcelJS.Workbook();
            const sheet = workbook.addWorksheet('Master Audit Trail');

            const row1 = sheet.getRow(1);
            row1.values = ['Booking Type', 'Booking Number', 'Doc ID', 'Document Name', 'Customer Name', '', '', '', '', 'PO Number /Authorisation Letter Number', '', '', '', '', 'Aadhar Number', '', '', '', '', 'PO Amount / Authorisation Letter Amount', '', '', '', '', 'Signature & Stamp Availability', '', '', '', '', 'Final Validation'];
            
            const row2 = sheet.getRow(2);
            row2.values = ['', '', '', '', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching Availability', 'Accuracy Criteria', 'Success Ratio', ''];

            sheet.mergeCells('E1:I1'); sheet.mergeCells('J1:N1'); sheet.mergeCells('O1:S1'); sheet.mergeCells('T1:X1'); sheet.mergeCells('Y1:AC1'); sheet.mergeCells('A1:A2'); sheet.mergeCells('B1:B2'); sheet.mergeCells('C1:C2'); sheet.mergeCells('D1:D2'); sheet.mergeCells('AD1:AD2');

            [row1, row2].forEach((r: any) => {
                r.font = { bold: true, size: 9 };
                r.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true };
                r.eachCell((cell: any) => { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFD9D9D9' } }; cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; });
            });

            docs.forEach((doc: any, idx: number) => {

                const rowData = CpcHistoryService.getSummaryRow(doc, idx);
                const values = [
                    rowData.booking_type, rowData.booking_number, String(doc.id).slice(0, 8), rowData.document_name,
                    rowData.customer_name_group.msd, rowData.customer_name_group.ocr, rowData.customer_name_group.accuracy_pct, rowData.customer_name_group.criteria, rowData.customer_name_group.is_match,
                    rowData.po_or_auth_number_group.msd, rowData.po_or_auth_number_group.ocr, rowData.po_or_auth_number_group.accuracy_pct, rowData.po_or_auth_number_group.criteria, rowData.po_or_auth_number_group.is_match,
                    rowData.aadhaar_number_group.msd, rowData.aadhaar_number_group.ocr, rowData.aadhaar_number_group.accuracy_pct, rowData.aadhaar_number_group.criteria, rowData.aadhaar_number_group.is_match,
                    rowData.amount_group.msd, rowData.amount_group.ocr, rowData.amount_group.accuracy_pct, rowData.amount_group.criteria, rowData.amount_group.is_match,
                    rowData.stamp_group.msd, rowData.stamp_group.ocr, rowData.stamp_group.accuracy_pct, rowData.stamp_group.criteria, rowData.stamp_group.is_match,
                    rowData.final_validation
                ];
                const row = sheet.addRow(values);
            });

            res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            res.setHeader('Content-Disposition', `attachment; filename=Master_Audit_Report.xlsx`);
            await workbook.xlsx.write(res);
            res.end();
        } catch (error: any) {
            return ResponseHandler.error(res, error.message || "Master report failed", 500);
        }
    }
}
