import type { ComposerTranslation } from 'vue-i18n';
import type {
    UsageBillingCategory,
    UsageBillingSummary,
    UsageBillingTotals,
} from '@/types/usageBilling';
import * as XLSX from 'xlsx';
import { formatCurrency, saudiRiyalFontFaceCss } from '@/utils/formatCurrency';
import { formatDate } from '@/utils/formatDate';

export interface UsageBillingExportData {
    summary: UsageBillingSummary;
    categories: UsageBillingCategory[];
    totals: UsageBillingTotals;
    companyName: string;
    planName: string;
}

interface UsageBillingExportLabels {
    pageTitle: string;
    pageSubtitle: string;
    dashboardTitle: string;
    categoryItem: string;
    qty: string;
    unitPrice: string;
    total: string;
    subtotal: string;
    vat: string;
    vatNote: string;
    grandTotal: string;
    showingFor: string;
    account: string;
    plan: string;
    perMonth: string;
    notAvailable: string;
}

function formatUnitPrice(
    price: number | 'N/A',
    suffix: 'monthly' | null,
    locale: string,
    perMonthLabel: string,
    withSymbol: boolean,
    notAvailableLabel: string,
): string {
    if (price === 'N/A') {
        return notAvailableLabel;
    }

    const formatted = formatCurrency(price, locale, { withSymbol });

    return suffix === 'monthly' ? `${formatted} ${perMonthLabel}` : formatted;
}

function buildLabels(t: ComposerTranslation, vatRate: number): UsageBillingExportLabels {
    return {
        pageTitle: t('usage_billing.page_title'),
        pageSubtitle: t('usage_billing.page_subtitle'),
        dashboardTitle: t('dashboard.title'),
        categoryItem: t('usage_billing.breakdown.columns.category_item'),
        qty: t('usage_billing.breakdown.columns.qty'),
        unitPrice: t('usage_billing.breakdown.columns.unit_price'),
        total: t('usage_billing.breakdown.columns.total'),
        subtotal: t('usage_billing.breakdown.subtotal'),
        vat: t('usage_billing.breakdown.vat', { rate: Math.round(vatRate * 100) }),
        vatNote: t('usage_billing.breakdown.vat_note'),
        grandTotal: t('usage_billing.breakdown.grand_total'),
        showingFor: t('usage_billing.breakdown.showing_for'),
        account: t('usage_billing.breakdown.account'),
        plan: t('usage_billing.breakdown.plan'),
        perMonth: t('packages_page.per_month'),
        notAvailable: t('usage_billing.breakdown.not_available'),
    };
}

function buildTableRows(
    data: UsageBillingExportData,
    labels: UsageBillingExportLabels,
    locale: string,
    withSymbol: boolean,
): string[][] {
    const money = (amount: number) => formatCurrency(amount, locale, { withSymbol });

    const rows: string[][] = [
        [labels.categoryItem, labels.qty, labels.unitPrice, labels.total],
    ];

    for (const category of data.categories) {
        rows.push([
            `${category.label} — ${category.description}`,
            '',
            '',
            money(category.total),
        ]);

        for (const item of category.items) {
            rows.push([
                item.name,
                String(item.quantity),
                formatUnitPrice(
                    item.unit_price,
                    item.unit_suffix,
                    locale,
                    labels.perMonth,
                    withSymbol,
                    labels.notAvailable,
                ),
                money(item.total),
            ]);
        }
    }

    rows.push(['', '', '', '']);
    rows.push([
        '',
        '',
        labels.subtotal,
        money(data.totals.subtotalWithoutVat),
    ]);
    rows.push([
        '',
        '',
        `${labels.vat} (${labels.vatNote})`,
        money(data.totals.vat_amount),
    ]);
    rows.push([
        '',
        '',
        labels.grandTotal,
        money(data.totals.total),
    ]);

    return rows;
}

function buildPdfTableHtml(rows: string[][], locale: string): string {
    const textAlign = locale === 'ar' ? 'right' : 'left';

    return rows.map((row, index) => {
        const isHeader = index === 0;
        const isFooter = index >= rows.length - 4;
        const tag = isHeader ? 'th' : 'td';
        const cells = row.map((cell, cellIndex) => {
            const align = cellIndex === 0 ? textAlign : cellIndex === 1 ? 'center' : 'right';
            const style = isHeader
                ? ''
                : isFooter && cellIndex === 2
                    ? 'font-weight: 600;'
                    : isFooter && cellIndex === 3
                        ? 'font-weight: 700;'
                        : '';

            return `<${tag} style="text-align: ${align}; ${style}">${cell}</${tag}>`;
        }).join('');

        return `<tr>${cells}</tr>`;
    }).join('');
}

export function exportUsageBillingToPdf(
    data: UsageBillingExportData,
    t: ComposerTranslation,
    locale: string,
): void {
    const labels = buildLabels(t, data.totals.vat_rate);
    const rows = buildTableRows(data, labels, locale, true);
    const tableHtml = buildPdfTableHtml(rows, locale);
    const periodLabel = data.summary.billing_period_label;

    const riyalFontUrl = `${window.location.origin}/fonts/saudi-riyal.woff2`
    const htmlContent = `
        <html dir="${locale === 'ar' ? 'rtl' : 'ltr'}">
        <head>
            <meta charset="utf-8">
            <title>${labels.pageTitle}</title>
            <style>
                ${saudiRiyalFontFaceCss(riyalFontUrl)}
                body {
                    font-family: "SaudiRiyal", 'Inter', sans-serif;
                    padding: 40px;
                    color: #1e293b;
                    background-color: #ffffff;
                }
                .header {
                    display: flex;
                    justify-content: space-between;
                    align-items: flex-start;
                    border-bottom: 2px solid #e2e8f0;
                    padding-bottom: 20px;
                    margin-bottom: 24px;
                }
                .title {
                    font-size: 24px;
                    font-weight: 700;
                    color: #0f172a;
                }
                .meta {
                    font-size: 14px;
                    color: #475569;
                    margin-top: 8px;
                    line-height: 1.6;
                }
                .date {
                    font-size: 14px;
                    color: #64748b;
                }
                table {
                    width: 100%;
                    border-collapse: collapse;
                }
                th {
                    background-color: #f8fafc;
                    color: #475569;
                    font-weight: 600;
                    font-size: 13px;
                    padding: 14px 16px;
                    border-bottom: 2px solid #e2e8f0;
                }
                td {
                    padding: 14px 16px;
                    border-bottom: 1px solid #f1f5f9;
                    font-size: 13px;
                    color: #334155;
                }
                tr:nth-child(even) td {
                    background-color: #fcfcfc;
                }
                .footer {
                    margin-top: 50px;
                    text-align: center;
                    font-size: 12px;
                    color: #94a3b8;
                    border-top: 1px solid #e2e8f0;
                    padding-top: 20px;
                }
            </style>
        </head>
        <body>
            <div class="header">
                <div>
                    <div class="title">${labels.pageTitle}</div>
                    <div class="meta">
                        ${data.companyName ? `<div>${data.companyName}</div>` : ''}
                        <div>${labels.showingFor} <strong>${periodLabel}</strong></div>
                        <div>${labels.plan} <strong>${data.planName}</strong></div>
                    </div>
                </div>
                <div class="date">${formatDate(new Date().toISOString())}</div>
            </div>
            <table>
                <tbody>
                    ${tableHtml}
                </tbody>
            </table>
            <div class="footer">
                ${labels.dashboardTitle} - ${labels.pageSubtitle}
            </div>
        </body>
        </html>
    `;

    const printWindow = window.open('', '_blank');

    if (!printWindow) {
        return;
    }

    printWindow.document.write(htmlContent);
    printWindow.document.close();
    printWindow.focus();

    setTimeout(() => {
        printWindow.print();
        printWindow.close();
    }, 300);
}

export function exportUsageBillingToExcel(
    data: UsageBillingExportData,
    t: ComposerTranslation,
    locale: string,
    companyName?: string | null,
): void {
    const labels = buildLabels(t, data.totals.vat_rate);
    const rows = buildTableRows(data, labels, locale, false);
    const headerRows: string[][] = [
        [labels.pageTitle],
        [data.companyName],
        [`${labels.showingFor} ${data.summary.billing_period_label}`],
        [`${labels.plan} ${data.planName}`],
        [],
    ];
    const worksheetData = [...headerRows, ...rows];
    const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);

    if (locale === 'ar') {
        if (!worksheet['!views']) {
            worksheet['!views'] = [];
        }

        worksheet['!views'].push({ RTL: true });
    }

    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, labels.pageTitle);

    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const blob = new Blob(
        [excelBuffer],
        { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' },
    );
    const url = URL.createObjectURL(blob);
    const filename = `${companyName ? `${companyName} - ` : ''}${labels.pageTitle}.xlsx`;

    const link = document.createElement('a');
    link.setAttribute('href', url);
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
}
