<?php
declare(strict_types=1);

require_once __DIR__ . '/../db.php';

$action = strtolower(trim((string) ($_GET['action'] ?? '')));
$user_id = (int) ($_GET['user_id'] ?? 0);
$draft_id = (int) ($_GET['draft_id'] ?? 0);
$attachment_id = (int) ($_GET['attachment_id'] ?? 0);
$download = (int) ($_GET['download'] ?? 0) === 1;

function failFile(int $status, string $message): void
{
    http_response_code($status);
    header('Content-Type: text/plain; charset=utf-8');
    echo $message;
    exit;
}

function checkApprovedUser(mysqli $conn, int $user_id): void
{
    if ($user_id <= 0) {
        failFile(422, 'User tidak sah.');
    }

    $stmt = mysqli_prepare($conn, 'SELECT id FROM users WHERE id = ? AND status = "approved" LIMIT 1');
    if (!$stmt) {
        failFile(500, 'Ralat sistem.');
    }

    mysqli_stmt_bind_param($stmt, 'i', $user_id);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    if (!$result || !mysqli_fetch_assoc($result)) {
        failFile(403, 'Akaun tidak dibenarkan.');
    }
}

function fetchAccessibleDraft(mysqli $conn, int $draft_id, int $user_id): ?array
{
    $sql = "
        SELECT
            ld.*,
            f.folder_name,
            f.folder_code,
            d.file_numbering,
            creator.fullname AS applicant_name,
            creator.department AS applicant_department,
            (SELECT COUNT(*)
             FROM documents d2
             WHERE d2.folder_id = ld.folder_id
               AND d2.deleted_at IS NULL
               AND d2.id <= ld.document_id) AS computed_file_numbering
        FROM letter_drafts ld
        INNER JOIN folders f ON f.id = ld.folder_id
        LEFT JOIN documents d ON d.id = ld.document_id AND d.deleted_at IS NULL
        LEFT JOIN users creator ON creator.id = ld.created_by
        WHERE ld.id = ?
          AND ld.deleted_at IS NULL
          AND (
              ld.created_by = ?
              OR ld.updated_by = ?
              OR ld.support_user_id = ?
              OR ld.department_officer_user_id = ?
              OR EXISTS (
                  SELECT 1
                  FROM letter_approval_recipients lar
                  WHERE lar.draft_id = ld.id
                    AND lar.user_id = ?
              )
          )
        LIMIT 1";

    $stmt = mysqli_prepare($conn, $sql);
    if (!$stmt) {
        return null;
    }

    mysqli_stmt_bind_param($stmt, 'iiiiii', $draft_id, $user_id, $user_id, $user_id, $user_id, $user_id);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    return $result ? mysqli_fetch_assoc($result) ?: null : null;
}

function cleanHtmlForPdf(string $html): string
{
    $text = html_entity_decode(strip_tags($html), ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $text = preg_replace('/[ \t]+/', ' ', $text);
    $text = preg_replace("/\n{3,}/", "\n\n", (string) $text);
    return trim((string) $text);
}

function malayDateLabel(?string $date): string
{
    $timestamp = strtotime((string) $date);
    if (!$timestamp) {
        return '-';
    }

    $months = [
        1 => 'Januari', 2 => 'Februari', 3 => 'Mac', 4 => 'April',
        5 => 'Mei', 6 => 'Jun', 7 => 'Julai', 8 => 'Ogos',
        9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Disember',
    ];

    return date('d', $timestamp) . ' ' . $months[(int) date('n', $timestamp)] . ' ' . date('Y', $timestamp);
}

function pdfEscape(string $text): string
{
    $text = iconv('UTF-8', 'Windows-1252//TRANSLIT//IGNORE', $text);
    $text = $text === false ? '' : $text;
    return str_replace(['\\', '(', ')'], ['\\\\', '\\(', '\\)'], $text);
}

function wrapText(string $text, int $width = 86): array
{
    $lines = [];
    foreach (preg_split("/\r\n|\n|\r/", $text) as $paragraph) {
        $paragraph = trim((string) $paragraph);
        if ($paragraph === '') {
            $lines[] = '';
            continue;
        }

        $wrapped = wordwrap($paragraph, $width, "\n", true);
        foreach (explode("\n", $wrapped) as $line) {
            $lines[] = $line;
        }
    }
    return $lines;
}

function streamSimplePdf(array $draft, bool $download): void
{
    $file_numbering = (($draft['file_numbering'] ?? '') !== '' && ($draft['file_numbering'] ?? '') !== ($draft['ref_no'] ?? ''))
        ? ($draft['file_numbering'] ?? '')
        : ($draft['computed_file_numbering'] ?? '');
    $reference = formatDraftLetterReferenceDisplay($draft['department'] ?? '', $draft['ref_no'] ?? '', $file_numbering);
    $title = preg_replace('/[^A-Za-z0-9_\-]+/', '_', (string) ($draft['subject'] ?: 'surat_mainpp'));

    $body = '';
    foreach (decodeDraftLetterPages($draft['letter_pages'] ?? '', $draft['letter_body'] ?? '') as $page) {
        $body .= cleanHtmlForPdf((string) $page) . "\n\n";
    }

    $extra_lines = [];
    if (!empty($draft['department_officer_note'])) {
        $extra_lines[] = '';
        $extra_lines[] = 'Ulasan Pegawai Bahagian MAINPP:';
        $extra_lines[] = (string) $draft['department_officer_note'];
    }
    if (!empty($draft['signatory_name'])) {
        $extra_lines[] = '';
        $extra_lines[] = 'Penandatangan / Pelulus: (' . strtoupper((string) $draft['signatory_name']) . ')';
        $extra_lines[] = 'Status Tandatangan: ' . (!empty($draft['signatory_signature_path']) ? '[Ditandatangani Digital]' : '[Belum Ditandatangani]');
    }

    $lines = array_merge([
        'MAJLIS AGAMA ISLAM NEGERI PULAU PINANG',
        strtoupper((string) ($draft['doc_type'] ?? 'Memo Kelulusan')),
        '',
        'Rujukan: ' . $reference,
        'Tarikh: ' . malayDateLabel($draft['letter_date'] ?? null),
        'Pemohon: ' . (($draft['applicant_name'] ?? '') ?: '-'),
        'Bahagian: ' . (($draft['department'] ?? '') ?: (($draft['applicant_department'] ?? '') ?: '-')),
        '',
        'Perkara:',
        (string) ($draft['subject'] ?? '-'),
        '',
        'Kandungan:',
    ], wrapText($body !== '' ? $body : '-'), $extra_lines);

    $pages = array_chunk($lines, 46);
    $objects = [];
    $page_ids = [];
    $font_id = 3;

    $objects[1] = '<< /Type /Catalog /Pages 2 0 R >>';
    $objects[2] = '<< /Type /Pages /Kids [] /Count 0 >>';
    $objects[$font_id] = '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>';

    $next_id = 4;
    foreach ($pages as $page_index => $page_lines) {
        $content = "BT\n/F1 10 Tf\n50 790 Td\n14 TL\n";
        foreach ($page_lines as $line) {
            $content .= '(' . pdfEscape((string) $line) . ") Tj\nT*\n";
        }
        $content .= "ET";

        $content_id = $next_id++;
        $page_id = $next_id++;
        $objects[$content_id] = '<< /Length ' . strlen($content) . " >>\nstream\n" . $content . "\nendstream";
        $objects[$page_id] = '<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 ' . $font_id . ' 0 R >> >> /Contents ' . $content_id . ' 0 R >>';
        $page_ids[] = $page_id;
    }

    $kids = implode(' ', array_map(static fn($id) => $id . ' 0 R', $page_ids));
    $objects[2] = '<< /Type /Pages /Kids [' . $kids . '] /Count ' . count($page_ids) . ' >>';
    ksort($objects);

    $pdf = "%PDF-1.4\n";
    $offsets = [0];
    foreach ($objects as $id => $object) {
        $offsets[$id] = strlen($pdf);
        $pdf .= $id . " 0 obj\n" . $object . "\nendobj\n";
    }
    $xref_offset = strlen($pdf);
    $max_id = max(array_keys($objects));
    $pdf .= "xref\n0 " . ($max_id + 1) . "\n";
    $pdf .= "0000000000 65535 f \n";
    for ($id = 1; $id <= $max_id; $id++) {
        $pdf .= sprintf("%010d 00000 n \n", $offsets[$id] ?? 0);
    }
    $pdf .= "trailer\n<< /Size " . ($max_id + 1) . " /Root 1 0 R >>\nstartxref\n" . $xref_offset . "\n%%EOF";

    header('Content-Type: application/pdf');
    header('Content-Disposition: ' . ($download ? 'attachment' : 'inline') . '; filename="' . $title . '.pdf"');
    header('Content-Length: ' . strlen($pdf));
    echo $pdf;
    exit;
}

function streamAttachment(mysqli $conn, int $draft_id, int $attachment_id, bool $download): void
{
    $stmt = mysqli_prepare($conn, "
        SELECT a.file_path, a.original_name
        FROM document_attachments a
        INNER JOIN letter_drafts ld ON ld.document_id = a.document_id
        WHERE ld.id = ?
          AND a.id = ?
          AND ld.deleted_at IS NULL
        LIMIT 1
    ");
    if (!$stmt) {
        failFile(500, 'Ralat sistem.');
    }

    mysqli_stmt_bind_param($stmt, 'ii', $draft_id, $attachment_id);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    $attachment = $result ? mysqli_fetch_assoc($result) : null;
    if (!$attachment) {
        failFile(404, 'Lampiran tidak dijumpai.');
    }

    $file_path = (string) ($attachment['file_path'] ?? '');
    $full_path = preg_match('/^[A-Za-z]:[\\\\\\/]/', $file_path) ? $file_path : __DIR__ . '/../' . $file_path;
    if ($file_path === '' || !is_file($full_path)) {
        failFile(404, 'Fail lampiran tidak dijumpai.');
    }

    $filename = (string) (($attachment['original_name'] ?? '') ?: basename($file_path));
    $mime = mime_content_type($full_path) ?: 'application/octet-stream';
    header('Content-Type: ' . $mime);
    header('Content-Disposition: ' . ($download ? 'attachment' : 'inline') . '; filename="' . basename($filename) . '"');
    header('Content-Length: ' . filesize($full_path));
    readfile($full_path);
    exit;
}

checkApprovedUser($conn, $user_id);
$draft = fetchAccessibleDraft($conn, $draft_id, $user_id);
if (!$draft) {
    failFile(404, 'Surat tidak dijumpai atau tiada akses.');
}

if ($action === 'letter_pdf') {
    streamSimplePdf($draft, $download);
}

if ($action === 'attachment') {
    if ($attachment_id <= 0) {
        failFile(422, 'Lampiran tidak sah.');
    }
    streamAttachment($conn, $draft_id, $attachment_id, $download);
}

failFile(404, 'Fail tidak dijumpai.');
