<?php
session_start();
require_once dirname(__DIR__) . '/includes/functions.php';
require_once dirname(__DIR__) . '/includes/sales_modules.php';

billing_require_auth();
billing_ensure_sales_module_support();

$user = billing_current_user();
$organization = billing_current_organization();
if (!$user) {
    billing_redirect('signin.php');
}
if (!$organization || empty($organization['onboarding_completed_at'])) {
    billing_redirect('onboarding.php?step=1');
}

$moduleKey = isset($salesModule) ? (string) $salesModule : 'quotes';
$module = billing_sales_module($moduleKey);
if (!$module) {
    billing_redirect('dashboard.php?tab=dashboard');
}

if (!isset($_SESSION['sales_document_custom_views']) || !is_array($_SESSION['sales_document_custom_views'])) {
    $_SESSION['sales_document_custom_views'] = [];
}
if (!isset($_SESSION['sales_document_custom_views'][$moduleKey]) || !is_array($_SESSION['sales_document_custom_views'][$moduleKey])) {
    $_SESSION['sales_document_custom_views'][$moduleKey] = [];
}

$stats = billing_dashboard_stats((int) $user['id']);
$organizationName = (string) ($organization['organization_name'] ?? 'Billing');
$userLabel = (string) ($user['email'] ?? 'billing-user');
$billingTopbarOrganizationName = $organizationName;
$billingTopbarUserLabel = $userLabel;
$billingActiveNav = (string) $module['nav'];

$listFn = (string) $module['list_fn'];
$records = $listFn((int) $user['id'], (int) $organization['id']);
$flashSuccess = billing_flash('success');
$flashError = billing_flash('error');

function billing_sales_document_url(string $path, array $changes = []): string
{
    $query = $_GET;
    foreach ($changes as $key => $value) {
        if ($value === null || $value === '') {
            unset($query[$key]);
        } else {
            $query[$key] = $value;
        }
    }

    return $path . ($query !== [] ? '?' . http_build_query($query) : '');
}

function billing_sales_money_value(float $amount): string
{
    return "\u{20B9}" . number_format($amount, 2);
}

function billing_sales_money_number(float $amount): string
{
    return number_format($amount, 2, '.', '');
}

function billing_sales_format_date(?string $date): string
{
    $date = (string) $date;
    if ($date === '') {
        return '-';
    }

    $time = strtotime($date);
    return $time ? date('d/m/Y', $time) : $date;
}

function billing_sales_filter_title(string $moduleKey): string
{
    $filter = billing_sales_normalize_filter_key((string) ($_GET['filter_by'] ?? ''));

    return match ($moduleKey) {
        'invoices' => $filter === 'unpaid' ? 'Unpaid' : 'All Invoices',
        'subscriptions' => 'All Subscriptions',
        'delivery_challans' => 'All Delivery Challans',
        'credit_notes' => 'All Credit Notes',
        default => (string) billing_sales_module($moduleKey)['list_title'],
    };
}

function billing_sales_normalize_filter_key(string $value): string
{
    $value = strtolower(trim($value));
    if ($value === '') {
        return 'all';
    }

    if (strpos($value, 'status.') === 0) {
        $value = substr($value, 7);
    }

    return str_replace(['_', '-'], ' ', $value);
}

function billing_sales_status_aliases(string $moduleKey): array
{
    if ($moduleKey === 'quotes') {
        return [
            'pending approval' => ['pending approval', 'pending'],
            'customer viewed' => ['customer viewed', 'viewed'],
            'accepted' => ['accepted'],
            'approved' => ['approved'],
            'invoiced' => ['invoiced'],
            'declined' => ['declined'],
            'sent' => ['sent'],
            'draft' => ['draft'],
        ];
    }

    if ($moduleKey === 'invoices') {
        return [
            'pending' => ['pending'],
            'payment initiated' => ['payment initiated'],
            'partially paid' => ['partially paid', 'partial paid'],
            'paid' => ['paid'],
            'unpaid' => ['unpaid', 'sent'],
            'overdue' => ['overdue'],
            'draft' => ['draft'],
            'void' => ['void'],
            'sent' => ['sent'],
        ];
    }

    if ($moduleKey === 'subscriptions') {
        return [
            'active' => ['active', 'live'],
            'trial' => ['trial'],
            'trials expired in the previous week' => ['trial expired', 'expired'],
            'trials expiring in the next week' => ['trial', 'expiring soon'],
            'trials expiring in the next seven days' => ['trial', 'expiring soon'],
            'dunning' => ['dunning'],
            'unpaid' => ['unpaid'],
            'subscriptions with unpaid invoices' => ['unpaid'],
            'cancelled' => ['cancelled', 'canceled'],
            'expired' => ['expired'],
            'live' => ['live', 'active'],
        ];
    }

    return [];
}

function billing_sales_status_matches(string $moduleKey, string $selectedStatus, string $recordStatus): bool
{
    $selectedStatus = billing_sales_normalize_filter_key($selectedStatus);
    $recordStatus = billing_sales_normalize_filter_key($recordStatus);

    if ($selectedStatus === 'all') {
        return true;
    }

    if ($selectedStatus === $recordStatus) {
        return true;
    }

    $aliases = billing_sales_status_aliases($moduleKey);
    if (!isset($aliases[$selectedStatus])) {
        return false;
    }

    return in_array($recordStatus, $aliases[$selectedStatus], true);
}

function billing_sales_status_class(string $status): string
{
    $status = strtolower(trim($status));
    return match ($status) {
        'live', 'active', 'paid', 'approved', 'accepted' => 'is-green',
        'open', 'due today', 'sent', 'customer viewed' => 'is-blue',
        'draft', 'inactive', 'pending approval' => 'is-muted',
        'declined', 'overdue', 'void' => 'is-red',
        default => 'is-default',
    };
}

function billing_sales_list_headers(string $moduleKey): array
{
    return match ($moduleKey) {
        'invoices' => ['DATE', 'INVOICE#', 'CUSTOMER NAME', 'EMAIL', 'STATUS', 'DUE DATE', 'AMOUNT', 'BALANCE'],
        'subscriptions' => ['CREATED ON', 'ACTIVATED ON', 'SUBSCRIPTION#', 'CUSTOMER NAME', 'PLAN NAME', 'STATUS', 'AMOUNT', 'LAST BILLED ON'],
        'delivery_challans' => ['DATE', 'DELIVERY CHALLAN#', 'REFERENCE NUMBER', 'CUSTOMER NAME', 'STATUS', 'INVOICE STATUS', 'AMOUNT', ''],
        'credit_notes' => ['DATE', 'CREDIT NOTE#', 'REFERENCE NUMBER', 'CUSTOMER NAME', 'INVOICE#', 'STATUS', 'AMOUNT', 'BALANCE'],
        default => ['DATE', 'NUMBER', 'CUSTOMER NAME', 'STATUS', 'AMOUNT'],
    };
}

function billing_sales_invoice_due_label(array $record): string
{
    $status = strtolower((string) ($record['status_label'] ?? ''));
    $invoiceDate = (string) ($record['invoice_date'] ?? '');
    $dueDate = (string) ($record['due_date'] ?? '');
    if ($dueDate !== '') {
        $dueTime = strtotime($dueDate);
        if ($dueTime) {
            $todayTime = strtotime(date('Y-m-d'));
            $daysDiff = (int) floor(($todayTime - $dueTime) / 86400);
            if ($daysDiff > 0 && in_array($status, ['sent', 'unpaid', 'overdue'], true)) {
                return 'OVERDUE BY ' . $daysDiff . ' DAY' . ($daysDiff === 1 ? '' : 'S');
            }
        }
    }
    if ($status === 'sent' && $invoiceDate !== '' && $dueDate !== '' && billing_sales_format_date($invoiceDate) === billing_sales_format_date($dueDate)) {
        return 'DUE TODAY';
    }
    if ($status === 'unpaid' && $invoiceDate !== '' && $dueDate !== '' && billing_sales_format_date($invoiceDate) === billing_sales_format_date($dueDate)) {
        return 'DUE TODAY';
    }
    return strtoupper((string) ($record['status_label'] ?? 'DRAFT'));
}

function billing_sales_row_cells(string $moduleKey, array $record): array
{
    return match ($moduleKey) {
        'quotes' => [
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['quote_date'] ?? ''))],
            ['type' => 'link', 'value' => (string) ($record['quote_number'] ?? ''), 'suffix_icon' => 'fa-regular fa-envelope'],
            ['type' => 'stack', 'primary' => (string) ($record['customer_name'] ?? ''), 'secondary' => (string) ($record['reference_number'] ?? '')],
            ['type' => 'status', 'value' => strtoupper((string) ($record['status_label'] ?? 'DRAFT')), 'class' => billing_sales_status_class((string) ($record['status_label'] ?? 'Draft'))],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['total_amount'] ?? 0))],
        ],
        'invoices' => [
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['invoice_date'] ?? ''))],
            ['type' => 'link', 'value' => (string) ($record['invoice_number'] ?? ''), 'suffix_icon' => 'fa-regular fa-envelope'],
            ['type' => 'stack', 'primary' => (string) ($record['customer_name'] ?? ''), 'secondary' => ''],
            ['type' => 'text', 'value' => (string) ($record['customer_email'] ?? '')],
            ['type' => 'status', 'value' => billing_sales_invoice_due_label($record), 'class' => billing_sales_invoice_status_class($record)],
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['due_date'] ?? ''))],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['total_amount'] ?? 0))],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['balance_amount'] ?? 0))],
        ],
        'subscriptions' => [
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['created_at'] ?? ''))],
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['start_date'] ?? ''))],
            ['type' => 'link', 'value' => (string) ($record['subscription_number'] ?? '')],
            ['type' => 'stack', 'primary' => (string) ($record['customer_name'] ?? ''), 'secondary' => (string) ($record['customer_email'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['plan_name'] ?? '')],
            ['type' => 'status', 'value' => strtoupper((string) ($record['status_label'] ?? '')), 'class' => 'is-green'],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['amount'] ?? $record['total_amount'] ?? 0))],
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['current_cycle_start'] ?? $record['start_date'] ?? ''))],
        ],
        'delivery_challans' => [
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['challan_date'] ?? ''))],
            ['type' => 'link', 'value' => (string) ($record['delivery_challan_number'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['reference_number'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['customer_name'] ?? '')],
            ['type' => 'status', 'value' => strtoupper((string) ($record['status_label'] ?? 'DRAFT')), 'class' => 'is-muted'],
            ['type' => 'text', 'value' => ''],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['total_amount'] ?? 0))],
            ['type' => 'icon', 'icon' => 'fa-solid fa-magnifying-glass'],
        ],
        'credit_notes' => [
            ['type' => 'text', 'value' => billing_sales_format_date((string) ($record['credit_note_date'] ?? ''))],
            ['type' => 'link', 'value' => (string) ($record['credit_note_number'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['reference_number'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['customer_name'] ?? '')],
            ['type' => 'text', 'value' => (string) ($record['invoice_number'] ?? '')],
            ['type' => 'status', 'value' => strtoupper((string) ($record['status_label'] ?? 'OPEN')), 'class' => 'is-blue'],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['total_amount'] ?? 0))],
            ['type' => 'amount', 'value' => billing_sales_money_value((float) ($record['credits_remaining'] ?? $record['total_amount'] ?? 0))],
        ],
        default => [],
    };
}

function billing_sales_invoice_status_class(array $record): string
{
    $label = billing_sales_invoice_due_label($record);
    if (strpos($label, 'OVERDUE BY') === 0) {
        return 'is-red';
    }
    if ($label === 'DUE TODAY') {
        return 'is-blue';
    }
    return billing_sales_status_class((string) ($record['status_label'] ?? 'Draft'));
}

function billing_sales_document_field_map(string $moduleKey): array
{
    return match ($moduleKey) {
        'quotes' => [
            'created_time' => ['label' => 'Created Time', 'value' => 'created_at', 'type' => 'datetime'],
            'modified_time' => ['label' => 'Last Modified Time', 'value' => 'updated_at', 'type' => 'datetime'],
            'date' => ['label' => 'Date', 'value' => 'quote_date', 'type' => 'date'],
            'number' => ['label' => 'Quote Number', 'value' => 'quote_number', 'type' => 'text'],
            'customer_name' => ['label' => 'Customer Name', 'value' => 'customer_name', 'type' => 'text'],
            'status' => ['label' => 'Quote Status', 'value' => 'status_label', 'type' => 'text'],
            'amount' => ['label' => 'Amount', 'value' => 'total_amount', 'type' => 'number'],
        ],
        'invoices' => [
            'created_time' => ['label' => 'Created Time', 'value' => 'created_at', 'type' => 'datetime'],
            'modified_time' => ['label' => 'Last Modified Time', 'value' => 'updated_at', 'type' => 'datetime'],
            'date' => ['label' => 'Date', 'value' => 'invoice_date', 'type' => 'date'],
            'number' => ['label' => 'Invoice Number', 'value' => 'invoice_number', 'type' => 'text'],
            'customer_name' => ['label' => 'Customer Name', 'value' => 'customer_name', 'type' => 'text'],
            'status' => ['label' => 'Invoice Status', 'value' => 'status_label', 'type' => 'text'],
            'amount' => ['label' => 'Amount', 'value' => 'total_amount', 'type' => 'number'],
        ],
        default => [
            'created_time' => ['label' => 'Created Time', 'value' => 'created_at', 'type' => 'datetime'],
            'modified_time' => ['label' => 'Last Modified Time', 'value' => 'updated_at', 'type' => 'datetime'],
            'date' => ['label' => 'Date', 'value' => 'created_at', 'type' => 'date'],
            'number' => ['label' => 'Number', 'value' => 'id', 'type' => 'text'],
            'customer_name' => ['label' => 'Customer Name', 'value' => 'customer_name', 'type' => 'text'],
            'status' => ['label' => 'Status', 'value' => 'status_label', 'type' => 'text'],
            'amount' => ['label' => 'Amount', 'value' => 'total_amount', 'type' => 'number'],
        ],
    };
}

function billing_sales_document_sort_options(string $moduleKey): array
{
    $fieldMap = billing_sales_document_field_map($moduleKey);
    return [
        'created_time' => $fieldMap['created_time']['label'],
        'modified_time' => $fieldMap['modified_time']['label'],
        'date' => $fieldMap['date']['label'],
        'number' => $fieldMap['number']['label'],
        'customer_name' => $fieldMap['customer_name']['label'],
        'amount' => $fieldMap['amount']['label'],
    ];
}

function billing_sales_document_statuses(array $records): array
{
    $statuses = [];
    foreach ($records as $record) {
        $status = trim((string) ($record['status_label'] ?? ''));
        if ($status === '') {
            continue;
        }
        $key = strtolower($status);
        $statuses[$key] = $status;
    }
    asort($statuses);
    return $statuses;
}

function billing_sales_document_view_statuses(string $moduleKey, array $records): array
{
    if ($moduleKey === 'quotes') {
        return [
            'all' => 'All',
            'draft' => 'Draft',
            'pending approval' => 'Pending Approval',
            'approved' => 'Approved',
            'sent' => 'Sent',
            'customer viewed' => 'Customer Viewed',
            'accepted' => 'Accepted',
            'invoiced' => 'Invoiced',
            'declined' => 'Declined',
        ];
    }

    if ($moduleKey === 'invoices') {
        return [
            'all' => 'All',
            'draft' => 'Draft',
            'pending' => 'Pending',
            'sent' => 'Sent',
            'overdue' => 'Overdue',
            'payment initiated' => 'Payment Initiated',
            'partially paid' => 'Partially Paid',
            'paid' => 'Paid',
            'unpaid' => 'Unpaid',
            'void' => 'Void',
        ];
    }

    if ($moduleKey === 'subscriptions') {
        return [
            'all' => 'All',
            'active' => 'Active',
            'trial' => 'Trial',
            'trials expired in the previous week' => 'Trials Expired in the Previous Week',
            'trials expiring in the next week' => 'Trials Expiring in the Next Week',
            'trials expiring in the next seven days' => 'Trials Expiring in the Next Seven Days',
            'dunning' => 'Dunning',
            'unpaid' => 'Unpaid',
            'subscriptions with unpaid invoices' => 'Subscriptions with Unpaid Invoices',
            'cancelled' => 'Cancelled',
            'expired' => 'Expired',
            'live' => 'Live',
        ];
    }

    $statuses = ['all' => 'All'];
    foreach (billing_sales_document_statuses($records) as $statusKey => $statusLabel) {
        $statuses[$statusKey] = $statusLabel;
    }
    return $statuses;
}

function billing_sales_document_value(array $record, string $fieldKey, string $moduleKey)
{
    $fieldMap = billing_sales_document_field_map($moduleKey);
    if (!isset($fieldMap[$fieldKey])) {
        return null;
    }

    $sourceKey = (string) $fieldMap[$fieldKey]['value'];
    $type = (string) $fieldMap[$fieldKey]['type'];
    $value = $record[$sourceKey] ?? null;

    if ($fieldKey === 'created_time' && empty($value)) {
        $dateFieldKey = (string) $fieldMap['date']['value'];
        $value = $record[$dateFieldKey] ?? null;
    }
    if ($fieldKey === 'modified_time' && empty($value)) {
        $value = $record['updated_at'] ?? $record['created_at'] ?? null;
        if (empty($value)) {
            $dateFieldKey = (string) $fieldMap['date']['value'];
            $value = $record[$dateFieldKey] ?? null;
        }
    }

    if ($type === 'number') {
        return (float) $value;
    }
    if ($type === 'date' || $type === 'datetime') {
        $time = strtotime((string) $value);
        return $time ?: 0;
    }

    return trim((string) $value);
}

function billing_sales_document_matches(array $record, string $fieldKey, string $comparator, string $expected, string $moduleKey): bool
{
    $fieldMap = billing_sales_document_field_map($moduleKey);
    if (!isset($fieldMap[$fieldKey])) {
        return true;
    }

    $type = (string) $fieldMap[$fieldKey]['type'];
    $actual = billing_sales_document_value($record, $fieldKey, $moduleKey);

    if ($comparator === 'is_empty') {
        return trim((string) $actual) === '' || $actual === 0 || $actual === null;
    }
    if ($comparator === 'is_not_empty') {
        return !(trim((string) $actual) === '' || $actual === 0 || $actual === null);
    }

    if ($type === 'number') {
        $left = (float) $actual;
        $right = (float) $expected;
        return match ($comparator) {
            'is' => $left === $right,
            'is_not' => $left !== $right,
            'greater_than' => $left > $right,
            'less_than' => $left < $right,
            default => true,
        };
    }

    $left = strtolower(trim((string) $actual));
    $right = strtolower(trim($expected));
    return match ($comparator) {
        'is' => $left === $right,
        'is_not' => $left !== $right,
        'contains' => $right === '' ? true : strpos($left, $right) !== false,
        'not_contains' => $right === '' ? true : strpos($left, $right) === false,
        default => true,
    };
}

$fieldMap = billing_sales_document_field_map($moduleKey);
$sortOptions = billing_sales_document_sort_options($moduleKey);
$comparatorOptions = [
    'is' => 'is',
    'is_not' => 'is not',
    'contains' => 'contains',
    'not_contains' => 'does not contain',
    'greater_than' => 'is greater than',
    'less_than' => 'is less than',
    'is_empty' => 'is empty',
    'is_not_empty' => 'is not empty',
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = (string) ($_POST['sales_documents_action'] ?? '');
    if ($action === 'save_custom_view') {
        $viewName = trim((string) ($_POST['view_name'] ?? ''));
        $favorite = !empty($_POST['favorite']) ? 1 : 0;
        $visibility = (string) ($_POST['visibility'] ?? 'only_me');
        $criteriaField = strtolower(trim((string) ($_POST['criteria_field'] ?? '')));
        $criteriaComparator = strtolower(trim((string) ($_POST['criteria_comparator'] ?? '')));
        $criteriaValue = trim((string) ($_POST['criteria_value'] ?? ''));

        if ($viewName === '') {
            billing_flash('error', 'Custom view name is required.');
            billing_redirect(billing_sales_document_url((string) $module['list_path'], ['modal' => 'custom-view']));
        }

        $allowedVisibility = ['only_me', 'selected_roles', 'everyone'];
        if (!in_array($visibility, $allowedVisibility, true)) {
            $visibility = 'only_me';
        }
        if ($criteriaField !== '' && !isset($fieldMap[$criteriaField])) {
            $criteriaField = '';
        }
        if ($criteriaComparator !== '' && !isset($comparatorOptions[$criteriaComparator])) {
            $criteriaComparator = '';
        }
        if (($criteriaField !== '' || $criteriaComparator !== '' || $criteriaValue !== '') && ($criteriaField === '' || $criteriaComparator === '')) {
            billing_flash('error', 'Choose a valid field and comparator for the custom view.');
            billing_redirect(billing_sales_document_url((string) $module['list_path'], ['modal' => 'custom-view']));
        }
        if (!in_array($criteriaComparator, ['is_empty', 'is_not_empty'], true) && $criteriaField !== '' && $criteriaValue === '') {
            billing_flash('error', 'Enter a value for the custom view criteria.');
            billing_redirect(billing_sales_document_url((string) $module['list_path'], ['modal' => 'custom-view']));
        }

        $slug = strtolower((string) preg_replace('/[^a-z0-9]+/', '-', $viewName));
        $slug = trim($slug, '-');
        if ($slug === '') {
            $slug = $moduleKey . '-view-' . count($_SESSION['sales_document_custom_views'][$moduleKey]);
        }

        $_SESSION['sales_document_custom_views'][$moduleKey][$slug] = [
            'name' => $viewName,
            'favorite' => $favorite,
            'visibility' => $visibility,
            'criteria' => [
                'field' => $criteriaField,
                'comparator' => $criteriaComparator,
                'value' => $criteriaValue,
            ],
        ];

        billing_flash('success', 'Custom view saved.');
        billing_redirect(billing_sales_document_url((string) $module['list_path'], [
            'view' => $slug,
            'filter_by' => null,
            'sort_by' => null,
            'sort_order' => null,
            'modal' => null,
        ]));
    }
}

$customViews = $_SESSION['sales_document_custom_views'][$moduleKey];
$statuses = billing_sales_document_statuses($records);
$viewStatuses = billing_sales_document_view_statuses($moduleKey, $records);
$selectedView = trim((string) ($_GET['view'] ?? ''));
$selectedStatus = billing_sales_normalize_filter_key((string) ($_GET['filter_by'] ?? 'all'));
$sortBy = strtolower(trim((string) ($_GET['sort_by'] ?? 'created_time')));
$sortOrder = strtolower(trim((string) ($_GET['sort_order'] ?? 'desc')));
$openModal = (string) ($_GET['modal'] ?? '');

if (!isset($sortOptions[$sortBy])) {
    $sortBy = 'created_time';
}
if (!in_array($sortOrder, ['asc', 'desc'], true)) {
    $sortOrder = 'desc';
}
$allRecords = $records;

if ($selectedStatus !== 'all') {
    $records = array_values(array_filter($records, static function (array $record) use ($selectedStatus, $moduleKey): bool {
        return billing_sales_status_matches($moduleKey, $selectedStatus, (string) ($record['status_label'] ?? ''));
    }));
}

$activeCustomViewCriteriaLabel = '';
if ($selectedView !== '' && isset($customViews[$selectedView]['criteria']) && is_array($customViews[$selectedView]['criteria'])) {
    $criteria = $customViews[$selectedView]['criteria'];
    $criteriaField = strtolower(trim((string) ($criteria['field'] ?? '')));
    $criteriaComparator = strtolower(trim((string) ($criteria['comparator'] ?? '')));
    $criteriaValue = trim((string) ($criteria['value'] ?? ''));
    if ($criteriaField !== '' && $criteriaComparator !== '') {
        $records = array_values(array_filter($records, static function (array $record) use ($criteriaField, $criteriaComparator, $criteriaValue, $moduleKey): bool {
            return billing_sales_document_matches($record, $criteriaField, $criteriaComparator, $criteriaValue, $moduleKey);
        }));
    }

    if ($criteriaField !== '' && $criteriaComparator !== '' && isset($fieldMap[$criteriaField], $comparatorOptions[$criteriaComparator])) {
        $activeCustomViewCriteriaLabel = $fieldMap[$criteriaField]['label'] . ' ' . $comparatorOptions[$criteriaComparator];
        if (!in_array($criteriaComparator, ['is_empty', 'is_not_empty'], true) && $criteriaValue !== '') {
            $activeCustomViewCriteriaLabel .= ': ' . $criteriaValue;
        }
    }
}

usort($records, static function (array $left, array $right) use ($sortBy, $sortOrder, $moduleKey): int {
    $leftValue = billing_sales_document_value($left, $sortBy, $moduleKey);
    $rightValue = billing_sales_document_value($right, $sortBy, $moduleKey);

    if (is_numeric($leftValue) && is_numeric($rightValue)) {
        $result = ((float) $leftValue) <=> ((float) $rightValue);
    } else {
        $result = strcasecmp((string) $leftValue, (string) $rightValue);
    }

    return $sortOrder === 'asc' ? $result : ($result * -1);
});

if ((string) ($_GET['export'] ?? '') !== '') {
    $exportMode = strtolower(trim((string) ($_GET['export'] ?? 'current')));
    $exportRecords = $exportMode === 'all' ? $allRecords : $records;

    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="' . $moduleKey . '-' . date('Ymd-His') . '.csv"');

    if ($moduleKey === 'quotes') {
        echo "\"Date\",\"Quote Number\",\"Customer Name\",\"Status\",\"Amount\"\r\n";
        foreach ($exportRecords as $record) {
            echo '"' . str_replace('"', '""', billing_sales_format_date((string) ($record['quote_date'] ?? ''))) . '",';
            echo '"' . str_replace('"', '""', (string) ($record['quote_number'] ?? '')) . '",';
            echo '"' . str_replace('"', '""', (string) ($record['customer_name'] ?? '')) . '",';
            echo '"' . str_replace('"', '""', strtoupper((string) ($record['status_label'] ?? 'DRAFT'))) . '",';
            echo '"' . str_replace('"', '""', billing_sales_money_number((float) ($record['total_amount'] ?? 0))) . '"' . "\r\n";
        }
    } else {
        echo "\"Number\",\"Customer Name\",\"Status\",\"Amount\"\r\n";
        foreach ($exportRecords as $record) {
            $number = (string) ($record['invoice_number'] ?? $record['quote_number'] ?? $record['subscription_number'] ?? $record['credit_note_number'] ?? $record['delivery_challan_number'] ?? '');
            echo '"' . str_replace('"', '""', $number) . '",';
            echo '"' . str_replace('"', '""', (string) ($record['customer_name'] ?? '')) . '",';
            echo '"' . str_replace('"', '""', (string) ($record['status_label'] ?? '')) . '",';
            echo '"' . str_replace('"', '""', billing_sales_money_number((float) ($record['total_amount'] ?? $record['amount'] ?? 0))) . '"' . "\r\n";
        }
    }
    exit;
}

$pageTitle = billing_sales_filter_title($moduleKey);
if ($selectedStatus !== 'all' && isset($statuses[$selectedStatus])) {
    $pageTitle = $statuses[$selectedStatus];
}
if ($selectedStatus !== 'all' && isset($viewStatuses[$selectedStatus])) {
    $pageTitle = $viewStatuses[$selectedStatus];
}
if ($selectedView !== '' && isset($customViews[$selectedView]['name'])) {
    $pageTitle = (string) $customViews[$selectedView]['name'];
}

$headers = billing_sales_list_headers($moduleKey);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<base href="<?php echo billing_escape(billing_base_href()); ?>">
<title><?php echo billing_escape((string) $module['list_title']); ?> | Zoho Billing</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap">
<link rel="stylesheet" href="Payslip_Project/assets/fontawesome/css/all.min.css">
<link rel="stylesheet" href="assets/billing.css?v=20260507-css-recovery-2">
<style>
.sales-list-card {
    background: #fff;
    border: 1px solid #dce5ef;
    border-radius: 22px;
    box-shadow: 0 12px 28px rgba(15, 23, 42, 0.05);
    overflow: visible;
}

.sales-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 28px 30px 20px;
}

.sales-list-title-wrap {
    position: relative;
}

.sales-list-title-trigger {
    list-style: none;
    cursor: pointer;
}

.sales-list-title-trigger::-webkit-details-marker {
    display: none;
}

.sales-list-title {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    padding: 0 12px;
    border: 1px solid #e5eaf3;
    border-radius: 12px;
    background: #f8fbff;
    color: #10203c;
    font-size: 17px;
    font-weight: 800;
    text-decoration: none;
}

.sales-list-actions,
.sales-list-new-split {
    display: flex;
    align-items: center;
}

.sales-list-actions {
    gap: 12px;
}

.sales-list-new-split {
    border-radius: 8px;
    overflow: hidden;
}

.sales-list-new-btn,
.sales-list-caret-btn,
.sales-list-icon-btn {
    min-height: 40px;
    border: 1px solid #27bc72;
    background: #27bc72;
    color: #fff;
    font: inherit;
    cursor: pointer;
}

.sales-list-new-btn {
    padding: 0 20px;
}

.sales-list-caret-btn {
    min-width: 38px;
    border-left-color: rgba(255, 255, 255, 0.25);
}

.sales-list-icon-btn {
    min-width: 40px;
    border-color: #d6dfeb;
    background: #fff;
    color: #334155;
    border-radius: 8px;
}

.sales-inline-details {
    position: relative;
}

.sales-inline-details summary {
    list-style: none;
}

.sales-inline-details summary::-webkit-details-marker {
    display: none;
}

.sales-popover {
    position: absolute;
    top: calc(100% + 8px);
    z-index: 20;
    min-width: 326px;
    padding: 8px 0 0;
    border: 1px solid #dce6f2;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.12);
}

.sales-popover--left {
    left: 0;
}

.sales-popover--right {
    right: 0;
}

.sales-popover-search {
    padding: 0 10px 10px;
}

.sales-popover-search input {
    width: 100%;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid #8db6ff;
    border-radius: 10px;
    outline: 0;
    font: inherit;
    box-shadow: inset 0 0 0 1px rgba(37, 99, 235, 0.02);
}

.sales-view-list,
.sales-menu-list,
.sales-submenu-list {
    display: grid;
    gap: 0;
}

.sales-view-list {
    max-height: 430px;
    overflow-y: auto;
    padding: 0 10px 10px;
}

.sales-view-item,
.sales-menu-item,
.sales-submenu-list a {
    min-height: 48px;
    padding: 0 22px 0 26px;
    border-radius: 10px;
    color: #3a4556;
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.sales-view-item.is-active,
.sales-menu-item.is-active,
.sales-submenu-list a.is-active,
.sales-view-item:hover,
.sales-menu-item:hover,
.sales-submenu-list a:hover {
    background: #4b87eb;
    color: #fff;
}

.sales-view-item i,
.sales-menu-item i,
.sales-submenu-list a i {
    font-size: 15px;
}

.sales-popover-empty {
    display: none;
    padding: 12px 18px;
    color: #94a3b8;
    font-size: 13px;
}

.sales-view-footer,
.sales-menu-divider {
    margin-top: 0;
    padding-top: 10px;
    border-top: 1px solid #edf2f7;
}

.sales-view-create {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 18px 14px;
    color: #2563eb;
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
}

.sales-menu-row {
    position: relative;
}

.sales-submenu-list {
    position: absolute;
    top: 0;
    right: calc(100% + 8px);
    min-width: 196px;
    padding: 8px;
    border: 1px solid #dce6f2;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 16px 40px rgba(15, 23, 42, 0.12);
    display: none;
}

.sales-menu-list {
    padding: 0 8px 8px;
}

.sales-menu-row.is-open .sales-submenu-list {
    display: grid;
}

.sales-filterbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 30px 20px;
}

.sales-filterbar-label {
    color: #64748b;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.04em;
}

.sales-filter-chip {
    min-height: 36px;
    padding: 0 14px;
    border: 1px solid #d9e2ef;
    border-radius: 999px;
    background: #fff;
    color: #334155;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
}

.sales-filter-chip.is-active {
    border-color: #cfe0ff;
    background: #eff6ff;
    color: #2563eb;
}

.sales-list-table-wrap {
    border-top: 1px solid #e8edf5;
    border-bottom-left-radius: 22px;
    border-bottom-right-radius: 22px;
    overflow-x: auto;
}

.sales-list-table {
    width: 100%;
    min-width: 1180px;
    border-collapse: collapse;
}

.sales-list-table thead th {
    padding: 12px 18px;
    border-bottom: 1px solid #e8edf5;
    color: #667085;
    font-size: 12px;
    font-weight: 800;
    text-align: left;
    white-space: nowrap;
    background: #fbfcff;
}

.sales-list-table thead th:last-child,
.sales-list-table tbody td:last-child {
    padding-right: 28px;
}

.sales-list-table tbody td {
    padding: 16px 18px;
    border-bottom: 1px solid #edf2f7;
    vertical-align: top;
    color: #0f172a;
}

.sales-list-table tbody tr:hover td {
    background: #fbfdff;
}

.sales-list-table th:first-child,
.sales-list-table td:first-child {
    width: 54px;
}

.sales-list-filter {
    color: #3b82f6;
    font-size: 18px;
}

.sales-list-checkbox {
    width: 19px;
    height: 19px;
}

.sales-list-link {
    color: #2563eb;
    text-decoration: none;
}

.sales-list-link-inline {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.sales-list-stack {
    display: grid;
    gap: 4px;
}

.sales-list-stack-sub {
    color: #667085;
}

.sales-list-amount {
    text-align: right;
    white-space: nowrap;
}

.sales-list-status {
    white-space: nowrap;
    font-weight: 500;
}

.sales-list-status.is-green {
    color: #10b981;
}

.sales-list-status.is-blue {
    color: #2563eb;
}

.sales-list-status.is-muted {
    color: #8a94a6;
}

.sales-list-status.is-red {
    color: #ef4444;
}

.sales-list-status.is-default {
    color: #475569;
}

.sales-list-end-icon {
    color: #667085;
}

.sales-list-empty {
    min-height: 360px;
    display: grid;
    place-items: center;
    color: #64748b;
}

.sales-modal {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: center;
    padding: 18px;
    background: rgba(15, 23, 42, 0.5);
}

.sales-modal-dialog {
    width: min(980px, 100%);
    border-radius: 18px;
    background: #fff;
    box-shadow: 0 24px 80px rgba(15, 23, 42, 0.22);
    overflow: hidden;
}

.sales-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 28px;
    border-bottom: 1px solid #edf2f7;
}

.sales-modal-header h3 {
    margin: 0;
    font-size: 22px;
    color: #0f172a;
}

.sales-modal-close {
    color: #64748b;
    text-decoration: none;
    font-size: 30px;
    line-height: 1;
}

.sales-modal-form {
    padding: 26px 28px 28px;
    display: grid;
    gap: 28px;
}

.sales-modal-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 24px;
    align-items: center;
}

.sales-modal-field label,
.sales-modal-section h4 {
    display: block;
    margin: 0 0 12px;
    color: #111827;
    font-size: 16px;
    font-weight: 600;
}

.sales-modal-field input[type="text"],
.sales-modal-field select {
    width: 100%;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid #d8e2ef;
    border-radius: 10px;
    outline: 0;
    background: #fff;
    font: inherit;
}

.sales-modal-criteria {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
}

.sales-modal-box {
    padding: 22px;
    border: 1px solid #e6ebf2;
    border-radius: 14px;
}

.sales-visibility-options {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
}

.sales-visibility-option {
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid #d8e2ef;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.sales-modal-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

.sales-modal-save,
.sales-modal-cancel {
    min-height: 40px;
    padding: 0 18px;
    border-radius: 8px;
    text-decoration: none;
    font: inherit;
    cursor: pointer;
}

.sales-modal-save {
    border: 1px solid #27bc72;
    background: #27bc72;
    color: #fff;
}

.sales-modal-cancel {
    border: 1px solid #d6dfeb;
    background: #fff;
    color: #334155;
}

@media (max-width: 900px) {
    .sales-list-head,
    .sales-filterbar,
    .sales-modal-row,
    .sales-modal-criteria {
        grid-template-columns: 1fr;
        flex-direction: column;
        align-items: flex-start;
    }

    .sales-list-head,
    .sales-filterbar {
        padding-left: 18px;
        padding-right: 18px;
    }

    .sales-popover {
        min-width: min(326px, calc(100vw - 44px));
    }
}
</style>
</head>
<body>
<div class="dashboard-shell customer-shell">
    <?php include dirname(__DIR__) . '/includes/app_sidebar.php'; ?>
    <div class="dashboard-main customer-main">
        <?php include dirname(__DIR__) . '/includes/topbar.php'; ?>
        <main class="catalog-page">
            <?php if ($flashSuccess): ?><div class="customer-flash"><?php echo billing_escape($flashSuccess); ?></div><?php endif; ?>
            <?php if ($flashError): ?><div class="customer-flash" style="background:#fef2f2;color:#b91c1c;border-color:#fecaca;"><?php echo billing_escape($flashError); ?></div><?php endif; ?>
            <section class="sales-list-card">
                <div class="sales-list-head">
                    <div class="sales-list-title-wrap">
                        <details class="sales-inline-details">
                            <summary class="sales-list-title-trigger">
                                <span class="sales-list-title">
                                    <?php echo billing_escape($pageTitle); ?>
                                    <i class="fa-solid fa-angle-down"></i>
                                </span>
                            </summary>
                            <div class="sales-popover sales-popover--left">
                                <div class="sales-popover-search">
                                    <input type="search" placeholder="Search" data-filter-search>
                                </div>
                                <div class="sales-view-list">
                                    <a class="sales-view-item <?php echo $selectedView === '' && $selectedStatus === 'all' ? 'is-active' : ''; ?>" href="<?php echo billing_escape((string) $module['list_path']); ?>" data-filter-option>
                                        <span>All</span>
                                        <i class="fa-solid fa-star-of-life" style="font-size:11px;opacity:.4;"></i>
                                    </a>
                                    <?php foreach ($viewStatuses as $statusKey => $statusLabel): ?>
                                        <?php if ($statusKey === 'all') { continue; } ?>
                                        <a class="sales-view-item <?php echo $selectedStatus === $statusKey ? 'is-active' : ''; ?>" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['filter_by' => $statusKey, 'view' => null])); ?>" data-filter-option>
                                            <span><?php echo billing_escape($statusLabel); ?></span>
                                            <i class="fa-regular fa-star" style="opacity:.45;"></i>
                                        </a>
                                    <?php endforeach; ?>
                                    <?php foreach ($customViews as $viewKey => $view): ?>
                                        <a class="sales-view-item <?php echo $selectedView === (string) $viewKey ? 'is-active' : ''; ?>" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['view' => $viewKey, 'filter_by' => null, 'sort_by' => null, 'sort_order' => null])); ?>" data-filter-option>
                                            <span><?php echo billing_escape((string) ($view['name'] ?? 'Custom View')); ?></span>
                                            <i class="fa-<?php echo !empty($view['favorite']) ? 'solid' : 'regular'; ?> fa-star" style="opacity:.65;"></i>
                                        </a>
                                    <?php endforeach; ?>
                                </div>
                                <div class="sales-popover-empty" data-filter-empty>No matching options</div>
                                <div class="sales-view-footer">
                                    <a class="sales-view-create" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['modal' => 'custom-view'])); ?>">
                                        <i class="fa-solid fa-circle-plus"></i>
                                        <span>New Custom View</span>
                                    </a>
                                </div>
                            </div>
                        </details>
                    </div>

                    <div class="sales-list-actions">
                        <?php if ($moduleKey === 'invoices'): ?>
                            <div class="sales-list-new-split">
                                <button class="sales-list-new-btn" type="button" onclick="window.location.href='<?php echo billing_escape((string) $module['new_path']); ?>';"><i class="fa-solid fa-plus"></i> New</button>
                                <button class="sales-list-caret-btn" type="button" aria-label="More new options"><i class="fa-solid fa-angle-down"></i></button>
                            </div>
                        <?php else: ?>
                            <button class="sales-list-new-btn" type="button" onclick="window.location.href='<?php echo billing_escape((string) $module['new_path']); ?>';"><i class="fa-solid fa-plus"></i> New</button>
                        <?php endif; ?>
                        <details class="sales-inline-details">
                            <summary class="sales-list-icon-btn" aria-label="More actions"><i class="fa-solid fa-ellipsis"></i></summary>
                            <div class="sales-popover sales-popover--right">
                                <div class="sales-menu-list">
                                    <div class="sales-menu-row" data-submenu-row>
                                        <a class="sales-menu-item" href="#" data-submenu-trigger>
                                            <span>Sort by</span>
                                            <i class="fa-solid fa-angle-right"></i>
                                        </a>
                                        <div class="sales-submenu-list">
                                            <?php foreach ($sortOptions as $sortKey => $sortLabel): ?>
                                                <a href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['sort_by' => $sortKey, 'sort_order' => $sortBy === $sortKey && $sortOrder === 'desc' ? 'asc' : 'desc'])); ?>" class="<?php echo $sortBy === $sortKey ? 'is-active' : ''; ?>">
                                                    <span><?php echo billing_escape($sortLabel); ?></span>
                                                    <?php if ($sortBy === $sortKey): ?><i class="fa-solid fa-arrow-<?php echo $sortOrder === 'asc' ? 'up' : 'down'; ?>"></i><?php endif; ?>
                                                </a>
                                            <?php endforeach; ?>
                                        </div>
                                    </div>
                                    <a class="sales-menu-item" href="#">
                                        <span>Import <?php echo billing_escape($moduleKey === 'quotes' ? 'Quotes' : ucfirst(str_replace('_', ' ', $moduleKey))); ?></span>
                                    </a>
                                    <div class="sales-menu-row" data-submenu-row>
                                        <a class="sales-menu-item" href="#" data-submenu-trigger>
                                            <span>Export</span>
                                            <i class="fa-solid fa-angle-right"></i>
                                        </a>
                                        <div class="sales-submenu-list">
                                            <a href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['export' => 'current'])); ?>">Export Current View</a>
                                            <a href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['export' => 'all'])); ?>">Export <?php echo billing_escape((string) $module['list_title']); ?></a>
                                        </div>
                                    </div>
                                    <a class="sales-menu-item" href="#">
                                        <span>Preferences</span>
                                    </a>
                                    <a class="sales-menu-item" href="#">
                                        <span>Manage Custom Fields</span>
                                    </a>
                                    <div class="sales-menu-divider"></div>
                                    <a class="sales-menu-item" href="<?php echo billing_escape((string) $module['list_path']); ?>">
                                        <span>Refresh List</span>
                                    </a>
                                </div>
                            </div>
                        </details>
                    </div>
                </div>

                <div class="sales-filterbar">
                    <span class="sales-filterbar-label">FILTER BY :</span>
                    <a class="sales-filter-chip <?php echo $selectedStatus === 'all' ? 'is-active' : ''; ?>" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['filter_by' => null, 'view' => null])); ?>">Status: All</a>
                    <?php if ($selectedStatus !== 'all' && isset($viewStatuses[$selectedStatus])): ?>
                        <span class="sales-filter-chip is-active">Status: <?php echo billing_escape($viewStatuses[$selectedStatus]); ?></span>
                    <?php endif; ?>
                    <?php if ($activeCustomViewCriteriaLabel !== ''): ?>
                        <span class="sales-filter-chip is-active">Custom View: <?php echo billing_escape($activeCustomViewCriteriaLabel); ?></span>
                    <?php endif; ?>
                </div>

                <?php if ($records === []): ?>
                    <div class="sales-list-empty">No records found.</div>
                <?php else: ?>
                    <div class="sales-list-table-wrap">
                        <table class="sales-list-table">
                            <thead>
                                <tr>
                                    <th>
                                        <span class="sales-list-filter"><i class="fa-solid fa-sliders"></i></span>
                                        <input class="sales-list-checkbox" type="checkbox" aria-label="Select all">
                                    </th>
                                    <?php foreach ($headers as $index => $header): ?>
                                        <th>
                                            <?php echo billing_escape($header); ?>
                                            <?php if ($moduleKey === 'credit_notes' && $index === 1): ?>
                                                <i class="fa-solid fa-arrow-up-long" style="font-size:10px;color:#2563eb;"></i>
                                            <?php endif; ?>
                                        </th>
                                    <?php endforeach; ?>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($records as $record): ?>
                                    <?php $cells = billing_sales_row_cells($moduleKey, $record); ?>
                                    <tr>
                                        <td><input class="sales-list-checkbox" type="checkbox" aria-label="Select row"></td>
                                        <?php foreach ($cells as $cell): ?>
                                            <td class="<?php echo in_array($cell['type'], ['amount'], true) ? 'sales-list-amount' : ''; ?>">
                                                <?php if ($cell['type'] === 'link'): ?>
                                                    <a class="sales-list-link sales-list-link-inline" href="<?php echo billing_escape(billing_sales_document_url((string) $module['new_path'], ['id' => (int) $record['id']])); ?>">
                                                        <span><?php echo billing_escape((string) $cell['value']); ?></span>
                                                        <?php if (!empty($cell['suffix_icon'])): ?><i class="<?php echo billing_escape((string) $cell['suffix_icon']); ?>" style="color:#667085;"></i><?php endif; ?>
                                                    </a>
                                                <?php elseif ($cell['type'] === 'stack'): ?>
                                                    <div class="sales-list-stack">
                                                        <a class="sales-list-link" href="<?php echo billing_escape(billing_sales_document_url((string) $module['new_path'], ['id' => (int) $record['id']])); ?>"><?php echo billing_escape((string) $cell['primary']); ?></a>
                                                        <?php if (($cell['secondary'] ?? '') !== ''): ?><span class="sales-list-stack-sub"><?php echo billing_escape((string) $cell['secondary']); ?></span><?php endif; ?>
                                                    </div>
                                                <?php elseif ($cell['type'] === 'status'): ?>
                                                    <span class="sales-list-status <?php echo billing_escape((string) ($cell['class'] ?? 'is-default')); ?>"><?php echo billing_escape((string) $cell['value']); ?></span>
                                                <?php elseif ($cell['type'] === 'icon'): ?>
                                                    <span class="sales-list-end-icon"><i class="<?php echo billing_escape((string) $cell['icon']); ?>"></i></span>
                                                <?php else: ?>
                                                    <?php echo $cell['value'] !== '' ? billing_escape((string) $cell['value']) : '&nbsp;'; ?>
                                                <?php endif; ?>
                                            </td>
                                        <?php endforeach; ?>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                <?php endif; ?>
            </section>

            <?php if ($openModal === 'custom-view'): ?>
                <div class="sales-modal">
                    <div class="sales-modal-dialog">
                        <div class="sales-modal-header">
                            <h3>New Custom View</h3>
                            <a class="sales-modal-close" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['modal' => null])); ?>" aria-label="Close">&times;</a>
                        </div>
                        <form class="sales-modal-form" action="<?php echo billing_escape((string) $module['list_path']); ?>" method="post">
                            <input type="hidden" name="sales_documents_action" value="save_custom_view">

                            <div class="sales-modal-row">
                                <div class="sales-modal-field">
                                    <label for="view_name">Name*</label>
                                    <input id="view_name" type="text" name="view_name" required autofocus>
                                </div>
                                <label class="sales-visibility-option" style="border:0;padding:0;">
                                    <input type="checkbox" name="favorite" value="1">
                                    <span>Mark as Favorite</span>
                                </label>
                            </div>

                            <div class="sales-modal-section">
                                <h4>Define the criteria ( if any )</h4>
                                <div class="sales-modal-criteria">
                                    <div class="sales-modal-field">
                                        <label for="criteria_field">Field</label>
                                        <select id="criteria_field" name="criteria_field">
                                            <option value="">Select a field</option>
                                            <?php foreach ($fieldMap as $fieldKey => $field): ?>
                                                <option value="<?php echo billing_escape($fieldKey); ?>"><?php echo billing_escape((string) $field['label']); ?></option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>
                                    <div class="sales-modal-field">
                                        <label for="criteria_comparator">Comparator</label>
                                        <select id="criteria_comparator" name="criteria_comparator">
                                            <option value="">Select a comparator</option>
                                            <?php foreach ($comparatorOptions as $comparatorKey => $comparatorLabel): ?>
                                                <option value="<?php echo billing_escape($comparatorKey); ?>"><?php echo billing_escape(ucfirst($comparatorLabel)); ?></option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>
                                    <div class="sales-modal-field">
                                        <label for="criteria_value">Value</label>
                                        <input id="criteria_value" type="text" name="criteria_value" placeholder="Enter a value">
                                    </div>
                                </div>
                            </div>

                            <div class="sales-modal-section">
                                <h4>Visibility Preference</h4>
                                <div class="sales-modal-box">
                                    <div class="sales-visibility-options">
                                        <label class="sales-visibility-option">
                                            <input type="radio" name="visibility" value="only_me" checked>
                                            <span>Only Me</span>
                                        </label>
                                        <label class="sales-visibility-option">
                                            <input type="radio" name="visibility" value="selected_roles">
                                            <span>Only Selected Users &amp; Roles</span>
                                        </label>
                                        <label class="sales-visibility-option">
                                            <input type="radio" name="visibility" value="everyone">
                                            <span>Everyone</span>
                                        </label>
                                    </div>
                                </div>
                            </div>

                            <div class="sales-modal-actions">
                                <button class="sales-modal-save" type="submit">Save</button>
                                <a class="sales-modal-cancel" href="<?php echo billing_escape(billing_sales_document_url((string) $module['list_path'], ['modal' => null])); ?>">Cancel</a>
                            </div>
                        </form>
                    </div>
                </div>
            <?php endif; ?>
        </main>
    </div>
</div>
<script src="assets/billing.js"></script>
<script>
document.querySelectorAll('.sales-inline-details').forEach(function (details) {
    details.addEventListener('toggle', function () {
        if (!details.open) {
            return;
        }

        document.querySelectorAll('.sales-inline-details').forEach(function (other) {
            if (other !== details) {
                other.open = false;
            }
        });

        var searchInput = details.querySelector('[data-filter-search]');
        if (searchInput) {
            setTimeout(function () {
                searchInput.focus();
                searchInput.select();
            }, 0);
        }

        details.querySelectorAll('[data-submenu-row]').forEach(function (row) {
            row.classList.remove('is-open');
        });
    });
});

document.addEventListener('click', function (event) {
    document.querySelectorAll('.sales-inline-details[open]').forEach(function (details) {
        if (!details.contains(event.target)) {
            details.open = false;
        }
    });
});

document.addEventListener('keydown', function (event) {
    if (event.key === 'Escape') {
        document.querySelectorAll('.sales-inline-details[open]').forEach(function (details) {
            details.open = false;
        });
    }
});

document.querySelectorAll('[data-filter-search]').forEach(function (input) {
    input.addEventListener('input', function () {
        var details = input.closest('.sales-inline-details');
        if (!details) {
            return;
        }

        var query = input.value.trim().toLowerCase();
        var options = details.querySelectorAll('[data-filter-option]');
        var visibleCount = 0;

        options.forEach(function (option) {
            var text = option.textContent.trim().toLowerCase();
            var match = query === '' || text.indexOf(query) !== -1;
            option.style.display = match ? '' : 'none';
            if (match) {
                visibleCount += 1;
            }
        });

        var empty = details.querySelector('[data-filter-empty]');
        if (empty) {
            empty.style.display = visibleCount === 0 ? 'block' : 'none';
        }
    });
});

document.querySelectorAll('[data-submenu-trigger]').forEach(function (trigger) {
    trigger.addEventListener('click', function (event) {
        event.preventDefault();
        var row = trigger.closest('[data-submenu-row]');
        if (!row) {
            return;
        }

        var details = trigger.closest('.sales-inline-details');
        if (!details) {
            return;
        }

        details.querySelectorAll('[data-submenu-row]').forEach(function (otherRow) {
            if (otherRow !== row) {
                otherRow.classList.remove('is-open');
            }
        });

        row.classList.toggle('is-open');
    });
});
</script>
</body>
</html>
