import * as fs from 'fs';
import * as path from 'path';
import { jsonReportFilePath, reportFilePath } from '../../playwright.config';

interface PageSummary {
    pageName: string;
    critical: number;
    serious: number;
    moderate: number;
    minor: number;
    total: number;
}

export function updateAccessibilityReport(pageName: string, results: any) {
    const reportDir = path.dirname(jsonReportFilePath);
    if (!fs.existsSync(reportDir)) {
        fs.mkdirSync(reportDir, { recursive: true });
    }

    let existingIssues: { [key: string]: any[] } = {};
    if (fs.existsSync(jsonReportFilePath)) {
        existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));
    }

    if (!existingIssues[pageName]) {
        existingIssues[pageName] = [];
    }

    results.violations.forEach(violation => {
        const violationWithPage = { ...violation, pageName };
        if (!isDuplicateIssue(existingIssues[pageName], violationWithPage)) {
            existingIssues[pageName].push(violationWithPage);
        }
    });

    fs.writeFileSync(jsonReportFilePath, JSON.stringify(existingIssues, null, 2));
}

export function consolidateJsonReport() {
    if (!fs.existsSync(jsonReportFilePath)) {
        console.error('JSON report file does not exist.');
        return;
    }

    const existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));

    // Consolidate issues by page
    const consolidatedIssues: { [key: string]: any[] } = {};
    Object.keys(existingIssues).forEach(pageName => {
        if (!consolidatedIssues[pageName]) {
            consolidatedIssues[pageName] = [];
        }
        existingIssues[pageName].forEach(issue => {
            if (!isDuplicateIssue(consolidatedIssues[pageName], issue)) {
                consolidatedIssues[pageName].push(issue);
            }
        });
    });

    fs.writeFileSync(jsonReportFilePath, JSON.stringify(consolidatedIssues, null, 2));
}

function generateSummaryTable(existingIssues: { [key: string]: any[] }): string {
    let totalCritical = 0;
    let totalSerious = 0;
    let totalModerate = 0;
    let totalMinor = 0;
    let totalTotal = 0;

    Object.keys(existingIssues).forEach(pageName => {
        const issues = existingIssues[pageName];
        totalCritical += issues.filter(issue => issue.impact === 'critical').length;
        totalSerious += issues.filter(issue => issue.impact === 'serious').length;
        totalModerate += issues.filter(issue => issue.impact === 'moderate').length;
        totalMinor += issues.filter(issue => issue.impact === 'minor').length;
        totalTotal += issues.length;
    });

    return `
        <table class="summary-table" role="table">
            <thead>
                <tr>
                    <th>Page Name</th>
                    <th>Critical</th>
                    <th>Serious</th>
                    <th>Moderate</th>
                    <th>Minor</th>
                    <th>Total</th>
                </tr>
            </thead>
            <tbody>
                ${Object.keys(existingIssues).map(pageName => {
                    const issues = existingIssues[pageName];
                    const critical = issues.filter(issue => issue.impact === 'critical').length;
                    const serious = issues.filter(issue => issue.impact === 'serious').length;
                    const moderate = issues.filter(issue => issue.impact === 'moderate').length;
                    const minor = issues.filter(issue => issue.impact === 'minor').length;
                    const total = issues.length;

                    return `
                        <tr>
                            <td><a href="#${pageName.replace(/\s+/g, '-')}">${pageName}</a></td>
                            <td><a href="#${pageName.replace(/\s+/g, '-')}-critical">${critical}</a></td>
                            <td><a href="#${pageName.replace(/\s+/g, '-')}-serious">${serious}</a></td>
                            <td><a href="#${pageName.replace(/\s+/g, '-')}-moderate">${moderate}</a></td>
                            <td><a href="#${pageName.replace(/\s+/g, '-')}-minor">${minor}</a></td>
                            <td>${total}</td>
                        </tr>
                    `;
                }).join('')}
            </tbody>
            <tfoot>
                <tr>
                    <td><b>Total</b></td>
                    <td><b>${totalCritical}</b></td>
                    <td><b>${totalSerious}</b></td>
                    <td><b>${totalModerate}</b></td>
                    <td><b>${totalMinor}</b></td>
                    <td><b>${totalTotal}</b></td>
                </tr>
            </tfoot>
        </table>
    `;
}

function generateImpactSections(issues: any[], pageName: string): string {
    return ['critical', 'serious', 'moderate', 'minor'].map(impactType => {
        const violations = issues.filter(issue => issue.impact === impactType);
        if (violations.length === 0) return '';

        return `
            <div class="impact-section" id="${pageName.replace(/\s+/g, '-')}-${impactType}">
                <h3>${impactType.charAt(0).toUpperCase() + impactType.slice(1)} Impact</h3>
                <button type="button" class="collapsible">${impactType.charAt(0).toUpperCase() + impactType.slice(1)} Impact</button>
                <div class="content">
                    <table role="table">
                        <thead>
                            <tr>
                                <th>Impact</th>
                                <th>Description</th>
                                <th>Help URL</th>
                                <th>Tags</th>
                                <th>Nodes</th>
                            </tr>
                        </thead>
                        <tbody>
                            ${violations.map(violation => `
                                <tr>
                                    <td>${violation.impact}</td>
                                    <td>${violation.description}</td>
                                    <td><a href="${violation.helpUrl}" target="_blank">${violation.helpUrl}</a></td>
                                    <td>${violation.tags.join(', ')}</td>
                                    <td>
                                        ${violation.nodes.map(node => `
                                            <div class="node">
                                                <div class="html">${node.html}</div>
                                                <div class="target">Target: ${node.target.join(', ')}</div>
                                                <div class="failureSummary">${node.failureSummary}</div>
                                                <div class="any">
                                                    <strong>Any:</strong>
                                                    ${node.any.map(check => `
                                                        <div class="check">
                                                            <div class="message">${check.message}</div>
                                                        </div>
                                                    `).join('')}
                                                </div>
                                                <div class="all">
                                                    <strong>All:</strong>
                                                    ${node.all.map(check => `
                                                        <div class="check">
                                                            <div class="message">${check.message}</div>
                                                        </div>
                                                    `).join('')}
                                                </div>
                                                <div class="none">
                                                    <strong>None:</strong>
                                                    ${node.none.map(check => `
                                                        <div class="check">
                                                            <div class="message">${check.message}</div>
                                                        </div>
                                                    `).join('')}
                                                </div>
                                            </div>
                                        `).join('')}
                                    </td>
                                </tr>
                            `).join('')}
                        </tbody>
                    </table>
                </div>
            </div>
        `;
    }).join('');
}

function generateDetailedSections(existingIssues: { [key: string]: any[] }): string {
    return Object.keys(existingIssues).map(pageName => {
        const issues = existingIssues[pageName];
        const impactSections = generateImpactSections(issues, pageName);

        return `
            <div class="page-section" id="${pageName.replace(/\s+/g, '-')}">
                <h2>${pageName}</h2>
                ${impactSections}
            </div>
        `;
    }).join('');
}

export function createAccessibilityHtmlReport() {
    consolidateJsonReport();

    if (!fs.existsSync(jsonReportFilePath)) {
        console.error('JSON report file does not exist.');
        return;
    }

    const existingIssues = JSON.parse(fs.readFileSync(jsonReportFilePath, 'utf-8'));

    const inlineStyles = `
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            color: #333;
        }
        h1 {
            text-align: center;
            color: #4CAF50;
        }
        .summary-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        .summary-table th, .summary-table td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }
        .summary-table th {
            background-color: #007BFF;
            color: white;
        }
        .summary-table td a {
            color: #007BFF;
            text-decoration: none;
        }
        .summary-table td a:hover {
            text-decoration: underline;
        }
        .page-section {
            margin-bottom: 40px;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .impact-section {
            margin-bottom: 20px;
        }
        .violation {
            margin-bottom: 20px;
        }
        .violation .impact {
            font-weight: bold;
            color: #d9534f;
        }
        .violation .description {
            margin-top: 5px;
        }
        .violation .helpUrl {
            margin-top: 5px;
        }
        .violation .tags {
            margin-top: 5px;
        }
        .violation .nodes {
            margin-top: 10px;
        }
        .violation .node {
            margin-top: 5px;
        }
        .collapsible {
            background-color: #f9f9f9;
            color: #333;
            cursor: pointer;
            padding: 10px;
            width: 100%;
            border: none;
            text-align: left;
            outline: none;
            font-size: 15px;
        }
        .active, .collapsible:hover {
            background-color: #ccc;
        }
        .content {
            padding: 0 18px;
            display: none;
            overflow: hidden;
            background-color: #f1f1f1;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }
        tfoot {
            font-weight: bold;
        }
    `;

    let reportContent = `
        <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>ISS Accessibility Report</title>
            <style>${inlineStyles}</style>
        </head>
        <body>
            <h1>Accessibility Report</h1>
    `;

    reportContent += generateSummaryTable(existingIssues);
    reportContent += generateDetailedSections(existingIssues);

    reportContent += `
            <script>
                var coll = document.getElementsByClassName("collapsible");
                for (var i = 0; i < coll.length; i++) {
                    coll[i].addEventListener("click", function() {
                        this.classList.toggle("active");
                        var content = this.nextElementSibling;
                        if (content.style.display === "block") {
                            content.style.display = "none";
                        } else {
                            content.style.display = "block";
                        }
                    });
                }
            </script>
        </body>
        </html>
    `;

    try {
        fs.writeFileSync(reportFilePath, reportContent);
        console.log(`Accessibility Report generated successfully at ${reportFilePath}`);
    } catch (error) {
        console.error('Error writing report file:', error);
    }
}

function isDuplicateIssue(existingIssues: any[], newIssue: any): boolean {
    return existingIssues.some(issue => {
        return issue.id === newIssue.id && issue.pageName === newIssue.pageName;
    });
}
