<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/layout.php';

require_permission($conn, 'bill_management');

ensure_order_branch_column($conn);
ensure_order_return_column($conn);
ensure_order_bill_number_column($conn);
ensure_order_source_column($conn);
ensure_payment_tender_columns($conn);
ensure_car_profile_columns($conn);

function bill_management_date_value(string $value, string $default): string
{
    $timestamp = strtotime($value);

    if ($timestamp === false) {
        return $default;
    }

    return date('Y-m-d', $timestamp);
}

function bill_management_month_value(string $value, string $default): string
{
    if (!preg_match('/^\d{4}-\d{2}$/', $value)) {
        return $default;
    }

    $timestamp = strtotime($value . '-01');

    if ($timestamp === false) {
        return $default;
    }

    return date('Y-m', $timestamp);
}

function bill_management_source_label(string $orderSource): string
{
    return $orderSource === 'quick_service'
        ? localized_text_value('ควิกเซอร์วิส', 'Quick Service')
        : localized_text_value('งานจอง', 'Booking');
}

function bill_management_branch_label(string $branchName): string
{
    $branchName = trim($branchName);

    if ($branchName === '' || $branchName === 'No branch') {
        return localized_text_value('ไม่ระบุสาขา', 'No branch');
    }

    return $branchName;
}

$allowedPeriods = array('day', 'month');
$period = trim((string) ($_GET['period'] ?? 'month'));
if (!in_array($period, $allowedPeriods, true)) {
    $period = 'month';
}

$today = date('Y-m-d');
$currentMonth = date('Y-m');
$hasRequestedBills = (string) ($_GET['load'] ?? '') === '1';
$dateValue = bill_management_date_value((string) ($_GET['date'] ?? $today), $today);
$monthValue = bill_management_month_value((string) ($_GET['month'] ?? $currentMonth), $currentMonth);
$searchQuery = trim((string) ($_GET['search'] ?? ''));

if ($period === 'day') {
    $startAt = $dateValue . ' 00:00:00';
    $endAt = date('Y-m-d 00:00:00', strtotime($startAt . ' +1 day'));
    $periodLabel = date('d/m/Y', strtotime($startAt));
} else {
    $startAt = date('Y-m-01 00:00:00', strtotime($monthValue . '-01'));
    $endAt = date('Y-m-d 00:00:00', strtotime($startAt . ' +1 month'));
    $periodLabel = localized_year_month_label($startAt);
}

$branchNames = authorized_order_branch_options($conn);
$branchFilter = trim((string) ($_GET['branch_name'] ?? ''));
if ($branchFilter !== '' && !in_array($branchFilter, $branchNames, true)) {
    $branchFilter = '';
}

$rows = array();

if ($hasRequestedBills) {
    $where = array(
        'o.order_date >= ?',
        'o.order_date < ?',
    );
    $types = 'ss';
    $params = array($startAt, $endAt);

    $branchAccessCondition = auth_branch_condition($conn, 'o', $types, $params);
    if ($branchAccessCondition !== '') {
        $where[] = $branchAccessCondition;
    }

    if ($branchFilter !== '') {
        $where[] = 'o.branch_name = ?';
        $types .= 's';
        $params[] = $branchFilter;
    }

    if ($searchQuery !== '') {
        $searchBill = '%' . $searchQuery . '%';
        $normalizedPlate = '%' . normalize_plate($searchQuery) . '%';
        $normalizedPhone = normalize_phone($searchQuery);
        $searchWhere = array(
            'o.bill_number LIKE ?',
            'CAST(o.order_id AS CHAR) LIKE ?',
            "REPLACE(UPPER(car.plate_number), ' ', '') LIKE ?",
        );

        $types .= 'sss';
        $params[] = $searchBill;
        $params[] = $searchBill;
        $params[] = $normalizedPlate;

        if ($normalizedPhone !== '') {
            $searchWhere[] = 'c.normalized_phone = ?';
            $types .= 's';
            $params[] = $normalizedPhone;
        }

        $where[] = '(' . implode(' OR ', $searchWhere) . ')';
    }

    $whereSql = implode(' AND ', $where);
    $stmt = db_prepare($conn, "
        SELECT
            o.order_id,
            o.bill_number,
            o.order_date,
            o.branch_name,
            o.return_at,
            o.status,
            o.payment_status,
            o.order_source,
            o.total_price,
            o.cancelled_at,
            c.name AS customer_name,
            c.phone,
            car.plate_number,
            car.province,
            car.brand,
            car.model,
            car.profile_image_path,
            car.profile_image_name
        FROM orders o FORCE INDEX (idx_orders_report_period)
        STRAIGHT_JOIN customers c ON c.customer_id = o.customer_id
        STRAIGHT_JOIN cars car ON car.car_id = o.car_id
        WHERE {$whereSql}
        ORDER BY o.order_date DESC, o.order_id DESC
    ");
    $stmt->bind_param($types, ...$params);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
    }
    $stmt->close();

    $orderIds = array_column($rows, 'order_id');
    $serviceSummaryMap = order_service_summary_map($conn, $orderIds);
    $paymentSummaryMap = order_payment_summary_map($conn, $orderIds);

    foreach ($rows as &$row) {
        $orderId = (int) ($row['order_id'] ?? 0);
        $serviceSummary = $serviceSummaryMap[$orderId] ?? array();
        $paymentSummary = $paymentSummaryMap[$orderId] ?? order_payment_summary_defaults();
        $row['service_names'] = (string) ($serviceSummary['service_names'] ?? '');
        $row['item_count'] = (int) ($serviceSummary['item_count'] ?? 0);
        $row['paid_amount'] = (float) ($paymentSummary['total_amount'] ?? 0);
        $row['last_payment_at'] = $paymentSummary['last_payment_at'] ?? null;
    }
    unset($row);
}

$summary = array(
    'total_bills' => count($rows),
    'paid_bills' => 0,
    'partial_bills' => 0,
    'unpaid_bills' => 0,
    'cancelled_bills' => 0,
    'sale_amount' => 0.0,
    'paid_amount' => 0.0,
);

foreach ($rows as $row) {
    $paymentStatus = (string) ($row['payment_status'] ?? 'unpaid');
    $status = (string) ($row['status'] ?? 'waiting');

    $summary['sale_amount'] += (float) ($row['total_price'] ?? 0);
    $summary['paid_amount'] += (float) ($row['paid_amount'] ?? 0);

    if ($status === 'cancelled') {
        $summary['cancelled_bills']++;
    }

    if ($paymentStatus === 'paid') {
        $summary['paid_bills']++;
    } elseif ($paymentStatus === 'partial') {
        $summary['partial_bills']++;
    } else {
        $summary['unpaid_bills']++;
    }
}

$canCancelClosedBill = can_access($conn, 'queue_cancel_closed');
$canCancelOpenBill = can_access($conn, 'queue_cancel_open');
$canCancelWaiting = can_access($conn, 'queue_cancel_waiting');
$returnTo = current_page_return('bill_management.php');

$pageTitle = localized_text_value('จัดการบิล', 'Bill Management');
$pageDescription = localized_text_value('ตรวจสอบบิลตามวันหรือเดือน ค้นหาจากเลขที่บิล ทะเบียนรถ หรือเบอร์โทร แล้วเปิดรายละเอียด พิมพ์ซ้ำ หรือยกเลิกได้ตามสิทธิ์', 'Review bills by day or month, search by bill number, plate number or phone number, then open bill details, reprint or cancel when permitted.');
$manageSystemLabel = localized_text_value('จัดการระบบ', 'Manage System');
$backToDashboardLabel = localized_text_value('กลับหน้าแดชบอร์ด', 'Back to dashboard');
$billFiltersTitle = localized_text_value('ตัวกรองบิล', 'Bill filters');
$billFiltersHelper = localized_text_value('กรองรายการบิลตามช่วงเวลาและสาขา แล้วค้นหาบิล ทะเบียนรถ หรือเบอร์โทรลูกค้าที่ต้องการ', 'Filter the bill list by selected period and branch, then search specific bills, plates or customer phones.');
$viewByLabel = localized_text_value('ดูตาม', 'View by');
$dailyLabel = localized_text_value('รายวัน', 'Daily');
$monthlyLabel = localized_text_value('รายเดือน', 'Monthly');
$dailyDateLabel = localized_text_value('วันที่', 'Daily date');
$monthlyPeriodLabel = localized_text_value('รอบเดือน', 'Monthly period');
$branchLabel = localized_text_value('สาขา', 'Branch');
$allAccessibleBranchesLabel = localized_text_value('ทุกสาขาที่เข้าถึงได้', 'All accessible branches');
$searchLabel = localized_text_value('ค้นหา', 'Search');
$searchPlaceholder = localized_text_value('เลขที่บิล / ทะเบียน / เบอร์โทร', 'Bill no. / Plate / Phone');
$viewBillsLabel = localized_text_value('ดูบิล', 'View bills');
$resetLabel = localized_text_value('รีเซ็ต', 'Reset');
$currentScopeLabel = localized_text_value('ขอบเขตปัจจุบัน', 'Current scope');
$periodScopeLabel = localized_text_value('ช่วงเวลา', 'Period');
$branchScopeLabel = localized_text_value('สาขา', 'Branch');
$searchScopeLabel = localized_text_value('ค้นหา', 'Search');
$billsStatLabel = localized_text_value('จำนวนบิล', 'Bills');
$paidPartialUnpaidLabel = localized_text_value('ชำระครบ / บางส่วน / ยังไม่ชำระ', 'Paid / Partial / Unpaid');
$cancelledLabel = localized_text_value('ยกเลิก', 'Cancelled');
$paidReceivedLabel = localized_text_value('ยอดรับชำระ', 'Paid received');
$billListTitle = localized_text_value('รายการบิล', 'Bill list');
$billCountLabel = localized_text_value('{count} บิล', '{count} bill(s)');
$useViewBillsListLabel = localized_text_value('กดดูบิลเพื่อโหลดรายการบิล', 'Use View bills to load the bill list.');
$useViewBillsDataLabel = localized_text_value('กดดูบิลเพื่อโหลดข้อมูลตามช่วงเวลาและสาขาที่เลือก', 'Use View bills to load data for the selected period and branch.');
$noBillsFoundLabel = localized_text_value('ไม่พบบิลตามตัวกรองที่เลือก', 'No bills found for the selected filters.');
$dateColumnLabel = localized_text_value('วันที่', 'Date');
$billColumnLabel = localized_text_value('บิล', 'Bill');
$customerColumnLabel = localized_text_value('ลูกค้า', 'Customer');
$vehicleColumnLabel = localized_text_value('รถ', 'Vehicle');
$servicesColumnLabel = localized_text_value('บริการ', 'Services');
$statusColumnLabel = localized_text_value('สถานะ', 'Status');
$paymentColumnLabel = localized_text_value('การชำระเงิน', 'Payment');
$totalColumnLabel = localized_text_value('รวม', 'Total');
$paidColumnLabel = localized_text_value('ชำระแล้ว', 'Paid');
$balanceColumnLabel = localized_text_value('คงเหลือ', 'Balance');
$actionColumnLabel = localized_text_value('การทำรายการ', 'Action');
$pickupDueLabel = localized_text_value('กำหนดรับรถ', 'Pickup due');
$vehiclePendingLabel = localized_text_value('ยังไม่มีรายละเอียดรถ', 'Vehicle details pending');
$itemCountLabel = localized_text_value('{count} รายการ', '{count} item(s)');
$viewLabel = localized_text_value('ดู', 'View');
$reprintLabel = localized_text_value('พิมพ์ซ้ำ', 'Reprint');
$cancelActionLabel = localized_text_value('ยกเลิก', 'Cancel');

render_page_start($pageTitle, 'bill_management', array('translation_buffer' => false));
?>

<section class="page-hero">
    <div>
        <h1><?= e($pageTitle) ?></h1>
        <p><?= e($pageDescription) ?></p>
    </div>
    <div class="hero-actions">
        <a class="button button-secondary" href="manage_system.php"><?= e($manageSystemLabel) ?></a>
        <a class="button button-secondary" href="dashboard.php"><?= e($backToDashboardLabel) ?></a>
    </div>
</section>

<section class="content-grid bill-management-filter-grid">
    <form class="form-card bill-management-filter-card" method="GET">
        <input type="hidden" name="load" value="1">
        <div class="section-head">
            <div>
                <h2 class="section-title"><?= e($billFiltersTitle) ?></h2>
                <p class="helper"><?= e($billFiltersHelper) ?></p>
            </div>
        </div>

        <div class="form-grid">
            <div class="field">
                <label for="period"><?= e($viewByLabel) ?></label>
                <select id="period" name="period">
                    <option value="day"<?= $period === 'day' ? ' selected' : '' ?>><?= e($dailyLabel) ?></option>
                    <option value="month"<?= $period === 'month' ? ' selected' : '' ?>><?= e($monthlyLabel) ?></option>
                </select>
            </div>

            <?php if ($period === 'day'): ?>
                <div class="field">
                    <label for="date"><?= e($dailyDateLabel) ?></label>
                    <input id="date" name="date" type="date" value="<?= e($dateValue) ?>">
                </div>
            <?php else: ?>
                <div class="field">
                    <label for="month"><?= e($monthlyPeriodLabel) ?></label>
                    <?= render_month_picker('month', 'month', $monthValue, $monthlyPeriodLabel) ?>
                </div>
            <?php endif; ?>

            <div class="field">
                <label for="branch_name"><?= e($branchLabel) ?></label>
                <select id="branch_name" name="branch_name">
                    <option value=""><?= e($allAccessibleBranchesLabel) ?></option>
                    <?php foreach ($branchNames as $branchName): ?>
                        <option value="<?= e($branchName) ?>"<?= $branchFilter === $branchName ? ' selected' : '' ?>><?= e($branchName) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>

            <div class="field">
                <label for="search"><?= e($searchLabel) ?></label>
                <input
                    id="search"
                    name="search"
                    type="search"
                    value="<?= e($searchQuery) ?>"
                    placeholder="<?= e($searchPlaceholder) ?>"
                >
            </div>
        </div>

        <div class="actions service-management-filter-actions">
            <button class="button button-accent" type="submit"><?= e($viewBillsLabel) ?></button>
            <a class="button button-ghost" href="bill_management.php"><?= e($resetLabel) ?></a>
        </div>
    </form>

    <aside class="card summary-panel bill-management-summary-panel">
        <h2 class="section-title"><?= e($currentScopeLabel) ?></h2>
        <div class="stack">
            <span class="muted"><?= e($periodScopeLabel) ?></span>
            <strong><?= e($periodLabel) ?></strong>
            <span class="muted"><?= e($branchScopeLabel) ?></span>
            <strong><?= e($branchFilter !== '' ? $branchFilter : $allAccessibleBranchesLabel) ?></strong>
            <span class="muted"><?= e($searchScopeLabel) ?></span>
            <strong><?= e($searchQuery !== '' ? $searchQuery : '-') ?></strong>
        </div>
    </aside>
</section>

<section class="grid grid-4 bill-management-stats">
    <article class="stat-card">
        <p class="stat-label"><?= e($billsStatLabel) ?></p>
        <p class="stat-value"><?= (int) $summary['total_bills'] ?></p>
    </article>
    <article class="stat-card">
        <p class="stat-label"><?= e($paidPartialUnpaidLabel) ?></p>
        <p class="stat-value bill-management-stat-combo"><?= (int) $summary['paid_bills'] ?> / <?= (int) $summary['partial_bills'] ?> / <?= (int) $summary['unpaid_bills'] ?></p>
    </article>
    <article class="stat-card">
        <p class="stat-label"><?= e($cancelledLabel) ?></p>
        <p class="stat-value"><?= (int) $summary['cancelled_bills'] ?></p>
    </article>
    <article class="stat-card">
        <p class="stat-label"><?= e($paidReceivedLabel) ?></p>
        <p class="stat-value"><?= format_money($summary['paid_amount']) ?></p>
    </article>
</section>

<section class="table-card bill-management-table-card" style="margin-top: 18px;">
    <div class="section-head" style="padding: 18px 18px 0;">
        <div>
            <h2 class="section-title"><?= e($billListTitle) ?></h2>
            <p class="helper">
                <?php if ($hasRequestedBills): ?>
                    <?= e(strtr($billCountLabel, array('{count}' => (string) ((int) $summary['total_bills'])))) ?>
                <?php else: ?>
                    <?= e($useViewBillsListLabel) ?>
                <?php endif; ?>
            </p>
        </div>
    </div>

    <?php if (!$hasRequestedBills): ?>
        <div class="empty-state"><?= e($useViewBillsDataLabel) ?></div>
    <?php elseif (empty($rows)): ?>
        <div class="empty-state"><?= e($noBillsFoundLabel) ?></div>
    <?php else: ?>
        <table class="bill-management-table" style="min-width: 1320px;">
            <thead>
                <tr>
                    <th><?= e($dateColumnLabel) ?></th>
                    <th><?= e($billColumnLabel) ?></th>
                    <th><?= e($customerColumnLabel) ?></th>
                    <th><?= e($vehicleColumnLabel) ?></th>
                    <th><?= e($servicesColumnLabel) ?></th>
                    <th><?= e($statusColumnLabel) ?></th>
                    <th><?= e($paymentColumnLabel) ?></th>
                    <th><?= e($totalColumnLabel) ?></th>
                    <th><?= e($paidColumnLabel) ?></th>
                    <th><?= e($balanceColumnLabel) ?></th>
                    <th><?= e($actionColumnLabel) ?></th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($rows as $row): ?>
                    <?php
                    $status = (string) ($row['status'] ?? 'waiting');
                    $paymentStatus = (string) ($row['payment_status'] ?? 'unpaid');
                    $orderSource = (string) ($row['order_source'] ?? 'booking');
                    $totalPrice = (float) ($row['total_price'] ?? 0);
                    $paidAmount = (float) ($row['paid_amount'] ?? 0);
                    $balanceAmount = max(0.0, $totalPrice - $paidAmount);
                    $billNumber = trim((string) ($row['bill_number'] ?? ''));
                    $billLabel = $billNumber !== '' ? $billNumber : '#' . (int) ($row['order_id'] ?? 0);
                    $brandModel = trim((string) (($row['brand'] ?? '') . ' ' . ($row['model'] ?? '')));
                    $serviceNames = trim((string) ($row['service_names'] ?? ''));
                    $isQuickServiceBill = $orderSource === 'quick_service';
                    $isWaitingQueueBill = !$isQuickServiceBill && $status === 'waiting';
                    $isBillClosed = $status === 'done'
                        || $paymentStatus === 'paid'
                        || ($totalPrice > 0.0 && $balanceAmount <= 0.0);
                    $canCancelBill = $status !== 'cancelled' && (
                        ($isBillClosed && !$isWaitingQueueBill && $canCancelClosedBill)
                        || ($isWaitingQueueBill && $canCancelWaiting)
                        || (!$isBillClosed && !$isWaitingQueueBill && ($canCancelOpenBill || ($isQuickServiceBill && can_access($conn, 'quick_service'))))
                    );
                    $receiptPath = 'bill_receipt.php?id=' . (int) $row['order_id'] . '&return_to=' . urlencode($returnTo);
                    $cancelPath = 'cancel_bill.php?id=' . (int) $row['order_id'] . '&return_to=' . urlencode($returnTo);
                    ?>
                    <tr>
                        <td>
                            <div class="stack stack-tight">
                                <strong><?= e(format_datetime((string) ($row['order_date'] ?? ''))) ?></strong>
                                <?php if (!empty($row['return_at'])): ?>
                                    <span class="muted"><?= e($pickupDueLabel) ?>: <?= e(format_datetime((string) $row['return_at'])) ?></span>
                                <?php endif; ?>
                            </div>
                        </td>
                        <td>
                            <div class="stack stack-tight">
                                <strong><?= e($billLabel) ?></strong>
                                <span class="muted"><?= e(bill_management_source_label($orderSource)) ?></span>
                                <span class="muted"><?= e(bill_management_branch_label((string) ($row['branch_name'] ?? '-'))) ?></span>
                            </div>
                        </td>
                        <td>
                            <div class="stack stack-tight">
                                <strong><?= e((string) ($row['customer_name'] ?? '-')) ?></strong>
                                <span class="muted"><?= e((string) ($row['phone'] ?? '-')) ?></span>
                            </div>
                        </td>
                        <td>
                            <div class="vehicle-profile-inline">
                                <?= car_profile_photo_html($row, 'vehicle-profile-photo vehicle-profile-photo--sm', 'vehicle-profile-photo-placeholder vehicle-profile-photo-placeholder--sm') ?>
                                <div class="stack stack-tight">
                                    <strong><?= e((string) ($row['plate_number'] ?? '-')) ?></strong>
                                    <span class="muted"><?= e($brandModel !== '' ? $brandModel : $vehiclePendingLabel) ?></span>
                                </div>
                            </div>
                        </td>
                        <td class="bill-management-services-cell">
                            <div class="stack stack-tight">
                                <strong><?= e(strtr($itemCountLabel, array('{count}' => (string) ((int) ($row['item_count'] ?? 0))))) ?></strong>
                                <span class="muted"><?= e($serviceNames !== '' ? $serviceNames : '-') ?></span>
                            </div>
                        </td>
                        <td>
                            <div class="stack stack-tight">
                                <span class="<?= e(status_class($status)) ?>"><?= e(status_label($status)) ?></span>
                            </div>
                        </td>
                        <td>
                            <div class="stack stack-tight">
                                <span class="<?= e(payment_status_class($paymentStatus)) ?>"><?= e(payment_status_label($paymentStatus)) ?></span>
                                <?php if (!empty($row['last_payment_at'])): ?>
                                    <span class="muted"><?= e(format_datetime((string) $row['last_payment_at'])) ?></span>
                                <?php endif; ?>
                            </div>
                        </td>
                        <td class="number"><?= format_money($totalPrice) ?></td>
                        <td class="number"><?= format_money($paidAmount) ?></td>
                        <td class="number"><?= format_money($balanceAmount) ?></td>
                        <td>
                            <div class="actions bill-management-row-actions">
                                <a
                                    class="button button-secondary bill-management-action app-action-button"
                                    href="<?= e($receiptPath) ?>"
                                    title="<?= e($viewLabel) ?>"
                                    aria-label="<?= e($viewLabel) ?>"
                                ><?= app_button_content('eye', $viewLabel) ?></a>
                                <a
                                    class="button button-secondary bill-management-action app-action-button"
                                    href="<?= e($receiptPath . '&autoprint=1') ?>"
                                    title="<?= e($reprintLabel) ?>"
                                    aria-label="<?= e($reprintLabel) ?>"
                                ><?= app_button_content('printer', $reprintLabel) ?></a>
                                <?php if ($canCancelBill): ?>
                                    <a
                                        class="button button-danger bill-management-action app-action-button"
                                        href="<?= e($cancelPath) ?>"
                                        title="<?= e($cancelActionLabel) ?>"
                                        aria-label="<?= e($cancelActionLabel) ?>"
                                    ><?= app_button_content('x', $cancelActionLabel) ?></a>
                                <?php endif; ?>
                            </div>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>
</section>

<?php render_page_end(); ?>
