<?php

require_once __DIR__ . '/helpers.php';

function expense_current_organization_id(): int
{
    $userId = current_user_id();
    if ($userId <= 0) {
        return 0;
    }

    $row = fetch_one(
        'SELECT id
         FROM organizations
         WHERE user_id = ?
         ORDER BY id DESC
         LIMIT 1',
        'i',
        [$userId]
    );

    return (int) ($row['id'] ?? 0);
}

function expense_picker_format_date(?string $value): string
{
    $value = trim((string) $value);
    if ($value === '') {
        return '';
    }

    $timestamp = strtotime($value);
    return $timestamp ? date('d M Y', $timestamp) : $value;
}

function expense_category_catalog(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $items = [];
    $seen = [];

    $push = static function (string $label, string $icon = 'fa-solid fa-tag', string $meta = '') use (&$items, &$seen): void {
        $label = trim($label);
        if ($label === '') {
            return;
        }

        $key = function_exists('mb_strtolower') ? mb_strtolower($label) : strtolower($label);
        if (isset($seen[$key])) {
            return;
        }

        $seen[$key] = true;
        $items[] = [
            'label' => $label,
            'value' => $label,
            'meta' => $meta,
            'icon' => $icon,
        ];
    };

    $userId = current_user_id();
    if ($userId > 0) {
        $organizationId = expense_current_organization_id();
        if ($organizationId > 0) {
            $rows = fetch_all(
                'SELECT
                    COALESCE(NULLIF(TRIM(category_name), ""), "") AS category_name,
                    COALESCE(NULLIF(TRIM(category_code), ""), "") AS category_code,
                    COALESCE(NULLIF(TRIM(expense_type), ""), "") AS expense_type
                 FROM expense_categories
                 WHERE organization_id = ? AND is_deleted = 0 AND status = "active"
                 ORDER BY sort_order ASC, category_name ASC
                 LIMIT 50',
                'i',
                [$organizationId]
            );

            foreach ($rows as $row) {
                $label = trim((string) ($row['category_name'] ?? ''));
                if ($label === '') {
                    continue;
                }

                $metaBits = [];
                $categoryCode = trim((string) ($row['category_code'] ?? ''));
                $expenseType = trim((string) ($row['expense_type'] ?? ''));
                if ($categoryCode !== '') {
                    $metaBits[] = $categoryCode;
                }
                if ($expenseType !== '') {
                    $metaBits[] = $expenseType;
                }

                $push($label, trim((string) ($row['icon_class'] ?? 'fa-solid fa-tag')) ?: 'fa-solid fa-tag', implode(' | ', $metaBits));
            }
        }

        $rows = fetch_all(
            'SELECT category_name
             FROM expense_report_items
             WHERE user_id = ? AND is_deleted = 0 AND deleted_at IS NULL AND TRIM(category_name) <> ""
             GROUP BY COALESCE(NULLIF(TRIM(category_name), ""), "")
             ORDER BY COUNT(*) DESC, category_name ASC
             LIMIT 20',
            'i',
            [$userId]
        );

        foreach ($rows as $row) {
            $push((string) ($row['category_name'] ?? ''), 'fa-solid fa-tag');
        }

        $defaultExpense = fetch_one(
            'SELECT expense_category
             FROM user_default_expense_values
             WHERE user_id = ? AND is_deleted = 0 AND deleted_at IS NULL
             ORDER BY id DESC
             LIMIT 1',
            'i',
            [$userId]
        );

        if ($defaultExpense) {
            $push((string) ($defaultExpense['expense_category'] ?? ''), 'fa-solid fa-tag');
        }
    }

    foreach ([
        ['Automobile Expense', 'fa-solid fa-car-side'],
        ['Fuel/Mileage Expenses', 'fa-solid fa-gas-pump'],
        ['IT and Internet Expenses', 'fa-solid fa-globe'],
        ['Lodging', 'fa-solid fa-hotel'],
        ['Meals and Entertainment', 'fa-solid fa-utensils'],
        ['Office Supplies', 'fa-solid fa-briefcase'],
        ['Other Expenses', 'fa-solid fa-money-bill-wave'],
        ['Parking', 'fa-solid fa-square-parking'],
        ['TDS Payable', 'fa-solid fa-file-invoice-dollar'],
        ['Telephone Expense', 'fa-solid fa-phone'],
        ['Travel Expense', 'fa-solid fa-plane'],
    ] as [$label, $icon]) {
        $push($label, $icon);
    }

    $cache = $items;
    return $cache;
}

function expense_report_picker_catalog(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $items = [];
    $seen = [];
    $userId = current_user_id();

    if ($userId > 0) {
        $rows = fetch_all(
            'SELECT
                r.id,
                r.report_title,
                r.start_date,
                r.end_date,
                t.trip_name,
                t.destination
             FROM expense_reports r
             LEFT JOIN expense_trips t ON t.id = r.trip_id
             WHERE r.user_id = ? AND r.is_deleted = 0 AND r.deleted_at IS NULL
             ORDER BY COALESCE(r.submitted_at, r.created_at) DESC, r.id DESC
             LIMIT 20',
            'i',
            [$userId]
        );

        foreach ($rows as $row) {
            $label = trim((string) ($row['report_title'] ?? ''));
            if ($label === '') {
                continue;
            }

            $key = function_exists('mb_strtolower') ? mb_strtolower($label) : strtolower($label);
            if (isset($seen[$key])) {
                continue;
            }

            $seen[$key] = true;
            $metaBits = [];

            $start = expense_picker_format_date((string) ($row['start_date'] ?? ''));
            $end = expense_picker_format_date((string) ($row['end_date'] ?? ''));
            if ($start !== '' && $end !== '') {
                $metaBits[] = $start . ' - ' . $end;
            }

            $tripName = trim((string) ($row['trip_name'] ?? ''));
            $destination = trim((string) ($row['destination'] ?? ''));
            if ($tripName !== '') {
                $metaBits[] = $tripName;
            } elseif ($destination !== '') {
                $metaBits[] = $destination;
            }

            $items[] = [
                'label' => $label,
                'value' => (string) ($row['id'] ?? $label),
                'meta' => implode(' | ', $metaBits),
                'icon' => 'fa-regular fa-file-lines',
            ];
        }
    }

    if ($items === []) {
        $items[] = [
            'label' => 'report-01',
            'value' => 'report-01',
            'meta' => '16 Apr 2026 - 30 Apr 2026 | Ahuas',
            'icon' => 'fa-regular fa-file-lines',
        ];
    }

    $cache = $items;
    return $cache;
}

function expense_merchant_picker_catalog(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $items = [];
    $seen = [];
    $userId = current_user_id();

    if ($userId > 0) {
        $rows = fetch_all(
            'SELECT
                COALESCE(NULLIF(TRIM(merchant_name), ""), "") AS merchant_name,
                COUNT(*) AS merchant_count
             FROM expense_report_items
             WHERE user_id = ? AND is_deleted = 0 AND deleted_at IS NULL AND TRIM(merchant_name) <> ""
             GROUP BY COALESCE(NULLIF(TRIM(merchant_name), ""), "")
             ORDER BY COUNT(*) DESC, merchant_name ASC
             LIMIT 20',
            'i',
            [$userId]
        );

        foreach ($rows as $row) {
            $label = trim((string) ($row['merchant_name'] ?? ''));
            if ($label === '') {
                continue;
            }

            $key = function_exists('mb_strtolower') ? mb_strtolower($label) : strtolower($label);
            if (isset($seen[$key])) {
                continue;
            }

            $seen[$key] = true;
            $count = (int) ($row['merchant_count'] ?? 0);
            $items[] = [
                'label' => $label,
                'value' => $label,
                'meta' => $count > 0 ? $count . ' expense' . ($count === 1 ? '' : 's') : '',
                'icon' => 'fa-solid fa-store',
            ];
        }
    }

    if ($items === []) {
        $items = [
            ['label' => 'Starbucks', 'value' => 'Starbucks', 'meta' => 'Recent merchant', 'icon' => 'fa-solid fa-store'],
            ['label' => 'Amazon', 'value' => 'Amazon', 'meta' => 'Recent merchant', 'icon' => 'fa-solid fa-store'],
            ['label' => 'Uber', 'value' => 'Uber', 'meta' => 'Recent merchant', 'icon' => 'fa-solid fa-store'],
        ];
    }

    $cache = $items;
    return $cache;
}

function expense_currency_picker_catalog(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $items = [];
    $seen = [];
    $nameMap = [
        'INR' => 'Indian Rupee',
        'USD' => 'US Dollar',
        'EUR' => 'Euro',
        'GBP' => 'Pound Sterling',
        'AUD' => 'Australian Dollar',
        'CAD' => 'Canadian Dollar',
        'CNY' => 'Yuan Renminbi',
        'SGD' => 'Singapore Dollar',
    ];

    $push = static function (string $code) use (&$items, &$seen, $nameMap): void {
        $code = strtoupper(trim($code));
        if ($code === '' || isset($seen[$code])) {
            return;
        }

        $seen[$code] = true;
        $items[] = [
            'label' => $code,
            'value' => $code,
            'meta' => $nameMap[$code] ?? 'Currency',
            'icon' => 'fa-solid fa-coins',
        ];
    };

    foreach (['INR', 'USD', 'EUR', 'GBP', 'AUD', 'CAD', 'CNY', 'SGD'] as $code) {
        $push($code);
    }

    $userId = current_user_id();
    if ($userId > 0) {
        $rows = fetch_all(
            'SELECT currency_code
             FROM expense_reports
             WHERE user_id = ? AND is_deleted = 0 AND deleted_at IS NULL AND TRIM(currency_code) <> ""
             UNION
             SELECT default_currency AS currency_code
             FROM user_default_expense_values
             WHERE user_id = ? AND is_deleted = 0 AND deleted_at IS NULL AND TRIM(default_currency) <> ""
             ORDER BY currency_code ASC',
            'ii',
            [$userId, $userId]
        );

        foreach ($rows as $row) {
            $push((string) ($row['currency_code'] ?? ''));
        }
    }

    $cache = $items;
    return $cache;
}

function expense_payment_picker_catalog(): array
{
    static $cache = null;
    if ($cache !== null) {
        return $cache;
    }

    $items = [];
    $seen = [];

    $push = static function (string $label, string $meta, string $icon = 'fa-solid fa-wallet') use (&$items, &$seen): void {
        $label = trim($label);
        if ($label === '') {
            return;
        }

        $key = function_exists('mb_strtolower') ? mb_strtolower($label) : strtolower($label);
        if (isset($seen[$key])) {
            return;
        }

        $seen[$key] = true;
        $items[] = [
            'label' => $label,
            'value' => $label,
            'meta' => $meta,
            'icon' => $icon,
        ];
    };

    $push('Petty Cash', 'Cash on hand', 'fa-solid fa-cash-register');
    $push('Undeposited Funds', 'Unapplied balance', 'fa-solid fa-circle-pause');

    $userId = current_user_id();
    if ($userId > 0) {
        $rows = fetch_all(
            'SELECT account_name, bank_name
             FROM user_bank_accounts
             WHERE user_id = ? AND status = "active"
             ORDER BY is_primary DESC, id DESC
             LIMIT 10',
            'i',
            [$userId]
        );

        foreach ($rows as $row) {
            $label = trim((string) ($row['account_name'] ?? ''));
            if ($label === '') {
                continue;
            }
            $meta = trim((string) ($row['bank_name'] ?? ''));
            if ($meta === '') {
                $meta = 'Bank account';
            }
            $push($label, $meta, 'fa-solid fa-building-columns');
        }
    }

    $cache = $items;
    return $cache;
}

function render_expense_picker(
    string $id,
    string $kind,
    string $name,
    string $selectedLabel = '',
    string $selectedValue = '',
    string $extraClass = '',
    bool $showFooter = false,
    bool $autoSelectFirst = false
): void {
    $catalog = match ($kind) {
        'category' => expense_category_catalog(),
        'report' => expense_report_picker_catalog(),
        'merchant' => expense_merchant_picker_catalog(),
        'currency' => expense_currency_picker_catalog(),
        'paid_through' => expense_payment_picker_catalog(),
        default => [],
    };

    $selectedLabel = trim($selectedLabel);
    $selectedValue = trim($selectedValue);
    if ($autoSelectFirst && $selectedLabel === '' && $selectedValue === '' && $catalog !== []) {
        $selectedLabel = (string) ($catalog[0]['label'] ?? '');
        $selectedValue = (string) ($catalog[0]['value'] ?? '');
    }

    $rootClass = trim('expense-picker expense-picker--' . $kind . ' ' . $extraClass);
    ?>
    <div class="<?= e($rootClass) ?>" data-expense-picker data-expense-picker-kind="<?= e($kind) ?>" data-expense-picker-id="<?= e($id) ?>">
        <input type="hidden" name="<?= e($name) ?>" value="<?= e($selectedValue) ?>" data-expense-picker-value>
        <button type="button" class="expense-picker-toggle" data-expense-picker-toggle aria-expanded="false">
            <span class="expense-picker-label" data-expense-picker-label><?= e($selectedLabel !== '' ? $selectedLabel : 'Select') ?></span>
            <i class="fa-solid fa-caret-down" aria-hidden="true"></i>
        </button>

        <div class="expense-picker-popover" data-expense-picker-popover hidden>
            <div class="expense-picker-search-wrap">
                <i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
                <input type="search" class="expense-picker-search" placeholder="Search" data-expense-picker-search>
            </div>

            <div class="expense-picker-list" role="listbox" aria-label="<?= e(ucfirst(str_replace('_', ' ', $kind))) ?>">
                <?php foreach ($catalog as $item): ?>
                    <?php
                        $itemLabel = (string) ($item['label'] ?? '');
                        $itemMeta = trim((string) ($item['meta'] ?? ''));
                        $itemIcon = (string) ($item['icon'] ?? 'fa-solid fa-tag');
                        $itemValue = (string) ($item['value'] ?? $itemLabel);
                        $search = strtolower(trim($itemLabel . ' ' . $itemMeta));
                    ?>
                    <button
                        type="button"
                        class="expense-picker-option<?= $selectedValue !== '' && $selectedValue === $itemValue ? ' is-selected' : '' ?>"
                        data-expense-picker-option
                        data-picker-value="<?= e($itemValue) ?>"
                        data-picker-label="<?= e($itemLabel) ?>"
                        data-picker-search="<?= e($search) ?>"
                    >
                        <i class="<?= e($itemIcon) ?>" aria-hidden="true"></i>
                        <span class="expense-picker-copy">
                            <strong><?= e($itemLabel) ?></strong>
                            <?php if ($itemMeta !== ''): ?>
                                <span><?= e($itemMeta) ?></span>
                            <?php endif; ?>
                        </span>
                    </button>
                <?php endforeach; ?>
            </div>

            <?php if ($showFooter): ?>
                <div class="expense-picker-footer">
                    <a href="<?= e(page_url('my_settings', 'navType=preferences&dialog=expense-category')) ?>" data-expense-category-open>+ New Category</a>
                    <a href="<?= e(page_url('my_settings', 'navType=preferences')) ?>" class="expense-picker-manage-link"><i class="fa-solid fa-gear" aria-hidden="true"></i> Manage <i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>
                </div>
            <?php endif; ?>
        </div>
    </div>
    <?php
}

function render_expense_category_dialog(string $returnHref): void
{
    $returnHref = trim($returnHref);
    if ($returnHref === '') {
        $returnHref = route_url('expenses/new/');
    }

    $workspaceName = trim((string) ($_SESSION['workspace_name'] ?? ''));
    if ($workspaceName === '') {
        $workspaceName = 'demo';
    }
    $policyOptions = [];
    foreach (['All', $workspaceName] as $policyLabel) {
        $policyLabel = trim($policyLabel);
        if ($policyLabel === '' || in_array($policyLabel, $policyOptions, true)) {
            continue;
        }
        $policyOptions[] = $policyLabel;
    }

    ?>
    <div class="expense-category-overlay" data-expense-category-overlay aria-hidden="true">
        <div class="expense-category-backdrop" data-expense-category-close></div>
        <section class="expense-category-dialog" data-expense-category-dialog role="dialog" aria-modal="true" aria-labelledby="expenseCategoryTitle">
            <form method="post" action="<?= e(page_url('my_settings', 'navType=preferences&dialog=expense-category')) ?>">
                <input type="hidden" name="return_to" value="<?= e($returnHref) ?>">
                <header class="expense-category-header">
                    <h3 id="expenseCategoryTitle">New Category</h3>
                    <button type="button" class="expense-category-close" data-expense-category-close aria-label="Close">
                        <i class="fa-solid fa-xmark" aria-hidden="true"></i>
                    </button>
                </header>

                <div class="expense-category-body">
                    <div class="expense-category-avatar">
                        <div class="expense-category-avatar-box" aria-hidden="true">
                            <i class="fa-solid fa-money-bill-1-wave"></i>
                        </div>
                        <button type="button" class="expense-category-avatar-change">Change</button>
                    </div>

                    <div class="expense-category-form">
                        <input type="hidden" name="category_id" value="">
                        <label class="expense-category-field expense-category-field--wide expense-category-field--required">
                            <span>Category Name *</span>
                            <input type="text" name="category_name" placeholder="Enter category name" required>
                        </label>
                        <label class="expense-category-subcategory">
                            <input type="checkbox" name="is_sub_category" value="1">
                            <span>Make this a sub-category</span>
                        </label>
                        <label class="expense-category-field expense-category-field--wide">
                            <span>Account Code</span>
                            <input type="text" name="category_code" maxlength="50" placeholder="A unique reference code">
                            <small>A unique reference code for this category that is limited to 50 characters and can comprise of letters, digits, hyphen and underscore</small>
                        </label>
                        <label class="expense-category-field expense-category-field--wide">
                            <span>Expense Type <i class="fa-regular fa-circle-question expense-category-label-help" aria-hidden="true"></i></span>
                            <select name="expense_type">
                                <option value="">Select</option>
                                <option value="Business">Business</option>
                                <option value="Personal">Personal</option>
                                <option value="Reimbursable">Reimbursable</option>
                                <option value="Non-Reimbursable">Non-Reimbursable</option>
                            </select>
                        </label>
                        <label class="expense-category-field expense-category-field--wide">
                            <span>Description</span>
                            <textarea name="description" rows="4" maxlength="500" placeholder="Max 500 characters"></textarea>
                        </label>
                        <label class="expense-category-field expense-category-field--wide">
                            <span>Policies</span>
                            <div class="expense-policy-picker" data-expense-policy-picker>
                                <input type="hidden" name="policy_name" value="" data-expense-policy-value>
                                <button type="button" class="expense-policy-toggle" data-expense-policy-toggle aria-expanded="false">
                                    <span class="expense-policy-label" data-expense-policy-label>Select</span>
                                    <i class="fa-solid fa-caret-down" aria-hidden="true"></i>
                                </button>

                                <div class="expense-policy-popover" data-expense-policy-popover hidden>
                                    <div class="expense-policy-search-wrap">
                                        <i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i>
                                        <input type="search" class="expense-policy-search" placeholder="Search" data-expense-policy-search>
                                    </div>

                                    <div class="expense-policy-list" role="listbox" aria-label="Policies">
                                        <?php foreach ($policyOptions as $policyLabel): ?>
                                            <?php $policySearch = strtolower($policyLabel); ?>
                                            <button
                                                type="button"
                                                class="expense-policy-option"
                                                data-expense-policy-option
                                                data-policy-value="<?= e($policyLabel) ?>"
                                                data-policy-label="<?= e($policyLabel) ?>"
                                                data-policy-search="<?= e($policySearch) ?>"
                                            >
                                                <span class="expense-policy-option-check" aria-hidden="true"></span>
                                                <span class="expense-policy-option-label"><?= e($policyLabel) ?></span>
                                            </button>
                                        <?php endforeach; ?>
                                    </div>
                                </div>
                            </div>
                        </label>
                        <div class="expense-category-note expense-category-field--wide">
                            <strong>Note :</strong>
                            <span>You have the same organization in Zoho Books, Zoho Payroll. Altering any information on this page will alter it there.</span>
                        </div>

                    </div>
                </div>

                <footer class="expense-category-footer">
                    <button type="submit" name="settings_action" value="save_expense_category" class="expense-category-primary">Save and Select</button>
                    <button type="button" class="expense-category-secondary" data-expense-category-close>Cancel</button>
                </footer>
            </form>
        </section>
    </div>
    <?php
}

function render_expense_category_picker(
    string $id,
    string $name = 'category_name',
    string $selectedLabel = '',
    string $selectedValue = '',
    string $extraClass = ''
): void {
    render_expense_picker($id, 'category', $name, $selectedLabel, $selectedValue, $extraClass, true, false);
}
