<?php
/**
 * Security deposit (caution) handler
 *
 * @package WahraRentalsBookings
 */

defined('ABSPATH') || exit;

/**
 * Security deposit class
 */
class WAHRB_Security_Deposit {

    /**
     * Calculate security deposit amount
     *
     * @param int $product_id Product ID
     * @param float $total Booking total
     * @param array $settings Settings
     * @return float
     */
    public static function calculate(int $product_id, float $total, array $settings): float {
        // Check product-level setting first
        $product_amount = get_post_meta($product_id, '_wahrb_security_deposit', true);
        if ($product_amount !== '') {
            return floatval($product_amount);
        }

        if (empty($settings['security_deposit_enabled'])) {
            return 0;
        }

        $type = $settings['security_deposit_type'] ?? 'fixed';
        $value = floatval($settings['security_deposit_value'] ?? 0);

        if ($type === 'percent') {
            return round($total * ($value / 100), 2);
        }

        return $value;
    }

    /**
     * Capture security deposit (for capture mode)
     *
     * @param int $booking_id Booking ID
     * @return bool
     */
    public static function capture(int $booking_id): bool {
        global $wpdb;
        $db = WAHRB_Database::instance();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
        return $wpdb->update(
            $db->table('payment_schedule'),
            [
                'security_status' => 'captured',
                'security_captured_at' => current_time('mysql'),
            ],
            ['booking_id' => $booking_id]
        ) !== false;
    }

    /**
     * Release security deposit
     *
     * @param int $booking_id Booking ID
     * @return bool
     */
    public static function release(int $booking_id): bool {
        $booking = new WAHRB_Booking($booking_id);
        $schedule = $booking->get_payment_schedule();

        if (!$schedule || $schedule['security_status'] !== 'captured') {
            return false;
        }

        $amount = floatval($schedule['security_deposit_amount_final']);

        // Refund via WooCommerce
        $order_id = $schedule['deposit_order_id'];
        if ($order_id && $amount > 0) {
            $order = wc_get_order($order_id);
            if ($order) {
                $refund = wc_create_refund([
                    'amount' => $amount,
                    'reason' => __('Security deposit return', 'wahra-rentals-bookings'),
                    'order_id' => $order_id,
                    'refund_payment' => true,
                ]);

                if (is_wp_error($refund)) {
                    return false;
                }
            }
        }

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

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

        $db->log('security_deposit_released', 'booking', $booking_id, [
            'amount' => $amount,
        ]);

        return true;
    }

    /**
     * Refund partial security deposit
     *
     * @param int $booking_id Booking ID
     * @param float $refund_amount Amount to refund
     * @return bool
     */
    public static function refund(int $booking_id, float $refund_amount): bool {
        $booking = new WAHRB_Booking($booking_id);
        $schedule = $booking->get_payment_schedule();

        if (!$schedule) {
            return false;
        }

        $order_id = $schedule['deposit_order_id'];
        if ($order_id && $refund_amount > 0) {
            $order = wc_get_order($order_id);
            if ($order) {
                $refund = wc_create_refund([
                    'amount' => $refund_amount,
                    'reason' => __('Partial security deposit return', 'wahra-rentals-bookings'),
                    'order_id' => $order_id,
                    'refund_payment' => true,
                ]);

                if (is_wp_error($refund)) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * Forfeit security deposit (keep for damages)
     *
     * @param int $booking_id Booking ID
     * @param float $damage_amount Damage amount
     * @param string $notes Notes about damages
     * @return bool
     */
    public static function forfeit(int $booking_id, float $damage_amount, string $notes = ''): bool {
        $booking = new WAHRB_Booking($booking_id);
        $schedule = $booking->get_payment_schedule();

        if (!$schedule) {
            return false;
        }

        $security_amount = floatval($schedule['security_deposit_amount_final']);
        $status = $damage_amount >= $security_amount ? 'forfeited' : 'partial_forfeited';
        $refund_amount = max(0, $security_amount - $damage_amount);

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

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $wpdb->update(
            $db->table('payment_schedule'),
            [
                'security_status' => $status,
                'security_released_at' => current_time('mysql'),
                'security_damage_claim' => $damage_amount,
                'security_damage_notes' => $notes,
            ],
            ['booking_id' => $booking_id]
        );

        // Refund remainder if any
        if ($refund_amount > 0) {
            self::refund($booking_id, $refund_amount);
        }

        $db->log('security_deposit_forfeited', 'booking', $booking_id, [
            'damage_amount' => $damage_amount,
            'refund_amount' => $refund_amount,
            'notes' => $notes,
        ]);

        return true;
    }
}
