<?php
require('fpdf.php');

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

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

$quoteId   = (int)($_GET['id'] ?? 0);
$bankParam = isset($_GET['bank']) ? $_GET['bank'] : 1;

if ($quoteId <= 0) {
    exit('Invalid quotation.');
}

/* -----------------------------
   Helpers
----------------------------- */
function pdf_txt($text)
{
    $text = (string)$text;
    if ($text === '') {
        return '';
    }
    $converted = @iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $text);
    return $converted !== false ? $converted : $text;
}

function money_fmt_pdf($amount)
{
    return number_format((float)$amount, 2);
}

function safe_date_fmt_pdf($date, $format = 'd M Y')
{
    if (!$date) return '';
    $ts = strtotime((string)$date);
    return $ts ? date($format, $ts) : (string)$date;
}

function quotation_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("
            SELECT COUNT(*)
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = DATABASE()
              AND TABLE_NAME = :table_name
              AND COLUMN_NAME = :column_name
        ");
        $stmt->execute([
            ':table_name'  => $table,
            ':column_name' => $column,
        ]);
        $cache[$key] = ((int)$stmt->fetchColumn() > 0);
    } catch (Throwable $e) {
        $cache[$key] = false;
    }

    return $cache[$key];
}


function quotation_table_exists(PDO $pdo, string $table): bool
{
    static $cache = [];
    $key = strtolower($table);

    if (array_key_exists($key, $cache)) {
        return $cache[$key];
    }

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

    return $cache[$key];
}

function quotation_first_existing_column(PDO $pdo, string $table, array $columns): string
{
    foreach ($columns as $column) {
        if (quotation_column_exists($pdo, $table, $column)) {
            return $column;
        }
    }
    return '';
}

/* -----------------------------
   Quotation data
----------------------------- */
$stmt = $pdo->prepare("
    SELECT
        q.*,
        p.name AS property_name,
        p.code AS property_code,
        p.currency_code AS property_currency_code,
        CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,'')) AS agent_name
    FROM reservation_quotes q
    LEFT JOIN properties p ON p.id = q.property_id
    LEFT JOIN agents a ON a.id = q.agent_id
    WHERE q.id = :id
    LIMIT 1
");
$stmt->execute([':id' => $quoteId]);
$q = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$q) {
    exit('Quotation not found.');
}

$propertyId = (int)($q['property_id'] ?? 0);

$guestName = trim((string)($q['guest_name'] ?? ''));
if ($guestName === '') {
    $guestName = 'Guest';
}

$agentName = trim((string)($q['agent_name'] ?? ''));
if ($agentName === '') {
    $agentName = 'Direct';
}

$quoteNo = trim((string)($q['quote_no'] ?? ''));
if ($quoteNo === '') {
    $quoteNo = 'QT-' . $quoteId;
}

$currency = trim((string)($q['currency'] ?? ''));
if ($currency === '') {
    $currency = trim((string)($q['property_currency_code'] ?? 'USD'));
}
if ($currency === '') {
    $currency = 'USD';
}

$propertyLabel = trim((string)($q['property_name'] ?? ''));
if (!empty($q['property_code'])) {
    $propertyLabel .= ($propertyLabel !== '' ? ' (' . $q['property_code'] . ')' : $q['property_code']);
}

/* -----------------------------
   Room rows
----------------------------- */
$stmt = $pdo->prepare("
    SELECT
        qr.*,
        rt.title AS room_type
    FROM reservation_quote_rooms qr
    LEFT JOIN room_types rt ON rt.id = qr.room_type_id
    WHERE qr.quote_id = :id
    ORDER BY qr.row_no ASC, qr.id ASC
");
$stmt->execute([':id' => $quoteId]);
$roomRows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

$roomMixParts = [];
$totalRooms = 0;
$totalAdults = 0;
$totalChildren = 0;

foreach ($roomRows as $r) {
    $roomType = trim((string)($r['room_type'] ?? ''));
    if ($roomType === '') {
        $roomType = !empty($r['room_type_id']) ? 'Room Type #' . (int)$r['room_type_id'] : 'Room Type';
    }

    $qtyRooms = (int)($r['qty_rooms'] ?? 0);
    $adults = (int)($r['adults'] ?? 0);
    $children = (int)($r['children'] ?? 0);

    $totalRooms += $qtyRooms;
    $totalAdults += $adults;
    $totalChildren += $children;

    if ($qtyRooms > 0) {
        $roomMixParts[] = $roomType . ' x ' . $qtyRooms;
    }
}

$roomMixSummary = $roomMixParts ? implode(', ', $roomMixParts) : 'Not set';

/* -----------------------------
   Nightly rows
----------------------------- */
$stmt = $pdo->prepare("
    SELECT
        stay_date,
        SUM(total) AS total
    FROM reservation_quote_prices
    WHERE quote_id = :id
    GROUP BY stay_date
    ORDER BY stay_date ASC
");
$stmt->execute([':id' => $quoteId]);
$nightRows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

$subtotal = (float)($q['subtotal'] ?? 0);
$discountAmount = (float)($q['discount_amount'] ?? 0);
$totalAmount = (float)($q['totalamount'] ?? 0);

if ($subtotal <= 0 && $nightRows) {
    foreach ($nightRows as $n) {
        $subtotal += (float)($n['total'] ?? 0);
    }
}
if ($totalAmount <= 0) {
    $totalAmount = max(0, $subtotal - $discountAmount);
}

$reservationNotes = trim((string)($q['reservation_notes'] ?? ''));
$terms = trim((string)($q['terms'] ?? ''));

/* -----------------------------
   Company profile
   Source: lodge_settings first, old tblmailinglist fallback.
----------------------------- */
$company = [
    'CompanyName'     => defined('APP_NAME') ? APP_NAME : 'RoomZ Lodge',
    'LegalName'       => '',
    'Postal'          => '',
    'Street'          => '',
    'City'            => '',
    'StateRegion'     => '',
    'Country'         => '',
    'Email'           => '',
    'Phone'           => '',
    'AltPhone'        => '',
    'Website'         => '',
    'VATNO'           => '',
    'TIN'             => '',
    'CompanyRegNo'    => '',
    'Motto'           => 'Reservations • Quotations • Hospitality',
    'QuotationPrefix' => 'QT',
    'LogoPath'        => '',
    'PaymentTerms'    => '',
    'Terms'           => '',
    'Footer'          => '',
];

$lodgeSettings = [];

try {
    $loadedCompany = false;

    if (quotation_table_exists($pdo, 'lodge_settings')) {
        try {
            $stmtLodge = $pdo->query("SELECT * FROM lodge_settings ORDER BY id ASC LIMIT 1");
            $lodgeSettings = $stmtLodge ? ($stmtLodge->fetch(PDO::FETCH_ASSOC) ?: []) : [];

            if ($lodgeSettings) {
                $lodgeName = trim((string)($lodgeSettings['lodge_name'] ?? ''));
                $legalName = trim((string)($lodgeSettings['legal_name'] ?? ''));

                $company['CompanyName'] = $legalName !== '' ? $legalName : ($lodgeName !== '' ? $lodgeName : $company['CompanyName']);
                $company['LegalName'] = $legalName;
                $company['Motto'] = trim((string)($lodgeSettings['tag_line'] ?? '')) !== ''
                    ? trim((string)$lodgeSettings['tag_line'])
                    : $company['Motto'];

                $company['Street'] = trim(implode(' ', array_filter([
                    (string)($lodgeSettings['address_line1'] ?? ''),
                    (string)($lodgeSettings['address_line2'] ?? ''),
                ], static function ($v) { return trim((string)$v) !== ''; })));

                $company['City'] = trim((string)($lodgeSettings['city'] ?? ''));
                $company['StateRegion'] = trim((string)($lodgeSettings['state_region'] ?? ''));
                $company['Country'] = trim((string)($lodgeSettings['country'] ?? ''));
                $company['Postal'] = trim((string)($lodgeSettings['postal_code'] ?? ''));
                $company['Email'] = trim((string)($lodgeSettings['email'] ?? ''));
                $company['Phone'] = trim((string)($lodgeSettings['phone'] ?? ''));
                $company['AltPhone'] = trim((string)($lodgeSettings['alt_phone'] ?? ''));
                $company['Website'] = trim((string)($lodgeSettings['website'] ?? ''));
                $company['VATNO'] = trim((string)($lodgeSettings['vat_number'] ?? ''));
                $company['TIN'] = trim((string)($lodgeSettings['tin_number'] ?? ''));
                $company['CompanyRegNo'] = trim((string)($lodgeSettings['company_reg_number'] ?? ''));
                $company['QuotationPrefix'] = trim((string)($lodgeSettings['reservation_prefix'] ?? '')) !== ''
                    ? trim((string)$lodgeSettings['reservation_prefix'])
                    : (trim((string)($lodgeSettings['invoice_prefix'] ?? '')) !== '' ? trim((string)$lodgeSettings['invoice_prefix']) : 'QT');
                $company['LogoPath'] = trim((string)($lodgeSettings['logo_path'] ?? ''));
                $company['PaymentTerms'] = trim((string)($lodgeSettings['payment_terms'] ?? ''));
                $company['Terms'] = trim((string)($lodgeSettings['terms_and_conditions'] ?? ''));
                $company['Footer'] = trim((string)($lodgeSettings['invoice_footer'] ?? ''));

                $loadedCompany = true;
            }
        } catch (Throwable $e) {
            $loadedCompany = false;
        }
    }

    if (!$loadedCompany) {
        $address = false;

        try {
            $stmtCompany = $pdo->prepare("
                SELECT *
                FROM tblmailinglist
                WHERE property_id = :property_id
                ORDER BY ID DESC
                LIMIT 1
            ");
            $stmtCompany->execute([':property_id' => $propertyId]);
            $address = $stmtCompany->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable $e) {
            $address = false;
        }

        if (!$address) {
            try {
                $qAddress = $pdo->query("SELECT * FROM tblmailinglist ORDER BY ID ASC LIMIT 1");
                $address = $qAddress ? $qAddress->fetch(PDO::FETCH_ASSOC) : false;
            } catch (Throwable $e) {
                $address = false;
            }
        }

        if ($address) {
            $company['CompanyName'] = $address['CompanyName'] ?: $company['CompanyName'];
            $company['Postal']     = $address['Postal'] ?? '';
            $company['Street']     = $address['Street'] ?? '';
            $company['City']       = $address['City'] ?? '';
            $company['Email']      = $address['Email'] ?? '';
            $company['Phone']      = $address['Phone'] ?? '';
            $company['Website']    = $address['Website'] ?? '';
            $company['VATNO']      = $address['VATNO'] ?? '';
            $company['TIN']        = $address['TIN'] ?? '';
            $company['Motto']      = $address['Motto'] ?: $company['Motto'];
        }
    }
} catch (Throwable $e) {
    // keep defaults
}

$propertyDisplay = trim((string)($q['property_name'] ?? ''));
if ($propertyDisplay !== '' && stripos((string)$company['CompanyName'], $propertyDisplay) === false) {
    // Keep the lodge_settings tag line unchanged, matching the proforma documents.
    $company['Motto'] = $company['Motto'];
}

/* -----------------------------
   Bank details
   Source: lodge_settings first, old tblbankdetails fallback.
----------------------------- */
$bankId = is_numeric($bankParam) ? (int)$bankParam : 1;
if ($bankId <= 0) {
    $bankId = 1;
}

$bankDetails = [
    'SwiftCode'   => '',
    'BranchCode'  => '',
    'Branch'      => '',
    'Bank'        => '',
    'AccountNo'   => '',
    'AccountName' => ''
];

try {
    $loadedBank = false;

    if (empty($lodgeSettings) && quotation_table_exists($pdo, 'lodge_settings')) {
        $stmtLodgeBank = $pdo->query("SELECT * FROM lodge_settings ORDER BY id ASC LIMIT 1");
        $lodgeSettings = $stmtLodgeBank ? ($stmtLodgeBank->fetch(PDO::FETCH_ASSOC) ?: []) : [];
    }

    if (!empty($lodgeSettings)) {
        $bankDetails['SwiftCode']   = trim((string)($lodgeSettings['bank_swift'] ?? ''));
        $bankDetails['BranchCode']  = '';
        $bankDetails['Branch']      = trim((string)($lodgeSettings['bank_branch'] ?? ''));
        $bankDetails['Bank']        = trim((string)($lodgeSettings['bank_name'] ?? ''));
        $bankDetails['AccountNo']   = trim((string)($lodgeSettings['bank_account_no'] ?? ''));
        $bankDetails['AccountName'] = trim((string)($lodgeSettings['bank_account_name'] ?? ''));
        $loadedBank = trim($bankDetails['Bank'] . $bankDetails['AccountName'] . $bankDetails['AccountNo']) !== '';
    }

    if (!$loadedBank) {
        $rowbank = false;

        try {
            $stmtBank = $pdo->prepare("
                SELECT *
                FROM tblbankdetails
                WHERE property_id = :property_id
                  AND ID = :id
                LIMIT 1
            ");
            $stmtBank->execute([
                ':property_id' => $propertyId,
                ':id' => $bankId,
            ]);
            $rowbank = $stmtBank->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable $e) {
            $rowbank = false;
        }

        if (!$rowbank) {
            try {
                $stmtBank = $pdo->prepare("
                    SELECT *
                    FROM tblbankdetails
                    WHERE property_id = :property_id
                    ORDER BY ID ASC
                    LIMIT 1
                ");
                $stmtBank->execute([':property_id' => $propertyId]);
                $rowbank = $stmtBank->fetch(PDO::FETCH_ASSOC);
            } catch (Throwable $e) {
                $rowbank = false;
            }
        }

        if (!$rowbank) {
            try {
                $stmtBank = $pdo->prepare("SELECT * FROM tblbankdetails WHERE ID = :id LIMIT 1");
                $stmtBank->execute([':id' => $bankId]);
                $rowbank = $stmtBank->fetch(PDO::FETCH_ASSOC);
            } catch (Throwable $e) {
                $rowbank = false;
            }
        }

        if ($rowbank) {
            $bankDetails['SwiftCode']   = $rowbank['SwiftCode'] ?? '';
            $bankDetails['BranchCode']  = $rowbank['BranchCode'] ?? '';
            $bankDetails['Branch']      = $rowbank['Branch'] ?? '';
            $bankDetails['Bank']        = $rowbank['Bank'] ?? '';
            $bankDetails['AccountNo']   = $rowbank['AccountNo'] ?? '';
            $bankDetails['AccountName'] = $rowbank['AccountName'] ?? '';
        }
    }
} catch (Throwable $e) {
    // keep defaults
}

/* -----------------------------
   PDF class - proforma-style layout
----------------------------- */
class PDF extends FPDF
{
    public $company = [];
    public $docTitle = 'QUOTATION';
    public $docRef = '';

function RoundedRect($x, $y, $w, $h, $r, $style = '')
{
    $k = $this->k;
    $hp = $this->h;

    if ($style == 'F') $op = 'f';
    elseif ($style == 'FD' || $style == 'DF') $op = 'B';
    else $op = 'S';

    $this->_out(sprintf('%.2F %.2F m', ($x+$r)*$k, ($hp-$y)*$k));

    // top line
    $this->_out(sprintf('%.2F %.2F l', ($x+$w-$r)*$k, ($hp-$y)*$k));
    $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c',
        ($x+$w-$r/2)*$k, ($hp-$y)*$k,
        ($x+$w)*$k, ($hp-($y+$r/2))*$k,
        ($x+$w)*$k, ($hp-($y+$r))*$k
    ));

    // right
    $this->_out(sprintf('%.2F %.2F l', ($x+$w)*$k, ($hp-($y+$h-$r))*$k));
    $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c',
        ($x+$w)*$k, ($hp-($y+$h-$r/2))*$k,
        ($x+$w-$r/2)*$k, ($hp-($y+$h))*$k,
        ($x+$w-$r)*$k, ($hp-($y+$h))*$k
    ));

    // bottom
    $this->_out(sprintf('%.2F %.2F l', ($x+$r)*$k, ($hp-($y+$h))*$k));
    $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c',
        ($x+$r/2)*$k, ($hp-($y+$h))*$k,
        $x*$k, ($hp-($y+$h-$r/2))*$k,
        $x*$k, ($hp-($y+$h-$r))*$k
    ));

    // left
    $this->_out(sprintf('%.2F %.2F l', $x*$k, ($hp-($y+$r))*$k));
    $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c',
        $x*$k, ($hp-($y+$r/2))*$k,
        ($x+$r/2)*$k, ($hp-$y)*$k,
        ($x+$r)*$k, ($hp-$y)*$k
    ));

    $this->_out($op);
}

    function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
    {
        $h = $this->h;
        $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ',
            $x1 * $this->k, ($h - $y1) * $this->k,
            $x2 * $this->k, ($h - $y2) * $this->k,
            $x3 * $this->k, ($h - $y3) * $this->k));
    }

    function Header()
    {
        // Header is drawn manually to match the proforma layout.
    }

    function Footer()
    {
        $this->SetY(-15);
        $this->SetDrawColor(196, 205, 214);
        $this->Line(10, $this->GetY(), 200, $this->GetY());
        $this->SetY(-11);
        $this->SetFont('Arial', '', 7.5);
        $this->SetTextColor(45, 55, 70);
        $this->Cell(95, 5, 'Prepared By: Reservations Department', 0, 0, 'L');
        $this->Cell(55, 5, 'Generated On: ' . date('d-M-Y H:i'), 0, 0, 'C');
        $this->Cell(40, 5, 'Page ' . $this->PageNo() . ' of {nb}', 0, 0, 'R');
    }

    function docTopBar(string $title, string $ref): void
    {
        $this->SetFillColor(36, 50, 66);
        $this->SetDrawColor(36, 50, 66);
        $this->RoundedRect(10, 8, 190, 12, 3, 'F');

        $this->SetTextColor(255, 255, 255);
        $this->SetFont('Arial', 'B', 14);
        $this->SetXY(18, 10.5);
        $this->Cell(90, 6, pdf_txt($title), 0, 0, 'L');

        $this->SetFont('Arial', 'B', 10);
        $this->SetXY(115, 10.8);
        $this->Cell(78, 6, pdf_txt('Ref: ' . $ref), 0, 0, 'R');
    }

    function card($x, $y, $w, $h, $title = ''): void
    {
        $this->SetFillColor(255, 255, 255);
        $this->SetDrawColor(157, 169, 184);
        $this->RoundedRect($x, $y, $w, $h, 3, 'D');

        if ($title !== '') {
            $this->SetFont('Arial', 'B', 8.5);
            $this->SetTextColor(18, 28, 43);
            $this->SetXY($x + 6, $y + 5);
            $this->Cell($w - 12, 5, pdf_txt($title), 0, 0, 'L');

            $this->SetDrawColor(222, 226, 232);
            $this->Line($x, $y + 13, $x + $w, $y + 13);
        }
    }

    function addRoomHeader(): void
    {
        $this->SetFillColor(36, 50, 66);
        $this->SetTextColor(255, 255, 255);
        $this->SetFont('Arial', 'B', 8.5);
        $this->SetX(10);
        $this->Cell(10, 8, '#', 0, 0, 'C', true);
        $this->Cell(98, 8, 'ROOM TYPE', 0, 0, 'L', true);
        $this->Cell(25, 8, 'ROOMS', 0, 0, 'C', true);
        $this->Cell(28, 8, 'ADULTS', 0, 0, 'C', true);
        $this->Cell(29, 8, 'CHILDREN', 0, 1, 'C', true);
    }

    function addNightHeader(): void
    {
        $this->SetFillColor(36, 50, 66);
        $this->SetTextColor(255, 255, 255);
        $this->SetFont('Arial', 'B', 8.5);
        $this->SetX(10);
        $this->Cell(10, 8, '#', 0, 0, 'C', true);
        $this->Cell(115, 8, 'STAY DATE', 0, 0, 'L', true);
        $this->Cell(65, 8, 'AMOUNT', 0, 1, 'R', true);
    }

    function checkPageSpace(float $needed): void
    {
        if ($this->GetY() + $needed > 266) {
            $this->AddPage();
            $this->SetY(18);
        }
    }
}

$pdf = new PDF();
$pdf->company = $company;
$pdf->docTitle = 'QUOTATION';
$pdf->docRef = $quoteNo;
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetAutoPageBreak(true, 18);

/* -----------------------------
   Top bar and company hero
----------------------------- */
$pdf->docTopBar('QUOTATION', $quoteNo);

$pdf->SetFillColor(255, 255, 255);
$pdf->SetDrawColor(157, 169, 184);
$pdf->RoundedRect(10, 20, 190, 48, 3, 'D');

$companyName = (string)($company['CompanyName'] ?? 'Company');

$pdf->SetTextColor(18, 28, 43);
$pdf->SetFont('Arial', 'B', 14);
$pdf->SetXY(16, 27);
$pdf->Cell(95, 6, pdf_txt($companyName), 0, 1, 'L');

$pdf->SetFont('Arial', 'I', 8.5);
$pdf->SetTextColor(75, 85, 99);
$pdf->SetX(16);
$pdf->Cell(95, 5, pdf_txt(trim((string)($company['Motto'] ?? 'Reservations | Quotations'))), 0, 1, 'L');

$pdf->SetTextColor(18, 28, 43);
$pdf->SetFont('Arial', '', 8.2);
$pdf->Ln(1);
$pdf->SetX(16);
$pdf->Cell(95, 4.7, pdf_txt(trim((string)($company['Street'] ?? ''))), 0, 1, 'L');
$pdf->SetX(16);
$companyAddressLine2 = trim(implode(' ', array_filter([
    (string)($company['Postal'] ?? ''),
    (string)($company['City'] ?? ''),
    (string)($company['StateRegion'] ?? ''),
    (string)($company['Country'] ?? ''),
], static function ($v) { return trim((string)$v) !== ''; })));
$pdf->Cell(95, 4.7, pdf_txt($companyAddressLine2), 0, 1, 'L');
$pdf->SetX(16);
$companyTelText = trim((string)($company['Phone'] ?? ''));
if (trim((string)($company['AltPhone'] ?? '')) !== '') {
    $companyTelText .= ($companyTelText !== '' ? ' / ' : '') . trim((string)$company['AltPhone']);
}
$pdf->Cell(95, 4.7, pdf_txt('Email: ' . (string)($company['Email'] ?? '') . '   Tel: ' . $companyTelText), 0, 1, 'L');
$pdf->SetX(16);
$companyTaxLineParts = [];
if (trim((string)($company['TIN'] ?? '')) !== '') {
    $companyTaxLineParts[] = 'TIN: ' . (string)$company['TIN'];
}
if (trim((string)($company['VATNO'] ?? '')) !== '') {
    $companyTaxLineParts[] = 'VAT: ' . (string)$company['VATNO'];
}
if (trim((string)($company['CompanyRegNo'] ?? '')) !== '') {
    $companyTaxLineParts[] = 'Reg No: ' . (string)$company['CompanyRegNo'];
}
$pdf->Cell(95, 4.7, pdf_txt(implode('   |   ', $companyTaxLineParts)), 0, 1, 'L');

$logoCandidates = [];
if (trim((string)($company['LogoPath'] ?? '')) !== '') {
    $configuredLogo = trim((string)$company['LogoPath']);
    if (preg_match('/^https?:\/\//i', $configuredLogo)) {
        $logoCandidates[] = $configuredLogo;
    } else {
        $logoCandidates[] = $configuredLogo;
        $logoCandidates[] = __DIR__ . '/' . ltrim($configuredLogo, '/');
        $logoCandidates[] = dirname(__DIR__, 2) . '/' . ltrim($configuredLogo, '/');
        if (!empty($_SERVER['DOCUMENT_ROOT'])) {
            $logoCandidates[] = rtrim((string)$_SERVER['DOCUMENT_ROOT'], '/') . '/' . ltrim($configuredLogo, '/');
        }
    }
}
$logoCandidates = array_merge($logoCandidates, [
    __DIR__ . '/att.png',
    __DIR__ . '/../../att.png',
    __DIR__ . '/../../assets/att.png',
    __DIR__ . '/../../assets/images/att.png',
    __DIR__ . '/../../uploads/att.png',
]);

foreach ($logoCandidates as $logo) {
    if ((preg_match('/^https?:\/\//i', (string)$logo)) || file_exists((string)$logo)) {
        $pdf->Image($logo, 128, 31, 58);
        break;
    }
}

/* -----------------------------
   Client and quotation summary cards
----------------------------- */
$cardY = 75;
$clientW = 70;
$summaryX0 = 85;
$summaryW = 115;

$pdf->card(10, $cardY, $clientW, 53, 'CLIENT / QUOTATION TO');

$pdf->SetTextColor(18, 28, 43);
$pdf->SetFont('Arial', 'B', 8.5);
$pdf->SetXY(14, $cardY + 17);
$pdf->MultiCell($clientW - 8, 4.7, pdf_txt($agentName), 0, 'L');

$pdf->SetFont('Arial', '', 7.8);
$pdf->SetXY(14, $cardY + 29);
$pdf->MultiCell($clientW - 8, 4.4, pdf_txt('Guest: ' . $guestName), 0, 'L');
$pdf->SetXY(14, $cardY + 38);
$pdf->MultiCell($clientW - 8, 4.4, pdf_txt('Property: ' . ($propertyLabel !== '' ? $propertyLabel : 'Not set')), 0, 'L');
$pdf->SetXY(14, $cardY + 47);
$pdf->SetFont('Arial', 'B', 7.8);
$pdf->Cell($clientW - 8, 4.5, pdf_txt('Currency: ' . $currency), 0, 1, 'L');

$pdf->card($summaryX0, $cardY, $summaryW, 53, 'QUOTATION SUMMARY');

$paxText = (int)$totalRooms . ' rooms | ' . (int)$totalAdults . 'A / ' . (int)$totalChildren . 'C';

$leftX = $summaryX0 + 6;
$rightX = $summaryX0 + 61;
$rowY = $cardY + 16;

$summaryLeft = [
    ['Quote No.', $quoteNo],
    ['Quote Date', safe_date_fmt_pdf($q['created_at'] ?? date('Y-m-d'), 'd-M-Y')],
    ['Status', (string)($q['status'] ?? 'Draft')],
];

$summaryRight = [
    ['Check In', safe_date_fmt_pdf($q['check_in'] ?? '', 'd-M-Y')],
    ['Check Out', safe_date_fmt_pdf($q['check_out'] ?? '', 'd-M-Y')],
    ['Property', (string)($q['property_code'] ?? '')],
];

for ($i = 0; $i < 3; $i++) {
    $y = $rowY + ($i * 8);
    $pdf->SetDrawColor(232, 236, 241);

    if ($i > 0) {
        $pdf->Line($summaryX0 + 4, $y - 1.5, $summaryX0 + $summaryW - 4, $y - 1.5);
    }

    $pdf->SetXY($leftX, $y);
    $pdf->SetFont('Arial', 'B', 7.5);
    $pdf->SetTextColor(18, 28, 43);
    $pdf->Cell(25, 5, pdf_txt($summaryLeft[$i][0]), 0, 0, 'L');
    $pdf->SetFont('Arial', '', 7.5);
    $pdf->Cell(25, 5, pdf_txt($summaryLeft[$i][1]), 0, 0, 'R');

    $pdf->SetXY($rightX, $y);
    $pdf->SetFont('Arial', 'B', 7.5);
    $pdf->Cell(22, 5, pdf_txt($summaryRight[$i][0]), 0, 0, 'L');
    $pdf->SetFont('Arial', '', 7.5);
    $pdf->Cell(28, 5, pdf_txt($summaryRight[$i][1]), 0, 0, 'R');
}

$pdf->SetFillColor(245, 247, 249);
$pdf->SetDrawColor(222, 226, 232);
$pdf->RoundedRect($summaryX0 + 5, $cardY + 42, $summaryW - 10, 8, 2, 'DF');
$pdf->SetXY($summaryX0 + 8, $cardY + 44);
$pdf->SetFont('Arial', 'B', 7.8);
$pdf->SetTextColor(18, 28, 43);
$pdf->Cell(20, 4, 'Pax', 0, 0, 'L');
$pdf->SetFont('Arial', '', 7.5);
$pdf->Cell($summaryW - 36, 4, pdf_txt($paxText), 0, 1, 'R');

/* -----------------------------
   Room mix line
----------------------------- */
$pdf->SetY(133);
$pdf->SetFont('Arial', 'B', 8.5);
$pdf->SetTextColor(18, 28, 43);
$pdf->Cell(25, 5, 'Room Mix:', 0, 0, 'L');

$pdf->SetFont('Arial', '', 8.3);
$pdf->MultiCell(165, 5, pdf_txt($roomMixSummary), 0, 'L');

$pdf->Ln(2);

/* -----------------------------
   Room mix table
----------------------------- */
$pdf->addRoomHeader();
$pdf->SetTextColor(18, 28, 43);
$pdf->SetFont('Arial', '', 8);

$idx = 1;
$fill = false;

if ($roomRows) {
    foreach ($roomRows as $r) {
        $pdf->checkPageSpace(12);

        $roomType = trim((string)($r['room_type'] ?? ''));
        if ($roomType === '') {
            $roomType = !empty($r['room_type_id']) ? 'Room Type #' . (int)$r['room_type_id'] : 'Room Type';
        }

        $qtyRooms = (int)($r['qty_rooms'] ?? 0);
        $adults = (int)($r['adults'] ?? 0);
        $children = (int)($r['children'] ?? 0);

        $rowY = $pdf->GetY();
        $descLines = max(1, ceil(strlen($roomType) / 62));
        $rowH = max(9, min(18, $descLines * 4.5));

        $pdf->SetFillColor($fill ? 248 : 255, $fill ? 250 : 255, $fill ? 252 : 255);
        $pdf->SetDrawColor(222, 226, 232);

        $pdf->SetX(10);
        $pdf->Cell(10, $rowH, (string)$idx, 1, 0, 'C', true);

        $xDesc = $pdf->GetX();
        $pdf->MultiCell(98, 4.5, pdf_txt($roomType), 1, 'L', true);

        $pdf->SetXY($xDesc + 98, $rowY);
        $pdf->Cell(25, $rowH, (string)$qtyRooms, 1, 0, 'C', true);
        $pdf->Cell(28, $rowH, (string)$adults, 1, 0, 'C', true);
        $pdf->Cell(29, $rowH, (string)$children, 1, 1, 'C', true);

        $fill = !$fill;
        $idx++;
    }
} else {
    $pdf->SetX(10);
    $pdf->Cell(190, 10, 'No room mix found.', 1, 1, 'C');
}

/* -----------------------------
   Nightly summary table
----------------------------- */
$pdf->Ln(5);
$pdf->SetFont('Arial', 'B', 8.5);
$pdf->SetTextColor(18, 28, 43);
$pdf->Cell(190, 5, 'Nightly Summary', 0, 1, 'L');

$pdf->addNightHeader();
$pdf->SetTextColor(18, 28, 43);
$pdf->SetFont('Arial', '', 8);

$idx = 1;
$fill = false;

if ($nightRows) {
    foreach ($nightRows as $n) {
        $pdf->checkPageSpace(10);

        $pdf->SetFillColor($fill ? 248 : 255, $fill ? 250 : 255, $fill ? 252 : 255);
        $pdf->SetDrawColor(222, 226, 232);

        $pdf->SetX(10);
        $pdf->Cell(10, 8, (string)$idx, 1, 0, 'C', true);
        $pdf->Cell(115, 8, pdf_txt(safe_date_fmt_pdf($n['stay_date'] ?? '', 'd-M-Y')), 1, 0, 'L', true);
        $pdf->Cell(65, 8, pdf_txt($currency . ' ' . money_fmt_pdf($n['total'] ?? 0)), 1, 1, 'R', true);

        $fill = !$fill;
        $idx++;
    }
} else {
    $pdf->SetX(10);
    $pdf->Cell(190, 10, 'No nightly prices found.', 1, 1, 'C');
}

/* -----------------------------
   Bank and totals grid
----------------------------- */
if ($pdf->GetY() > 205) {
    $pdf->AddPage();
    $pdf->SetY(18);
} else {
    $pdf->Ln(5);
}

$gridY = $pdf->GetY();
$bankH = 45;

$pdf->card(10, $gridY, 92, $bankH, 'BANK DETAILS - ALL PAYMENTS TO BE MADE TO');

$pdf->SetFont('Arial', '', 8);
$pdf->SetTextColor(18, 28, 43);

$by = $gridY + 16;
$bankRows = [
    ['Account Name', (string)$bankDetails['AccountName']],
    ['Account Number', (string)$bankDetails['AccountNo']],
    ['Bank', (string)$bankDetails['Bank']],
    ['Branch', (string)$bankDetails['Branch']],
    ['Swift', (string)$bankDetails['SwiftCode']],
    ['Currency', $currency],
];

foreach ($bankRows as $br) {
    $pdf->SetXY(14, $by);
    $pdf->SetFont('Arial', 'B', 7.7);
    $pdf->Cell(34, 5.5, pdf_txt($br[0]), 0, 0, 'L');
    $pdf->SetFont('Arial', '', 7.7);
    $pdf->Cell(49, 5.5, pdf_txt($br[1]), 0, 1, 'L');
    $by += 6;
}

$pdf->card(106, $gridY, 94, $bankH, '');

$tx = 112;
$ty = $gridY + 7;

$totRows = [
    ['Subtotal (' . $currency . ')', money_fmt_pdf($subtotal), false],
    ['Discount (' . $currency . ')', money_fmt_pdf($discountAmount), false],
    ['Quotation Total (' . $currency . ')', money_fmt_pdf($totalAmount), true],
];

foreach ($totRows as $tr) {
    $pdf->SetXY($tx, $ty);
    $pdf->SetFont('Arial', $tr[2] ? 'B' : '', 8.2);
    $pdf->SetTextColor(18, 28, 43);
    $pdf->Cell(45, 6, pdf_txt($tr[0]), 0, 0, 'L');
    $pdf->Cell(35, 6, pdf_txt($tr[1]), 0, 1, 'R');
    $ty += 6.5;
}

$pdf->SetFillColor(36, 50, 66);
$pdf->RoundedRect(106, $gridY + $bankH - 12, 94, 12, 2, 'F');

$pdf->SetTextColor(255, 255, 255);
$pdf->SetFont('Arial', 'B', 11);
$pdf->SetXY(112, $gridY + $bankH - 9.5);
$pdf->Cell(38, 7, 'TOTAL', 0, 0, 'L');

$pdf->SetFont('Arial', 'B', 12);
$pdf->Cell(44, 7, pdf_txt($currency . ' ' . money_fmt_pdf($totalAmount)), 0, 1, 'R');

/* -----------------------------
   Notes and terms
----------------------------- */
$notesY = $gridY + $bankH + 6;
$notesText = '';

if ($reservationNotes !== '') {
    $notesText .= "Notes:\n" . $reservationNotes . "\n\n";
}

if ($terms !== '') {
    $notesText .= "Terms:\n" . $terms;
} elseif (trim((string)($company['PaymentTerms'] ?? '')) !== '') {
    $notesText .= "Terms:\n" . trim((string)$company['PaymentTerms']);
} elseif (trim((string)($company['Terms'] ?? '')) !== '') {
    $notesText .= "Terms:\n" . trim((string)$company['Terms']);
} else {
    $notesText .= "Terms:\nThis quotation is subject to availability and confirmation. Kindly use the quotation number as reference when making payment.";
}

if (trim((string)($company['Footer'] ?? '')) !== '') {
    $notesText .= "\n\n" . trim((string)$company['Footer']);
}

$notesText = trim($notesText);
$lineCount = 0;
foreach (preg_split('/\R/', $notesText) as $noteLine) {
    $lineCount += max(1, (int)ceil(strlen((string)$noteLine) / 105));
}
$lineCount = max(3, $lineCount);
$notesH = max(30, 18 + ($lineCount * 4.6));
$maxNotesH = 245;
if ($notesH > $maxNotesH) {
    $notesH = $maxNotesH;
}

if ($notesY + $notesH > 270) {
    $pdf->AddPage();
    $notesY = 20;
}

$pdf->card(10, $notesY, 190, $notesH, 'NOTES / TERMS');
$pdf->SetXY(14, $notesY + 16);
$pdf->SetFont('Arial', '', 8);
$pdf->SetTextColor(18, 28, 43);
$pdf->MultiCell(182, 4.6, pdf_txt($notesText), 0, 'L');

$pdf->Output('Quotation_' . preg_replace('/[^A-Za-z0-9_\-]/', '_', $quoteNo) . '.pdf', 'I');
exit;
