<?php
/**
 * Balance (solde) handler
 *
 * @package WahraRentalsBookings
 */

defined('ABSPATH') || exit;

/**
 * Balance handler class
 */
class WAHRB_Balance_Handler {

    /**
     * Maybe create balance order after deposit is paid
     *
     * @param WAHRB_Booking $booking Booking object
     * @return WC_Order|null
     */
    public static function maybe_create_balance_order(WAHRB_Booking $booking): ?WC_Order {
        $schedule = $booking->get_payment_schedule();

        if (!$schedule || !$schedule['balance_enabled'] || $schedule['balance_amount_final'] <= 0) {
            return null;
        }

        // Check if balance order already exists
        if (!empty($schedule['balance_order_id'])) {
            return wc_get_order($schedule['balance_order_id']);
        }

        return WAHRB_Payment_Manager::instance()->create_balance_order($booking);
    }

    /**
     * Process pending balance orders (cron job)
     */
    public static function process_pending_orders(): void {
        global $wpdb;
        $db = WAHRB_Database::instance();

        // Find bookings where balance is due soon and order not created
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom tables
        $pending = $wpdb->get_results(
            "SELECT ps.*, b.customer_email, b.customer_name
             FROM {$db->table('payment_schedule')} ps
             JOIN {$db->table('bookings')} b ON ps.booking_id = b.booking_id
             WHERE ps.balance_enabled = 1
             AND ps.balance_status = 'not_due'
             AND ps.balance_order_id IS NULL
             AND ps.deposit_status = 'paid'
             AND ps.balance_due_at <= DATE_ADD(NOW(), INTERVAL 1 DAY)
             AND b.status NOT IN ('cancelled', 'failed')
             AND b.deleted_at IS NULL
             LIMIT 50" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        );

        foreach ($pending as $schedule) {
            $booking = new WAHRB_Booking($schedule->booking_id);
            if ($booking->exists()) {
                $order = WAHRB_Payment_Manager::instance()->create_balance_order($booking);

                if ($order && !is_wp_error($order)) {
                    // Send reminder email
                    self::send_balance_reminder($booking, $order);
                }
            }
        }
    }

    /**
     * Send balance reminder email
     *
     * @param WAHRB_Booking $booking Booking
     * @param WC_Order $order Balance order
     */
    private static function send_balance_reminder(WAHRB_Booking $booking, WC_Order $order): void {
        $customer_email = $booking->get('customer_email');
        if (!$customer_email) {
            return;
        }

        $subject = sprintf(
            /* translators: 1: site name, 2: booking number */
            __('[%1$s] Balance due for your booking #%2$s', 'wahra-rentals-bookings'),
            get_bloginfo('name'),
            $booking->get_booking_number()
        );

        $pay_url = $order->get_checkout_payment_url();
        $schedule = $booking->get_payment_schedule();

        $message = sprintf(
            /* translators: 1: customer name, 2: booking number, 3: balance amount with currency, 4: due date, 5: payment URL */
            __("Hello %1\$s,\n\nThe balance for your booking #%2\$s is now due.\n\nAmount: %3\$s\nDue date: %4\$s\n\nTo pay your balance, click here:\n%5\$s\n\nThank you!", 'wahra-rentals-bookings'),
            $booking->get('customer_name'),
            $booking->get_booking_number(),
            html_entity_decode(wp_strip_all_tags(wc_price($schedule['balance_amount_final']))),
            date_i18n(get_option('date_format'), strtotime($schedule['balance_due_at'])),
            $pay_url
        );

        wp_mail($customer_email, $subject, $message);

        // Log
        WAHRB_Database::instance()->log('balance_reminder_sent', 'booking', $booking->get_id());
    }

    /**
     * Mark COD balance as paid (vendor action)
     *
     * @param int $booking_id Booking ID
     * @return bool
     */
    public static function mark_cod_paid(int $booking_id): bool {
        $booking = new WAHRB_Booking($booking_id);
        if (!$booking->exists()) {
            return false;
        }

        $schedule = $booking->get_payment_schedule();
        if (!$schedule || $schedule['balance_status'] === 'paid') {
            return false;
        }

        $order_id = $schedule['balance_order_id'];
        if ($order_id) {
            $order = wc_get_order($order_id);
            if ($order && $order->get_payment_method() === 'cod') {
                $order->payment_complete();
            }
        }

        global $wpdb;
        $db = WAHRB_Database::instance();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom table update
        $wpdb->update(
            $db->table('payment_schedule'),
            [
                'balance_status' => 'paid',
                'balance_paid_at' => current_time('mysql'),
            ],
            ['booking_id' => $booking_id]
        );

        $db->log('cod_balance_paid', 'booking', $booking_id);

        return true;
    }
}
