<?php
/* guest_registration.php
 * One-page Pioneers-style guest registration + indemnity form.
 * - Matches attached customer layout.
 * - First 2 checked-in/registered guests show in Guest 1 and Guest 2 full detail area.
 * - Guests 3 and 4 show only as names in Additional Guests area.
 * - Designed to fit on ONE A4 page.
 */

require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$orderId   = (int)($_GET['order_id'] ?? 0);
$roomingId = (int)($_GET['rooming_id'] ?? 0);
$download  = (int)($_GET['download'] ?? 0) === 1;

if ($orderId <= 0) {
    die('Invalid booking selected.');
}

if (!function_exists('gr_e')) {
    function gr_e($value): string
    {
        return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('gr_date')) {
    function gr_date($value, string $format = 'd/m/Y'): string
    {
        if (!$value) return '';
        $ts = strtotime((string)$value);
        return $ts ? date($format, $ts) : (string)$value;
    }
}

if (!function_exists('gr_column_exists')) {
    function gr_column_exists(PDO $pdo, string $table, string $column): bool
    {
        static $cache = [];
        $key = $table . '.' . $column;
        if (array_key_exists($key, $cache)) return $cache[$key];

        try {
            $stmt = $pdo->prepare("\n                SELECT COUNT(*)\n                FROM INFORMATION_SCHEMA.COLUMNS\n                WHERE TABLE_SCHEMA = DATABASE()\n                  AND TABLE_NAME = :table_name\n                  AND COLUMN_NAME = :column_name\n            ");
            $stmt->execute([
                ':table_name' => $table,
                ':column_name' => $column,
            ]);
            $cache[$key] = ((int)$stmt->fetchColumn() > 0);
        } catch (Throwable $e) {
            $cache[$key] = false;
        }
        return $cache[$key];
    }
}

if (!function_exists('gr_first_existing_file')) {
    function gr_first_existing_file(array $paths): string
    {
        foreach ($paths as $path) {
            if ($path && is_file($path)) return $path;
        }
        return '';
    }
}

if (!function_exists('gr_guest_value')) {
    function gr_guest_value(array $guest, array $keys, string $fallback = ''): string
    {
        foreach ($keys as $key) {
            if (isset($guest[$key]) && trim((string)$guest[$key]) !== '') {
                return trim((string)$guest[$key]);
            }
        }
        return $fallback;
    }
}

if (!function_exists('gr_guest_full_name')) {
    function gr_guest_full_name(array $guest, string $fallback = ''): string
    {
        $name = trim((string)($guest['first_name'] ?? '') . ' ' . (string)($guest['last_name'] ?? ''));
        if ($name !== '') return $name;
        $name = trim((string)($guest['firstname'] ?? '') . ' ' . (string)($guest['lastname'] ?? ''));
        return $name !== '' ? $name : $fallback;
    }
}

$guestSelectExtra = [];
foreach ([
    'id_type', 'id_number', 'passport_no', 'passport_number', 'nationality',
    'gender', 'date_of_birth', 'phone', 'contact_no', 'mobile', 'email',
    'address', 'signature_data', 'registration_notes'
] as $col) {
    if (gr_column_exists($pdo, 'order_rooming_guests', $col)) {
        $guestSelectExtra[] = 'org.' . $col;
    }
}
$guestExtraSql = $guestSelectExtra ? ', ' . implode(', ', $guestSelectExtra) : '';

$stmt = $pdo->prepare("\n    SELECT\n        o.*,\n        g.firstname AS lead_firstname,\n        g.lastname AS lead_lastname,\n        g.email AS lead_email,\n        g.phone AS lead_phone,\n        p.name AS property_name,\n        p.code AS property_code,\n        p.address AS property_address,\n        p.phone AS property_phone,\n        p.email AS property_email,\n        rt.title AS booking_room_type,\n        CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,'')) AS agent_name\n    FROM orders o\n    LEFT JOIN guests g ON g.id = o.guest_id\n    LEFT JOIN properties p ON p.id = o.property_id\n    LEFT JOIN room_types rt ON rt.id = o.room_type_id\n    LEFT JOIN agents a ON a.id = o.agent_id\n    WHERE o.id = :id\n    LIMIT 1\n");
$stmt->execute([':id' => $orderId]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$order) {
    die('Booking not found.');
}

$params = [':order_id' => $orderId];
$roomingFilter = '';
if ($roomingId > 0) {
    $roomingFilter = ' AND rmg.id = :rooming_id ';
    $params[':rooming_id'] = $roomingId;
}

$stmt = $pdo->prepare("\n    SELECT\n        rmg.*,\n        rm.room_no AS actual_room_no,\n        rm.status AS room_status,\n        rt.title AS room_type_title\n    FROM order_rooming rmg\n    LEFT JOIN rooms rm ON rm.id = rmg.room_id\n    LEFT JOIN room_types rt ON rt.id = rmg.room_type_id\n    WHERE rmg.order_id = :order_id\n    $roomingFilter\n    ORDER BY rmg.room_no ASC, rmg.id ASC\n");
$stmt->execute($params);
$roomingRows = $stmt->fetchAll(PDO::FETCH_ASSOC);

if (!$roomingRows) {
    die('No room registration records found for this booking.');
}

$roomingIds = array_map(static fn($r) => (int)$r['id'], $roomingRows);
$placeholders = implode(',', array_fill(0, count($roomingIds), '?'));

$guestRows = [];
$stmt = $pdo->prepare("\n    SELECT\n        org.id,\n        org.order_id,\n        org.rooming_id,\n        org.first_name,\n        org.last_name,\n        org.is_primary,\n        org.checked_in_at,\n        org.checked_out_at\n        $guestExtraSql\n    FROM order_rooming_guests org\n    WHERE org.rooming_id IN ($placeholders)\n    ORDER BY org.rooming_id ASC, org.is_primary DESC, org.id ASC\n");
$stmt->execute($roomingIds);
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $guest) {
    $guestRows[] = $guest;
}

if (!$guestRows) {
    $guestRows[] = [
        'first_name' => (string)($order['lead_firstname'] ?? ''),
        'last_name'  => (string)($order['lead_lastname'] ?? ''),
        'email'      => (string)($order['lead_email'] ?? ''),
        'phone'      => (string)($order['lead_phone'] ?? ''),
        'is_primary' => 1,
    ];
}

$guestRows = array_values($guestRows);
$guest1 = $guestRows[0] ?? [];
$guest2 = $guestRows[1] ?? [];
$additionalGuests = array_slice($guestRows, 2, 2);

$roomNos = [];
foreach ($roomingRows as $room) {
    $roomNo = trim((string)($room['actual_room_no'] ?? ''));
    if ($roomNo === '') $roomNo = trim((string)($room['room_no'] ?? ''));
    if ($roomNo !== '') $roomNos[] = $roomNo;
}
$roomNoLabel = implode(', ', array_values(array_unique($roomNos)));

$checkInDate = $roomingRows[0]['check_in'] ?? ($order['check_in'] ?? '');
$checkOutDate = $roomingRows[0]['check_out'] ?? ($order['check_out'] ?? '');

$tcpdfPaths = [
    __DIR__ . '/../../vendor/tecnickcom/tcpdf/tcpdf.php',
    __DIR__ . '/../../../vendor/tecnickcom/tcpdf/tcpdf.php',
    __DIR__ . '/../../vendor/autoload.php',
    __DIR__ . '/../../../vendor/autoload.php',
    __DIR__ . '/../../tcpdf/tcpdf.php',
    __DIR__ . '/../../../tcpdf/tcpdf.php',
    __DIR__ . '/../../includes/tcpdf/tcpdf.php',
    __DIR__ . '/../../../includes/tcpdf/tcpdf.php',
    $_SERVER['DOCUMENT_ROOT'] . '/tcpdf/tcpdf.php',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/tcpdf/tcpdf.php',
];

$tcpdfFile = gr_first_existing_file($tcpdfPaths);
if ($tcpdfFile === '') {
    die('TCPDF not found. Please install TCPDF or check the path.');
}
require_once $tcpdfFile;

class OnePageGuestRegistrationPdf extends TCPDF
{
    public function Header() {}
    public function Footer() {}
}

$pdf = new OnePageGuestRegistrationPdf('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetCreator('Rooms PMS');
$pdf->SetAuthor((string)($order['property_name'] ?? 'Pioneers Lodge'));
$pdf->SetTitle('Guest Registration - ' . ($order['order_no'] ?: $orderId));
$pdf->SetSubject('Guest Registration Form');
$pdf->SetMargins(6, 6, 6);
$pdf->SetAutoPageBreak(false, 0);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetTextColor(0, 0, 0);
$pdf->SetDrawColor(0, 0, 0);
$pdf->SetLineWidth(0.18);

$logoPath = gr_first_existing_file([
    __DIR__ . '/../../assets/img/pioneers-logo.png',
    __DIR__ . '/../../assets/images/pioneers-logo.png',
    __DIR__ . '/../../assets/pioneers-logo.png',
    __DIR__ . '/../../assets/img/company-logo.png',
    __DIR__ . '/../../assets/images/logo.png',
    __DIR__ . '/../../assets/logo.png',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/assets/img/pioneers-logo.png',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/assets/images/pioneers-logo.png',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/assets/img/logo.png',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/assets/images/logo.png',
    $_SERVER['DOCUMENT_ROOT'] . '/rooms/assets/logo.png',
]);

if ($logoPath !== '') {
    try { $pdf->Image($logoPath, 8, 7, 48, 0, '', '', '', false, 300); } catch (Throwable $e) {}
} else {
    $pdf->SetXY(8, 7);
    $pdf->SetFont('helvetica', 'B', 18);
    $pdf->Cell(56, 8, 'PIONEERS', 0, 1, 'L');
    $pdf->SetX(8);
    $pdf->SetFont('helvetica', 'I', 9);
    $pdf->Cell(56, 4, 'Victoria Falls', 0, 1, 'C');
}

function gr_line_value(TCPDF $pdf, float $x, float $y, string $label, string $value, float $labelW, float $lineW, float $font = 8.0): void
{
    $pdf->SetXY($x, $y);
    $pdf->SetFont('helvetica', 'B', $font);
    $pdf->Cell($labelW, 4, $label, 0, 0, 'L');
    $lineX = $x + $labelW;
    $lineY = $y + 3.2;
    $pdf->Line($lineX, $lineY, $lineX + $lineW, $lineY);
    if (trim($value) !== '') {
        $pdf->SetXY($lineX + 1, $y - 0.2);
        $pdf->SetFont('helvetica', '', $font);
        $pdf->Cell($lineW - 2, 4, $value, 0, 0, 'C');
    }
}

function gr_guest_block(TCPDF $pdf, float $y, string $title, array $guest): void
{
    $fullName = gr_guest_full_name($guest, '');
    $passport = gr_guest_value($guest, ['passport_no', 'passport_number', 'id_number']);
    $nationality = gr_guest_value($guest, ['nationality']);
    $contact = gr_guest_value($guest, ['phone', 'contact_no', 'mobile']);
    $address = gr_guest_value($guest, ['address']);
    $email = gr_guest_value($guest, ['email']);

    $pdf->SetFont('helvetica', 'B', 8.2);
    $pdf->SetXY(8, $y);
    $pdf->Cell(30, 4, $title, 0, 1, 'L');
    $pdf->Line(8, $y + 4.2, 27, $y + 4.2);

    gr_line_value($pdf, 8, $y + 7, 'Full Name:', $fullName, 19, 72, 8.0);
    gr_line_value($pdf, 101, $y + 7, 'Passport #:', $passport, 21, 78, 8.0);
    gr_line_value($pdf, 8, $y + 14, 'Nationality:', $nationality, 22, 69, 8.0);
    gr_line_value($pdf, 101, $y + 14, 'Contact #:', $contact, 20, 79, 8.0);
    gr_line_value($pdf, 8, $y + 21, 'Address:', $address, 15, 177, 8.0);
    gr_line_value($pdf, 8, $y + 28, 'Email address:', $email, 26, 166, 8.0);
}

$pdf->SetFont('helvetica', 'B', 8.2);
gr_line_value($pdf, 132, 7, 'Date:', date('d/m/Y'), 12, 55, 8.0);
gr_line_value($pdf, 132, 16, 'Room Number:', $roomNoLabel, 27, 40, 8.0);
gr_line_value($pdf, 8, 31, 'Arrival Date:', gr_date($checkInDate), 23, 50, 8.0);
gr_line_value($pdf, 107, 31, 'Departure Date:', gr_date($checkOutDate), 29, 64, 8.0);

gr_guest_block($pdf, 40, 'Guest 1', $guest1);
gr_guest_block($pdf, 78, 'Guest 2', $guest2);

$pdf->SetFont('helvetica', 'B', 8.2);
$pdf->SetXY(8, 116);
$pdf->Cell(40, 4, 'Additional Guests:', 0, 1, 'L');
$pdf->Line(8, 120.2, 38, 120.2);
$add1 = isset($additionalGuests[0]) ? gr_guest_full_name($additionalGuests[0]) : '';
$add2 = isset($additionalGuests[1]) ? gr_guest_full_name($additionalGuests[1]) : '';
gr_line_value($pdf, 8, 124, 'Name:', $add1, 12, 78, 8.0);
gr_line_value($pdf, 101, 124, 'Name:', $add2, 12, 87, 8.0);

$html = '
<style>
    h3{
        font-size:7.8px;
        text-align:center;
        text-decoration:underline;
        margin:0 0 6px 0;
        font-weight:bold;
    }

    table{
        font-size:6.4px;
        line-height:1.42;
    }

    td.no{
        width:8%;
        font-weight:bold;
        vertical-align:top;
        padding-top:2px;
        padding-bottom:2px;
    }

    td.txt{
        width:92%;
        vertical-align:top;
        padding-top:2px;
        padding-bottom:2px;
    }

    .section{
        font-weight:bold;
        text-decoration:underline;
    }

    p{
        font-size:6.4px;
        line-height:1.42;
        margin:4px 0 0 0;
    }
</style>
<h3>Pioneers Lodge (Private) trading as Pioneers Lodge - DISCLAIMER &amp; INDEMNITY</h3>
<table cellpadding="0.7" cellspacing="0">
<tr><td class="no">1.</td><td class="txt section">Introduction</td></tr>
<tr><td class="no">1.1</td><td class="txt">Pioneers Lodge (PVT) Ltd, Registration Number 241/2019 (&quot;the Company&quot;) operates the Pioneers Lodge (&quot;the Lodge&quot;) and conducts the activities described herein for guests.</td></tr>
<tr><td class="no">1.2</td><td class="txt">The guest and members of the guest\'s party (including any minor children), whose names and particulars appears both on the registration form, will be accommodated at the Lodge and will utilize the facilities and grounds of the Lodge, and may book activities from the lodge activities desk, subject to the terms and conditions set out herein.</td></tr>
<tr><td class="no">2.</td><td class="txt section">Disclaimer and Indemnity</td></tr>
<tr><td class="no">2.1</td><td class="txt">The Company and its shareholders, directors, employees and representatives (collectively referred to as &quot;the Indemnified Parties&quot;), are not liable for any loss or damage to any property of the Guest/s or injury to or death of the Guest/s, howsoever arising, even if such loss, damage, injury or death has been occasioned by the negligence (including gross negligence) of one or more of the Indemnified Parties.</td></tr>
<tr><td class="no">2.2</td><td class="txt">The Guest/s partakes in the Activities entirely at the Guest/s\'s own risk.</td></tr>
<tr><td class="no">2.3</td><td class="txt">The Guest/s accordingly waive all claims of any nature whatsoever which the Guest/s or his/her deceased estate (&quot;Estate&quot;) may have against the Indemnified Parties, arising from the death of or injury or the loss of or damage to any Guest\'s property, even if such death or injury or loss or damage has been occasioned by negligence (including gross negligence) of the Indemnified Parties. The Guest/s hereby indemnifies and holds harmless each of the Indemnified Parties against all loss or damage arising from any claim which may be brought against any one of them by any of the Guest/s\' dependants, in respect of any such death, injury, loss or damage.</td></tr>
<tr><td class="no">2.4</td><td class="txt">The Guest/s acknowledges that participation in the Activities will expose the Guest/s to various risks and dangers inherent in or directly or indirectly associated with the Activities.</td></tr>
<tr><td class="no">2.5</td><td class="txt">The Guest/s further acknowledges that:</td></tr>
<tr><td class="no">2.5.1</td><td class="txt">The Guest/s is obliged to exercise his/her own independent judgement in participating in the Activities and evaluating the Risks.</td></tr>
<tr><td class="no">2.5.2</td><td class="txt">It is not possible for the Indemnified Parties to give any representation or warranty, whether expressed or implied, that the Risks will not materialise, even when the Activities are undertaken with the supervision of a trained guide/s or in accordance with the Company guidelines.</td></tr>
<tr><td class="no">2.5.3</td><td class="txt">In the event of any accident or injury, the Indemnified Parties:</td></tr>
<tr><td class="no">2.5.3.1</td><td class="txt">shall provide the immediate first aid treatment of the Guest/s and the evacuation/transfer of the Guest/s to the nearest available medical care center/doctor, which medical care center/doctor may be remote and during evacuation, proper medical assistance may be limited or non-existent;</td></tr>
<tr><td class="no">2.5.3.2</td><td class="txt">may (in their sole discretion) meet with some of the medical treatment/transfers/accommodation costs of the Guest/s occasioned by the accident or injury, which payment/s shall be a voluntary gesture in good faith without any admission of liability on part of the Indemnified Parties and without prejudice to any of the Indemnified Parties\' rights in terms hereof, or otherwise in law.</td></tr>
<tr><td class="no">2.5.4</td><td class="txt">This disclaimer and indemnity will be binding on the Guest\'s Estate.</td></tr>
<tr><td class="no">2.5.5</td><td class="txt">If any term or provision of this agreement is found to be illegal or unenforceable then such term shall be severable and the remaining terms and provisions hereof shall be and remain binding and of full force and effect.</td></tr>
</table>
<p>The Guest/s warrants that the Guest/s is in a sufficiently good physical and mental condition to take part in the Activities</p>';

$pdf->writeHTMLCell(196, 0, 7, 134, $html, 0, 1, false, true, 'L', true);

$signatureY = 291;
$pdf->SetFont('helvetica', 'B', 6.8);
gr_line_value($pdf, 8, $signatureY, 'Guest 1 Signature:', '', 27, 60, 6.8);
gr_line_value($pdf, 106, $signatureY, 'Guest 2 Signature:', '', 27, 60, 6.8);

$filename = 'guest_registration_one_page_' . preg_replace('/[^A-Za-z0-9_-]/', '_', (string)($order['order_no'] ?: $orderId)) . '.pdf';
$pdf->Output($filename, $download ? 'D' : 'I');
exit;
