<?php

if (!defined('ABSPATH')) {
    exit;
}

function chbk_get_default_settings()
{
    return [
        'currency' => 'USD',
        'trips_slug' => 'charters',
        'trip_card_book_now_label' => 'Book Now',
        'payment_phone_number' => '',
        'payment_message' => 'You must call {{phone_number}} to make a deposit or make full payment before the trip.',
        'email_booking_confirmation_enabled' => 1,
        'email_payment_receipt_enabled' => 1,
        'email_deposit_reminder_enabled' => 1,
        'email_cancellation_enabled' => 1,
        'email_admin_notification_enabled' => 1,
        'email_booking_confirmation_subject' => 'Your booking is confirmed',
        'email_booking_confirmation_html' => '<p>Hi {{customer_name}}, your booking {{booking_id}} is confirmed.</p>',
        'email_booking_confirmation_text' => 'Hi {{customer_name}}, your booking {{booking_id}} is confirmed.',
        'email_admin_notification_subject' => 'New booking received',
        'email_admin_notification_html' => '<p>Booking {{booking_id}} for trip {{trip_title}}.</p>',
        'email_admin_notification_text' => 'Booking {{booking_id}} for trip {{trip_title}}.',
    ];
}

function chbk_get_setting($key, $default = null)
{
    $settings = get_option('chbk_settings', chbk_get_default_settings());
    return isset($settings[$key]) ? $settings[$key] : $default;
}

function chbk_update_setting($key, $value)
{
    $settings = get_option('chbk_settings', chbk_get_default_settings());
    $settings[$key] = $value;
    update_option('chbk_settings', $settings);
}

function chbk_get_trip_meta($trip_id, $key, $default = null)
{
    $value = get_post_meta($trip_id, $key, true);
    if ($value === '' || $value === null) {
        return $default;
    }
    return $value;
}

function chbk_get_post_id_from_value($value)
{
    return absint(is_array($value) ? 0 : $value);
}

function chbk_get_default_site_timezone()
{
    $timezone = wp_timezone_string();
    return $timezone !== '' ? $timezone : 'UTC';
}

function chbk_get_supported_currencies()
{
    return [
        'USD' => 'USD - US Dollar',
        'EUR' => 'EUR - Euro',
        'GBP' => 'GBP - British Pound',
        'CAD' => 'CAD - Canadian Dollar',
        'AUD' => 'AUD - Australian Dollar',
        'NZD' => 'NZD - New Zealand Dollar',
        'JPY' => 'JPY - Japanese Yen',
        'CNY' => 'CNY - Chinese Yuan',
        'HKD' => 'HKD - Hong Kong Dollar',
        'SGD' => 'SGD - Singapore Dollar',
        'INR' => 'INR - Indian Rupee',
        'KRW' => 'KRW - South Korean Won',
        'CHF' => 'CHF - Swiss Franc',
        'SEK' => 'SEK - Swedish Krona',
        'NOK' => 'NOK - Norwegian Krone',
        'DKK' => 'DKK - Danish Krone',
        'PLN' => 'PLN - Polish Zloty',
        'CZK' => 'CZK - Czech Koruna',
        'HUF' => 'HUF - Hungarian Forint',
        'RON' => 'RON - Romanian Leu',
        'BRL' => 'BRL - Brazilian Real',
        'MXN' => 'MXN - Mexican Peso',
        'ARS' => 'ARS - Argentine Peso',
        'CLP' => 'CLP - Chilean Peso',
        'COP' => 'COP - Colombian Peso',
        'ZAR' => 'ZAR - South African Rand',
        'AED' => 'AED - UAE Dirham',
        'SAR' => 'SAR - Saudi Riyal',
        'TRY' => 'TRY - Turkish Lira',
        'THB' => 'THB - Thai Baht',
    ];
}

function chbk_format_currency_display($amount, $currency_code = '')
{
    $currency = strtoupper(trim((string) $currency_code));
    if ($currency === '') {
        $currency = strtoupper((string) chbk_get_setting('currency', 'USD'));
    }

    $formatted = number_format((float) $amount, 2, '.', ',');
    if ($currency === 'USD') {
        return '$' . $formatted;
    }

    return $currency . ' ' . $formatted;
}

function chbk_to_utc_datetime($datetime_string, $timezone_string = '')
{
    if (empty($datetime_string)) {
        return '';
    }

    $timezone_string = $timezone_string ?: chbk_get_default_site_timezone();

    try {
        $local = new DateTime($datetime_string, new DateTimeZone($timezone_string));
        $local->setTimezone(new DateTimeZone('UTC'));
        return $local->format('Y-m-d H:i:s');
    } catch (Exception $e) {
        return '';
    }
}

function chbk_from_utc_datetime($utc_string, $timezone_string = '')
{
    if (empty($utc_string)) {
        return '';
    }

    $timezone_string = $timezone_string ?: chbk_get_default_site_timezone();

    try {
        $utc = new DateTime($utc_string, new DateTimeZone('UTC'));
        $utc->setTimezone(new DateTimeZone($timezone_string));
        return $utc->format('Y-m-d H:i:s');
    } catch (Exception $e) {
        return '';
    }
}

function chbk_parse_json_meta($value)
{
    if (is_array($value)) {
        return $value;
    }

    if (!is_string($value) || $value === '') {
        return [];
    }

    $decoded = json_decode($value, true);
    return is_array($decoded) ? $decoded : [];
}

function chbk_render_template_variables($template, $vars)
{
    $result = (string) $template;
    foreach ($vars as $key => $value) {
        $result = str_replace('{{' . $key . '}}', (string) $value, $result);
    }
    return $result;
}

function chbk_get_payment_message_for_trip($trip_id)
{
    $trip_id = (int) $trip_id;
    $override = '';
    if ($trip_id > 0) {
        $override = (string) get_post_meta($trip_id, 'chbk_payment_message_override', true);
    }

    $template = trim($override);
    if ($template === '') {
        $template = (string) chbk_get_setting('payment_message', '');
    }

    if ($template === '') {
        $template = 'You must call {{phone_number}} to make a deposit or make full payment before the trip.';
    }

    $phone = trim((string) chbk_get_setting('payment_phone_number', ''));
    return chbk_render_template_variables($template, [
        'phone_number' => $phone !== '' ? $phone : '[phone number not set]',
    ]);
}

function chbk_get_payment_ledger($booking_id)
{
    $booking_id = (int) $booking_id;
    if ($booking_id < 1) {
        return [];
    }

    $raw = get_post_meta($booking_id, 'chbk_payment_ledger', true);
    $rows = chbk_parse_json_meta($raw);
    return is_array($rows) ? $rows : [];
}

function chbk_append_payment_ledger_entry($booking_id, $entry = [])
{
    $booking_id = (int) $booking_id;
    if ($booking_id < 1) {
        return false;
    }

    $ledger = chbk_get_payment_ledger($booking_id);
    $amount = isset($entry['amount']) ? (float) $entry['amount'] : 0.0;
    if ($amount < 0) {
        $amount = 0.0;
    }

    $row = [
        'entry_id' => isset($entry['entry_id']) && (string) $entry['entry_id'] !== '' ? sanitize_text_field((string) $entry['entry_id']) : wp_generate_uuid4(),
        'date' => isset($entry['date']) ? sanitize_text_field((string) $entry['date']) : current_time('mysql'),
        'amount' => round($amount, 2),
        'method' => isset($entry['method']) ? sanitize_text_field((string) $entry['method']) : 'manual',
        'source' => isset($entry['source']) ? sanitize_text_field((string) $entry['source']) : 'admin',
        'reference' => isset($entry['reference']) ? sanitize_text_field((string) $entry['reference']) : '',
        'note' => isset($entry['note']) ? sanitize_text_field((string) $entry['note']) : '',
        'user_id' => isset($entry['user_id']) ? (int) $entry['user_id'] : get_current_user_id(),
    ];

    $ledger[] = $row;
    update_post_meta($booking_id, 'chbk_payment_ledger', wp_json_encode($ledger));
    chbk_sync_booking_payment_status_from_ledger($booking_id);
    return true;
}

function chbk_get_booking_paid_amount($booking_id)
{
    $ledger = chbk_get_payment_ledger($booking_id);
    $total = 0.0;
    foreach ($ledger as $row) {
        if (!is_array($row)) {
            continue;
        }
        $amount = isset($row['amount']) ? (float) $row['amount'] : 0.0;
        if ($amount > 0) {
            $total += $amount;
        }
    }
    return round($total, 2);
}

function chbk_update_payment_ledger_entry($booking_id, $entry_index, $entry = [])
{
    $booking_id = (int) $booking_id;
    $entry_index = (int) $entry_index;
    $ledger = chbk_get_payment_ledger($booking_id);
    if (!isset($ledger[$entry_index]) || !is_array($ledger[$entry_index])) {
        return false;
    }

    $current = $ledger[$entry_index];
    $amount = isset($entry['amount']) ? (float) $entry['amount'] : (isset($current['amount']) ? (float) $current['amount'] : 0.0);
    if ($amount < 0) {
        $amount = 0.0;
    }

    $ledger[$entry_index] = [
        'entry_id' => isset($current['entry_id']) ? sanitize_text_field((string) $current['entry_id']) : wp_generate_uuid4(),
        'date' => isset($entry['date']) ? sanitize_text_field((string) $entry['date']) : (isset($current['date']) ? sanitize_text_field((string) $current['date']) : current_time('mysql')),
        'amount' => round($amount, 2),
        'method' => isset($entry['method']) ? sanitize_text_field((string) $entry['method']) : (isset($current['method']) ? sanitize_text_field((string) $current['method']) : 'manual'),
        'source' => isset($entry['source']) ? sanitize_text_field((string) $entry['source']) : (isset($current['source']) ? sanitize_text_field((string) $current['source']) : 'admin'),
        'reference' => isset($entry['reference']) ? sanitize_text_field((string) $entry['reference']) : (isset($current['reference']) ? sanitize_text_field((string) $current['reference']) : ''),
        'note' => isset($entry['note']) ? sanitize_text_field((string) $entry['note']) : (isset($current['note']) ? sanitize_text_field((string) $current['note']) : ''),
        'user_id' => isset($current['user_id']) ? (int) $current['user_id'] : get_current_user_id(),
    ];

    update_post_meta($booking_id, 'chbk_payment_ledger', wp_json_encode(array_values($ledger)));
    chbk_sync_booking_payment_status_from_ledger($booking_id);
    return true;
}

function chbk_delete_payment_ledger_entry($booking_id, $entry_index)
{
    $booking_id = (int) $booking_id;
    $entry_index = (int) $entry_index;
    $ledger = chbk_get_payment_ledger($booking_id);
    if (!isset($ledger[$entry_index])) {
        return false;
    }

    unset($ledger[$entry_index]);
    update_post_meta($booking_id, 'chbk_payment_ledger', wp_json_encode(array_values($ledger)));
    chbk_sync_booking_payment_status_from_ledger($booking_id);
    return true;
}

function chbk_sync_booking_payment_status_from_ledger($booking_id)
{
    $booking_id = (int) $booking_id;
    if ($booking_id < 1 || get_post_type($booking_id) !== 'chbk_booking') {
        return false;
    }

    $paid = chbk_get_booking_paid_amount($booking_id);
    $total = (float) get_post_meta($booking_id, 'chbk_total_price', true);
    $deposit = (float) get_post_meta($booking_id, 'chbk_deposit_due', true);

    $next_status = 'pending_payment';
    if ($total > 0 && $paid >= $total) {
        $next_status = 'paid_full';
        update_post_meta($booking_id, 'chbk_booking_status', 'confirmed');
    } elseif ($paid > 0) {
        if ($deposit > 0 && $paid >= $deposit) {
            $next_status = 'paid_deposit';
        } else {
            $next_status = 'partial';
        }
    }

    update_post_meta($booking_id, 'chbk_payment_status', $next_status);
    return true;
}

function chbk_trip_requires_online_payment($trip_id)
{
    return (bool) apply_filters('chbk_trip_requires_online_payment', false, (int) $trip_id);
}

function chbk_consume_frontend_checkout_result($trip_id)
{
    $result = apply_filters('chbk_frontend_checkout_result', null, (int) $trip_id);
    return is_array($result) ? $result : null;
}

function chbk_start_frontend_checkout($trip_id, $booking_args, $gateway)
{
    $result = apply_filters('chbk_start_frontend_checkout', null, (int) $trip_id, is_array($booking_args) ? $booking_args : [], sanitize_key((string) $gateway));
    if ($result === null) {
        return new WP_Error('chbk_checkout_unavailable', 'Online checkout is currently unavailable.');
    }
    return $result;
}

function chbk_get_enabled_checkout_gateways()
{
    $gateways = apply_filters('chbk_enabled_checkout_gateways', []);
    return is_array($gateways) ? $gateways : [];
}

function chbk_calculate_required_payment_due_now($trip_id, $party_size, $trip_datetime_local)
{
    $result = apply_filters('chbk_required_payment_due_now', null, (int) $trip_id, max(1, (int) $party_size), sanitize_text_field((string) $trip_datetime_local));
    if (is_array($result)) {
        return $result;
    }
    return [
        'error' => 'Online checkout is currently unavailable.',
    ];
}
