import { NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';
import React from 'react';
import {
    Document, Page, Text, View, StyleSheet, renderToBuffer, Font,
} from '@react-pdf/renderer';
import {
    EXPORT_FIELDS, ExportFieldKey,
    fetchExportData, weekLabel, fmtDate, priorityLabel, priorityColor,
} from '../export/route';

// ── PDF styles ─────────────────────────────────────────────────────────────

const INDIGO  = '#6366f1';
const SLATE   = '#1e293b';
const MUTED   = '#64748b';
const BORDER  = '#e2e8f0';
const STRIPE  = '#f8fafc';
const WHITE   = '#ffffff';
const SUCCESS = '#059669';

const styles = StyleSheet.create({
    page: {
        fontFamily: 'Helvetica',
        fontSize: 9,
        color: SLATE,
        paddingTop: 48,
        paddingBottom: 48,
        paddingHorizontal: 44,
        backgroundColor: WHITE,
    },
    // ── Cover header
    coverBand: {
        backgroundColor: INDIGO,
        borderRadius: 8,
        paddingVertical: 20,
        paddingHorizontal: 24,
        marginBottom: 24,
    },
    coverTitle: {
        fontFamily: 'Helvetica-Bold',
        fontSize: 20,
        color: WHITE,
        marginBottom: 4,
    },
    coverSub: {
        fontSize: 10,
        color: 'rgba(255,255,255,0.78)',
    },
    coverMeta: {
        fontSize: 9,
        color: 'rgba(255,255,255,0.6)',
        marginTop: 10,
    },
    // ── Summary row
    summaryRow: {
        flexDirection: 'row',
        gap: 10,
        marginBottom: 20,
    },
    summaryCard: {
        flex: 1,
        borderRadius: 6,
        borderWidth: 1,
        borderColor: BORDER,
        paddingVertical: 10,
        paddingHorizontal: 12,
        backgroundColor: STRIPE,
    },
    summaryValue: {
        fontFamily: 'Helvetica-Bold',
        fontSize: 18,
        color: INDIGO,
        marginBottom: 2,
    },
    summaryLabel: {
        fontSize: 8,
        color: MUTED,
        textTransform: 'uppercase',
        letterSpacing: 0.5,
    },
    // ── Week section
    weekBlock: {
        marginBottom: 18,
    },
    weekHeader: {
        flexDirection: 'row',
        alignItems: 'center',
        backgroundColor: INDIGO,
        borderRadius: 5,
        paddingVertical: 6,
        paddingHorizontal: 10,
        marginBottom: 6,
    },
    weekHeaderText: {
        fontFamily: 'Helvetica-Bold',
        fontSize: 10,
        color: WHITE,
        flex: 1,
    },
    weekCount: {
        fontSize: 8,
        color: 'rgba(255,255,255,0.7)',
    },
    // ── Goal banner
    goalBanner: {
        flexDirection: 'row',
        alignItems: 'flex-start',
        backgroundColor: '#eff6ff',
        borderLeftWidth: 3,
        borderLeftColor: '#3b82f6',
        borderRadius: 4,
        paddingVertical: 5,
        paddingHorizontal: 8,
        marginBottom: 6,
        gap: 5,
    },
    goalLabel: {
        fontFamily: 'Helvetica-Bold',
        fontSize: 8,
        color: '#1d4ed8',
        marginBottom: 1,
    },
    goalText: {
        fontSize: 8.5,
        color: '#1e40af',
        fontFamily: 'Helvetica-Oblique',
    },
    // ── Table
    tableHeader: {
        flexDirection: 'row',
        backgroundColor: '#f1f5f9',
        borderTopLeftRadius: 4,
        borderTopRightRadius: 4,
        paddingVertical: 4,
        paddingHorizontal: 6,
        borderBottomWidth: 1,
        borderBottomColor: BORDER,
    },
    tableHeaderCell: {
        fontFamily: 'Helvetica-Bold',
        fontSize: 7.5,
        color: MUTED,
        textTransform: 'uppercase',
        letterSpacing: 0.3,
    },
    tableRow: {
        flexDirection: 'row',
        paddingVertical: 5,
        paddingHorizontal: 6,
        borderBottomWidth: 1,
        borderBottomColor: BORDER,
        alignItems: 'flex-start',
    },
    tableRowAlt: {
        backgroundColor: STRIPE,
    },
    cell: {
        fontSize: 8.5,
        color: SLATE,
        paddingRight: 4,
    },
    cellMuted: {
        fontSize: 8,
        color: MUTED,
        paddingRight: 4,
    },
    priorityDot: {
        width: 6,
        height: 6,
        borderRadius: 3,
        marginTop: 1,
        marginRight: 4,
        flexShrink: 0,
    },
    checkMark: {
        fontSize: 8,
        color: SUCCESS,
        marginRight: 4,
        flexShrink: 0,
    },
    // ── Footer
    footer: {
        position: 'absolute',
        bottom: 20,
        left: 44,
        right: 44,
        flexDirection: 'row',
        justifyContent: 'space-between',
        borderTopWidth: 1,
        borderTopColor: BORDER,
        paddingTop: 6,
    },
    footerText: {
        fontSize: 7.5,
        color: '#94a3b8',
    },
});

// ── Column width config ────────────────────────────────────────────────────

const COL_WIDTHS: Partial<Record<ExportFieldKey, number>> = {
    completedDate: 60,
    scheduledDate: 60,
    createdDate:   60,
    project:       70,
    list:          70,
    priority:      65,
    url:           80,
    notes:         100,
    description:   80,
    delegatedTo:   60,
    delegationNote:80,
    startTime:     40,
    kanbanStage:   55,
};

// ── PDF Document component ─────────────────────────────────────────────────

function WorkReportPDF({
    byWeek,
    goalByWeek,
    colFields,
    selectedFields,
    de,
    userName,
    startDate,
    endDate,
}: {
    byWeek: Map<string, any[]>;
    goalByWeek: Map<string, string>;
    colFields: typeof EXPORT_FIELDS;
    selectedFields: Set<ExportFieldKey>;
    de: boolean;
    userName: string;
    startDate: string | null;
    endDate: string | null;
}) {
    const totalTasks = Array.from(byWeek.values()).reduce((s, t) => s + t.length, 0);
    const totalWeeks = byWeek.size;
    const projectSet = new Set<string>();
    for (const tasks of byWeek.values()) {
        for (const t of tasks) if (t.project?.name) projectSet.add(t.project.name);
    }

    const exportedOn = new Date().toLocaleDateString(de ? 'de-DE' : 'en-GB', {
        day: '2-digit', month: 'long', year: 'numeric',
    });

    const periodLabel = startDate && endDate
        ? `${fmtDate(new Date(startDate), de)} – ${fmtDate(new Date(endDate), de)}`
        : startDate ? `${de ? 'Ab' : 'From'} ${fmtDate(new Date(startDate), de)}`
        : endDate   ? `${de ? 'Bis' : 'Until'} ${fmtDate(new Date(endDate), de)}`
        : de ? 'Gesamter Zeitraum' : 'All time';

    // Total title column width = page width minus padding minus sum of other cols
    const usableWidth = 595 - 88; // A4 minus 2×44 padding
    const otherColsWidth = colFields.reduce((s, f) => s + (COL_WIDTHS[f.key] || 70), 0);
    const titleWidth = Math.max(80, usableWidth - otherColsWidth - 10 /* dot/check */);

    return React.createElement(Document, { title: de ? 'Arbeitsbericht' : 'Work Report' },
        React.createElement(Page, { size: 'A4', style: styles.page },

            // ── Cover band
            React.createElement(View, { style: styles.coverBand },
                React.createElement(Text, { style: styles.coverTitle },
                    de ? 'Arbeitsbericht' : 'Work Report'
                ),
                React.createElement(Text, { style: styles.coverSub }, userName),
                React.createElement(Text, { style: styles.coverMeta },
                    `${periodLabel}   ·   ${de ? 'Exportiert am' : 'Exported'} ${exportedOn}`
                ),
            ),

            // ── Summary cards
            React.createElement(View, { style: styles.summaryRow },
                React.createElement(View, { style: styles.summaryCard },
                    React.createElement(Text, { style: styles.summaryValue }, String(totalTasks)),
                    React.createElement(Text, { style: styles.summaryLabel }, de ? 'Erledigte Aufgaben' : 'Completed tasks'),
                ),
                React.createElement(View, { style: styles.summaryCard },
                    React.createElement(Text, { style: styles.summaryValue }, String(totalWeeks)),
                    React.createElement(Text, { style: styles.summaryLabel }, de ? 'Kalenderwochen' : 'Calendar weeks'),
                ),
                React.createElement(View, { style: styles.summaryCard },
                    React.createElement(Text, { style: styles.summaryValue }, String(projectSet.size)),
                    React.createElement(Text, { style: styles.summaryLabel }, de ? 'Projekte' : 'Projects'),
                ),
            ),

            // ── Week sections
            ...Array.from(byWeek.entries()).map(([weekKey, tasks]) => {
                const goal = selectedFields.has('weekGoal') ? goalByWeek.get(weekKey) : undefined;

                return React.createElement(View, { key: weekKey, style: styles.weekBlock, wrap: false },

                    // Week header bar
                    React.createElement(View, { style: styles.weekHeader },
                        React.createElement(Text, { style: styles.weekHeaderText },
                            selectedFields.has('week') ? weekLabel(weekKey, de) : weekKey
                        ),
                        React.createElement(Text, { style: styles.weekCount },
                            `${tasks.length} ${de ? 'Aufgaben' : 'tasks'}`
                        ),
                    ),

                    // Goal banner
                    ...(goal ? [
                        React.createElement(View, { style: styles.goalBanner },
                            React.createElement(View, null,
                                React.createElement(Text, { style: styles.goalLabel },
                                    de ? 'Wochenziel' : 'Goal of the week'
                                ),
                                React.createElement(Text, { style: styles.goalText }, goal),
                            ),
                        ),
                    ] : []),

                    // Table header
                    React.createElement(View, { style: styles.tableHeader },
                        React.createElement(View, { style: { width: 10 } }), // dot/check space
                        React.createElement(Text, { style: [styles.tableHeaderCell, { flex: 1, minWidth: titleWidth }] },
                            de ? 'Aufgabe' : 'Task'
                        ),
                        ...colFields.map(f =>
                            React.createElement(Text, {
                                key: f.key,
                                style: [styles.tableHeaderCell, { width: COL_WIDTHS[f.key] || 70 }],
                            }, de ? f.labelDe : f.labelEn)
                        ),
                    ),

                    // Task rows
                    ...tasks.map((t, i) => {
                        const pColor = priorityLabel(t, de) ? priorityColor(t) : undefined;
                        return React.createElement(View, {
                            key: t.id,
                            style: [styles.tableRow, i % 2 === 1 ? styles.tableRowAlt : {}],
                        },
                            // Priority dot or checkmark
                            pColor
                                ? React.createElement(View, { style: [styles.priorityDot, { backgroundColor: pColor }] })
                                : React.createElement(Text, { style: styles.checkMark }, '✓'),

                            // Title
                            React.createElement(Text, { style: [styles.cell, { flex: 1, minWidth: titleWidth }] }, t.title || ''),

                            // Dynamic columns
                            ...colFields.map(f => {
                                let val = '';
                                switch (f.key) {
                                    case 'completedDate':  val = fmtDate(t.updatedAt, de); break;
                                    case 'scheduledDate':  val = fmtDate(t.scheduledDate, de); break;
                                    case 'createdDate':    val = fmtDate(t.createdAt, de); break;
                                    case 'project':        val = t.project?.name || ''; break;
                                    case 'list':           val = t.somedayList?.title || ''; break;
                                    case 'priority':       val = priorityLabel(t, de); break;
                                    case 'url':            val = t.url || ''; break;
                                    case 'notes':          val = (t.markdownContent || '').slice(0, 200); break;
                                    case 'description':    val = (t.description || '').slice(0, 200); break;
                                    case 'delegatedTo':    val = t.delegatedTo || ''; break;
                                    case 'delegationNote': val = t.delegationNote || ''; break;
                                    case 'startTime':      val = t.startTime || ''; break;
                                    case 'kanbanStage':    val = t.kanbanStage || ''; break;
                                }
                                return React.createElement(Text, {
                                    key: f.key,
                                    style: [styles.cellMuted, { width: COL_WIDTHS[f.key] || 70 }],
                                }, val);
                            }),
                        );
                    }),
                );
            }),

            // ── Footer
            React.createElement(View, { style: styles.footer, fixed: true },
                React.createElement(Text, { style: styles.footerText },
                    de ? 'Arbeitsbericht — My Weekly ToDo' : 'Work Report — My Weekly ToDo'
                ),
                React.createElement(Text, {
                    style: styles.footerText,
                    render: ({ pageNumber, totalPages }: { pageNumber: number; totalPages: number }) =>
                        `${pageNumber} / ${totalPages}`,
                }),
            ),
        )
    );
}

// ── Route ──────────────────────────────────────────────────────────────────

export async function GET(request: Request) {
    const session = await getServerSession(authOptions);
    const { searchParams } = new URL(request.url);
    const startDate   = searchParams.get('startDate');
    const endDate     = searchParams.get('endDate');
    const lang        = searchParams.get('lang') || 'de';
    const de          = lang === 'de';

    const fieldsParam = searchParams.get('fields');
    const selectedFields: Set<ExportFieldKey> = fieldsParam
        ? new Set(fieldsParam.split(',') as ExportFieldKey[])
        : new Set(EXPORT_FIELDS.filter(f => f.defaultOn).map(f => f.key));

    if (!session?.user?.email) {
        return new NextResponse('Unauthorized', { status: 401 });
    }

    try {
        const user = await prisma.user.findUnique({
            where: { email: session.user.email },
            select: { id: true, name: true, email: true },
        });
        if (!user) return new NextResponse('User not found', { status: 404 });

        const { byWeek, goalByWeek } = await fetchExportData(user.id, startDate, endDate);

        // Column fields = selected fields that are actual table columns (not csvOnly section markers)
        const colFields = EXPORT_FIELDS.filter(f => selectedFields.has(f.key) && !f.csvOnly);

        const pdfBuffer = await renderToBuffer(
            React.createElement(WorkReportPDF, {
                byWeek,
                goalByWeek,
                colFields,
                selectedFields,
                de,
                userName: user.name || user.email || '',
                startDate,
                endDate,
            }) as React.ReactElement<any>
        );

        const period = startDate && endDate ? `_${startDate}_${endDate}` : startDate ? `_ab_${startDate}` : endDate ? `_bis_${endDate}` : '';
        const filename = de
            ? `arbeitsbericht${period}_${new Date().toISOString().split('T')[0]}.pdf`
            : `work-report${period}_${new Date().toISOString().split('T')[0]}.pdf`;

        return new NextResponse(new Uint8Array(pdfBuffer), {
            headers: {
                'Content-Type': 'application/pdf',
                'Content-Disposition': `attachment; filename="${filename}"`,
            },
        });
    } catch (error) {
        console.error('PDF export error:', error);
        return new NextResponse('Internal Server Error', { status: 500 });
    }
}
