import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';

function age(iso) {
    if (!iso) return { y: 0, m: 0 };
    const t = new Date(), b = new Date(iso);
    let y = t.getFullYear() - b.getFullYear();
    let m = t.getMonth() - b.getMonth();
    if (m < 0) { y--; m += 12; }
    return { y, m };
}

export async function GET({ params, fetch, cookies }) {
    const { id } = params;

    const token = cookies.get('session');
    if (!token) {
        return new Response(JSON.stringify({ success: false, message: 'unauthorized: missing token' }), {
            status: 401, headers: { 'Content-Type': 'application/json' }
        });
    }
    const auth = token;

    const API_BASE = 'http://localhost:8080/v1';

    const patientRes = await fetch(`${API_BASE}/patients/${id}`, {
        headers: { Authorization: auth }
    });
    if (!patientRes.ok) {
        return new Response(await patientRes.text(), { status: patientRes.status });
    }
    const pjRaw = await patientRes.json();
    const patient = (pjRaw?.data ?? pjRaw) || {};

    let diagnose = null;
    const diagnoseRes = await fetch(`${API_BASE}/diagnoses/${id}`, {
        headers: { Authorization: auth }
    });
    if (diagnoseRes.ok) {
        const djRaw = await diagnoseRes.json();
        diagnose = (djRaw?.data ?? djRaw) || null;
    }

    const pdf = await PDFDocument.create();
    let page = pdf.addPage([595.28, 841.89]);
    const font = await pdf.embedFont(StandardFonts.Helvetica);
    const M = 42;
    const pageH = 841.89;
    let y = pageH - M;
    const lineColor = rgb(0.8, 0.8, 0.8);
    const headerBg = rgb(0.95, 0.95, 0.95);

    const draw = (t, size = 12, x = M, color = rgb(0, 0, 0)) => {
        page.drawText(String(t ?? ''), { x, y, size, font, color });
        y -= size + 6;
    };

    const wrapLines = (text, maxWidth, size = 12) => {
        const words = String(text ?? '').split(/\s+/);
        const lines = [];
        let line = '';
        for (const w of words) {
            const test = line ? `${line} ${w}` : w;
            if (font.widthOfTextAtSize(test, size) > maxWidth) {
                if (line) lines.push(line);
                line = w;
            } else line = test;
        }
        if (line) lines.push(line);
        return lines;
    };

    const ensurePageSpace = (needed) => {
        if (y - needed < 40) {
            page = pdf.addPage([595.28, 841.89]);
            y = pageH - M;
        }
    };

    const drawTable = ({ x = M, widths = [], header = [], rows = [], cellPad = 6, fontSize = 11 }) => {
        const tableW = widths.reduce((a, b) => a + b, 0);

        const headerHeights = header.map((h, i) =>
            wrapLines(h, widths[i] - 2 * cellPad, fontSize).length || 1
        );
        const headerLinesMax = header.length ? Math.max(...headerHeights) : 0;
        const headerH = header.length ? headerLinesMax * (fontSize + 2) + 2 * cellPad : 0;

        const rowHeights = rows.map((row) => {
            const counts = row.map((cell, i) =>
                wrapLines(cell, widths[i] - 2 * cellPad, fontSize).length || 1
            );
            return Math.max(...counts) * (fontSize + 2) + 2 * cellPad;
        });

        const totalH = headerH + rowHeights.reduce((a, b) => a + b, 0);
        ensurePageSpace(totalH + 10);

        let cursorY = y;

        if (header.length) {
            page.drawRectangle({ x, y: cursorY - headerH, width: tableW, height: headerH, color: headerBg, borderColor: lineColor, borderWidth: 1 });

            let cx = x;
            header.forEach((h, i) => {
                const lines = wrapLines(h, widths[i] - 2 * cellPad, fontSize);
                let ty = cursorY - cellPad - fontSize;
                lines.forEach((ln) => {
                    page.drawText(ln, { x: cx + cellPad, y: ty, size: fontSize, font });
                    ty -= (fontSize + 2);
                });
                page.drawRectangle({ x: cx, y: cursorY - headerH, width: widths[i], height: headerH, borderColor: lineColor, borderWidth: 1 });
                cx += widths[i];
            });
            cursorY -= headerH;
        }

        rows.forEach((row, rowIdx) => {
            const rh = rowHeights[rowIdx];

            page.drawRectangle({ x, y: cursorY - rh, width: tableW, height: rh, borderColor: lineColor, borderWidth: 1 });

            let cx = x;
            row.forEach((cell, i) => {
                page.drawRectangle({ x: cx, y: cursorY - rh, width: widths[i], height: rh, borderColor: lineColor, borderWidth: 1 });

                const lines = wrapLines(cell, widths[i] - 2 * cellPad, fontSize);
                let ty = cursorY - cellPad - fontSize;
                lines.forEach((ln) => {
                    page.drawText(ln, { x: cx + cellPad, y: ty, size: fontSize, font, color: rgb(0, 0, 0) });
                    ty -= (fontSize + 2);
                });

                cx += widths[i];
            });

            cursorY -= rh;

            if (cursorY < 60 && rowIdx < rows.length - 1) {
                y = cursorY;
                ensurePageSpace(120);
                cursorY = y;
            }
        });

        y = cursorY - 12;
    };

    draw('Laporan Diagnosa Pasien', 18, M, rgb(0.1, 0.1, 0.1));
    y -= 6;

    const um = age(patient?.birth_date);
    const infoRows = [
        ['Nama Lengkap', patient?.fullname ?? '-'],
        ['Usia', patient?.birth_date ? `${um.y} tahun ${um.m} bulan` : '-'],
        ['Tanggal Lahir', patient?.birth_date ?? '-'],
        ['Jenis Kelamin', patient?.gender === 'male' ? 'Laki-Laki' : patient?.gender === 'female' ? 'Perempuan' : '-'],
        ['Didaftarkan Oleh', patient?.created_by?.username ?? '-'],
        ['Tanggal Daftar', patient?.created_at ?? '-']
    ];

    drawTable({
        widths: [160, (page.getSize().width - 2 * M) - 160],
        header: ['Informasi Pasien', ''],
        rows: infoRows,
        fontSize: 11
    });

    const diagnosaRows = [
        ['Penyakit', diagnose?.disease?.name ?? '-'],
        ['Deskripsi', diagnose?.disease?.description ?? '-'],
        ['Rekomendasi', diagnose?.disease?.treatment ?? '-']
    ];

    drawTable({
        widths: [160, (page.getSize().width - 2 * M) - 160],
        header: ['Hasil Diagnosa', ''],
        rows: diagnosaRows,
        fontSize: 11
    });

    const gfRows = (diagnose?.symptoms ?? []).map((s) => {
        const follow = (diagnose?.follow_up_questions ?? [])
            .filter((q) => q.symptom_id === s.id)
            .map((q) => `${q?.question ?? ''}: ${q?.option ?? ''}`)
            .join('\n');
        return [s?.name ?? '-', s?.description ?? '-', follow || '-'];
    });

    if (gfRows.length) {
        drawTable({
            widths: [140, 220, (page.getSize().width - 2 * M) - (140 + 220)],
            header: ['Gejala', 'Deskripsi', 'Follow-up'],
            rows: gfRows,
            fontSize: 11
        });
    }

    const bytes = await pdf.save();
    return new Response(new Uint8Array(bytes), {
        headers: {
            'Content-Type': 'application/pdf',
            'Content-Disposition': `attachment; filename="diagnosa-pasien-${id}.pdf"`
        }
    });
}
