<?php
/**
 * Email Handler Class
 *
 * @package WahraRentalsBookings
 */

defined('ABSPATH') || exit;

/**
 * Handles email notifications
 */
class WAHRB_Emailer {

    /**
     * Instance
     *
     * @var WAHRB_Emailer
     */
    protected static $instance = null;

    /**
     * Get instance
     *
     * @return WAHRB_Emailer
     */
    public static function instance() {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    public function __construct() {
        add_action('wahrb_booking_created', [$this, 'on_booking_created'], 10, 2);
        add_action('wahrb_booking_status_changed', [$this, 'on_status_changed'], 10, 3);

        // Lifecycle hooks (fired by check_in(), check_out(), complete(), cancel())
        add_action('wahrb_booking_checked_in', [$this, 'on_booking_checked_in'], 10, 1);
        add_action('wahrb_booking_checked_out', [$this, 'on_booking_checked_out'], 10, 2);
        add_action('wahrb_booking_completed', [$this, 'on_booking_completed'], 10, 1);
    }

    /**
     * Handle new booking
     */
    public function on_booking_created($booking_id, $data) {
        $booking = new WAHRB_Booking($booking_id);
        if (!$booking->exists()) return;

        if ($booking->get_status() === 'pending') {
            $this->send('booking_request', $booking, null, true); // CC Admin
        } elseif ($booking->get_status() === 'confirmed') {
            $this->send('booking_confirmed', $booking);
            $this->send('booking_request', $booking, null, true); // Vendor + Admin
        }
    }

    /**
     * Handle status change (via update_status())
     */
    public function on_status_changed($booking_id, $old_status, $new_status) {
        $booking = new WAHRB_Booking($booking_id);
        if (!$booking->exists()) return;

        if ($old_status === 'pending' && $new_status === 'confirmed') {
            $this->send('booking_confirmed', $booking);
        } elseif ($old_status === 'pending' && $new_status === 'cancelled') {
            $this->send('booking_refused', $booking);
        } elseif ($new_status === 'cancelled' && $old_status !== 'pending') {
            // Send cancellation to BOTH client and vendor
            $this->send('booking_cancelled', $booking); // Default to customer
            $this->send_to_vendor('booking_cancelled', $booking); // Also to vendor
        }
    }

    /**
     * Handle booking checked in (rental started)
     *
     * @param WAHRB_Booking $booking
     */
    public function on_booking_checked_in($booking) {
        if (!$booking || !($booking instanceof WAHRB_Booking)) {
            if (is_numeric($booking)) {
                $booking = new WAHRB_Booking($booking);
            } else {
                return;
            }
        }
        if (!$booking->exists()) return;

        $this->send('booking_started', $booking);
    }

    /**
     * Handle booking checked out (rental returned)
     *
     * @param WAHRB_Booking $booking
     * @param float|null $damage_amount
     */
    public function on_booking_checked_out($booking, $damage_amount = null) {
        if (!$booking || !($booking instanceof WAHRB_Booking)) {
            if (is_numeric($booking)) {
                $booking = new WAHRB_Booking($booking);
            } else {
                return;
            }
        }
        if (!$booking->exists()) return;

        $this->send('booking_returned', $booking);
    }

    /**
     * Handle booking completed (final recap)
     *
     * @param WAHRB_Booking $booking
     */
    public function on_booking_completed($booking) {
        if (!$booking || !($booking instanceof WAHRB_Booking)) {
            if (is_numeric($booking)) {
                $booking = new WAHRB_Booking($booking);
            } else {
                return;
            }
        }
        if (!$booking->exists()) return;

        // Send recap to customer
        $this->send('booking_completed', $booking);
        // Also notify vendor
        $this->send_to_vendor('booking_completed', $booking);
    }

    /**
     * Get available email types and their defaults
     *
     * @return array
     */
    public function get_email_types() {
        return [
            'booking_request' => [
                'label' => __('New booking request (Vendor)', 'wahra-rentals-bookings'),
                'description' => __('Sent to the vendor when a new booking request is created.', 'wahra-rentals-bookings'),
                'recipient' => 'vendor',
                'variables' => ['{vendor_name}', '{customer_name}', '{product_name}', '{booking_id}', '{start_date}', '{end_date}', '{price}', '{dashboard_link}'],
                'default_subject' => __('New booking request: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {vendor_name},\n\nYou have received a new booking request from {customer_name}.\n\nProduct: {product_name}\nDates: from {start_date} to {end_date}\nPrice: {price}\n\nPlease log in to your dashboard to approve or decline this request.\n\n{dashboard_link}", 'wahra-rentals-bookings'),
            ],
            'booking_confirmed' => [
                'label' => __('Booking confirmation (Customer)', 'wahra-rentals-bookings'),
                'description' => __('Sent to the customer when the booking is confirmed.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{vendor_name}', '{product_name}', '{booking_id}', '{start_date}', '{end_date}', '{price}'],
                'default_subject' => __('Booking confirmed: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nGreat news! Your booking for {product_name} has been confirmed by {vendor_name}.\n\nDates: from {start_date} to {end_date}\n\nThank you for your trust.", 'wahra-rentals-bookings'),
            ],
            'booking_refused' => [
                'label' => __('Booking declined (Customer)', 'wahra-rentals-bookings'),
                'description' => __('Sent to the customer if the request is declined by the vendor.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{vendor_name}', '{product_name}', '{booking_id}'],
                'default_subject' => __('Booking declined: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nWe are sorry, but your booking request for {product_name} could not be accepted by {vendor_name}.\n\nNo charge has been made (or a refund has been initiated).", 'wahra-rentals-bookings'),
            ],
            'booking_cancelled' => [
                'label' => __('Booking cancellation', 'wahra-rentals-bookings'),
                'description' => __('Sent when a booking is cancelled (by customer or vendor).', 'wahra-rentals-bookings'),
                'recipient' => 'both', // Context dependent usually
                'variables' => ['{name}', '{product_name}', '{booking_id}', '{reason}'],
                'default_subject' => __('Booking cancelled: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {name},\n\nBooking #{booking_id} for {product_name} has been cancelled.\n\nBest regards.", 'wahra-rentals-bookings'),
            ],
            'booking_reminder' => [
                'label' => __('Booking reminder (Customer)', 'wahra-rentals-bookings'),
                'description' => __('Sent x days before the rental starts.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{product_name}', '{booking_id}', '{start_date}'],
                'default_subject' => __('Reminder: Your rental starts soon!', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nThis is a reminder that your booking for {product_name} starts on {start_date}.\n\nWe look forward to seeing you!", 'wahra-rentals-bookings'),
            ],
            'booking_started' => [
                'label' => __('Rental started (Customer)', 'wahra-rentals-bookings'),
                'description' => __('Sent to the customer when the rental period begins.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{vendor_name}', '{product_name}', '{booking_id}', '{start_date}', '{end_date}', '{price}'],
                'default_subject' => __('Your rental has started: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nYour rental for {product_name} has now started.\n\nBooking: #{booking_id}\nDates: from {start_date} to {end_date}\nVendor: {vendor_name}\n\nPlease remember to return the item on time.\n\nEnjoy your rental!", 'wahra-rentals-bookings'),
            ],
            'booking_returned' => [
                'label' => __('Rental returned (Customer)', 'wahra-rentals-bookings'),
                'description' => __('Sent to the customer when the rental period ends and the item is returned.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{vendor_name}', '{product_name}', '{booking_id}', '{start_date}', '{end_date}', '{price}'],
                'default_subject' => __('Rental returned: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nYour rental for {product_name} has been marked as returned.\n\nBooking: #{booking_id}\nDates: from {start_date} to {end_date}\n\nThe vendor will now validate the return. You will receive a final summary once the process is complete.\n\nThank you for using our platform!", 'wahra-rentals-bookings'),
            ],
            'booking_completed' => [
                'label' => __('Booking completed - Summary (Customer & Vendor)', 'wahra-rentals-bookings'),
                'description' => __('Sent to both customer and vendor when the booking is fully completed, with a full recap.', 'wahra-rentals-bookings'),
                'recipient' => 'customer',
                'variables' => ['{customer_name}', '{vendor_name}', '{product_name}', '{booking_id}', '{start_date}', '{end_date}', '{price}', '{payment_summary}'],
                'default_subject' => __('Booking completed - Summary: #{booking_id}', 'wahra-rentals-bookings'),
                'default_body' => __("Hello {customer_name},\n\nYour booking for {product_name} is now complete!\n\nBooking: #{booking_id}\nDates: from {start_date} to {end_date}\nVendor: {vendor_name}\n\n--- Payment Summary ---\n{payment_summary}\n\nThank you for your trust. We hope you had a great experience!\n\nSee you soon on our platform.", 'wahra-rentals-bookings'),
            ],
        ];
    }

    /**
     * Send an email
     *
     * @param string $type Email type key
     * @param WAHRB_Booking $booking Booking object
     * @param string $recipient_email Optional override
     * @param bool $cc_admin Whether to CC the site admin
     * @return bool
     */
    public function send($type, $booking, $recipient_email = null, $cc_admin = false) {
        if (!$booking) return false;

        $types = $this->get_email_types();
        if (!isset($types[$type])) return false;

        $vendor_id = $booking->get('vendor_id');
        $customer_email = $booking->get('customer_email');
        $vendor_userData = get_userdata($vendor_id);
        $vendor_email = $vendor_userData ? $vendor_userData->user_email : '';

        // Determine Recipient
        $to = $recipient_email;
        if (!$to) {
            if ($types[$type]['recipient'] === 'vendor') {
                $to = $vendor_email;
            } elseif ($types[$type]['recipient'] === 'customer' || $types[$type]['recipient'] === 'both') {
                $to = $customer_email;
            }
        }
        if (!$to) return false;

        // Get Template (Subject & Body)
        $template = $this->get_template($type, $vendor_id);
        
        // Prepare Variables
        $variables = $this->prepare_variables($booking, $vendor_id);
        
        // Compile
        $subject = $this->replace_variables($template['subject'], $variables);
        $message = $this->replace_variables($template['body'], $variables);
        
        // Headers
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        
        // CC Admin if requested
        if ($cc_admin) {
            $admin_email = get_option('admin_email');
            if ($admin_email && $admin_email !== $to) {
                $headers[] = 'Cc: ' . $admin_email;
            }
        }
        
        // Normalize line breaks: replace literal \n sequences (stored in DB/translations)
        // with actual newlines, then convert to HTML <br> tags
        $message = str_replace(['\r\n', '\n', '\r'], "\n", $message);
        $message = nl2br(esc_html($message));

        // Convert plain-text URLs to clickable links (after esc_html so they are safe)
        $message = preg_replace(
            '#(https?://[^\s<>&]+)#i',
            '<a href="$1" style="color:#2563eb;text-decoration:underline;">$1</a>',
            $message
        );
        
        // Wrap in a minimal HTML email template for consistent rendering
        $site_name = get_bloginfo('name');
        $message = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body style="font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,sans-serif;font-size:15px;line-height:1.6;color:#1e293b;margin:0;padding:0;background-color:#f1f5f9;">'
            . '<div style="max-width:600px;margin:30px auto;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.08);">'
            . '<div style="background:linear-gradient(135deg,#1e40af 0%,#3b82f6 100%);padding:24px 30px;color:#ffffff;">'
            . '<h2 style="margin:0;font-size:20px;font-weight:700;">' . esc_html($site_name) . '</h2>'
            . '</div>'
            . '<div style="padding:30px;">' . $message . '</div>'
            . '<div style="padding:20px 30px;background:#f8fafc;border-top:1px solid #e2e8f0;text-align:center;font-size:12px;color:#94a3b8;">'
            . esc_html($site_name) . '</div>'
            . '</div></body></html>';
        
        $result = wp_mail($to, $subject, $message, $headers);

        // Log the email
        $this->log_email($booking->get_id(), $type, $to, $subject, $message, $result);

        // Add a system note to the booking
        if (class_exists('WAHRB_Booking_Notes')) {
            $notes_handler = WAHRB_Booking_Notes::instance();
            $status_label = $result ? __('sent', 'wahra-rentals-bookings') : __('failed', 'wahra-rentals-bookings');
            /* translators: 1: email type, 2: recipient email, 3: sent/failed status */
            $note_content = sprintf(__('Email "%1$s" → %2$s (%3$s)', 'wahra-rentals-bookings'), $type, $to, $status_label);
            $notes_handler->add($booking->get_id(), $note_content, 'email', false, null);
        }

        return $result;
    }

    /**
     * Send booking reminder email to customer
     *
     * @param WAHRB_Booking $booking Booking object
     * @return bool
     */
    public function send_booking_reminder($booking) {
        return $this->send('booking_reminder', $booking);
    }

    /**
     * Send email specifically to vendor (for cancellation scenarios)
     *
     * @param string $type Email type key
     * @param WAHRB_Booking $booking Booking object
     * @return bool
     */
    public function send_to_vendor($type, $booking) {
        $vendor_id = $booking->get('vendor_id');
        $vendor_userData = get_userdata($vendor_id);
        $vendor_email = $vendor_userData ? $vendor_userData->user_email : '';
        
        if (!$vendor_email) return false;
        
        return $this->send($type, $booking, $vendor_email);
    }

    /**
     * Get Template (Global or Vendor Override)
     *
     * @param string $type
     * @param int $vendor_id
     * @return array [subject, body]
     */
    public function get_template($type, $vendor_id) {
        $defaults = $this->get_email_types()[$type];
        
        // 1. Check Vendor Override
        $vendor_settings = get_user_meta($vendor_id, '_wahrb_vendor_settings', true);
        if (!empty($vendor_settings['emails'][$type]['mode']) && $vendor_settings['emails'][$type]['mode'] === 'custom') {
            return [
                'subject' => $vendor_settings['emails'][$type]['subject'] ?? $defaults['default_subject'],
                'body' => $vendor_settings['emails'][$type]['body'] ?? $defaults['default_body'],
            ];
        }

        // 2. Check Global Admin Settings
        $global_settings = get_option('wahrb_settings_notifications', []);
        if (!empty($global_settings['templates'][$type]['body'])) {
             return [
                'subject' => $global_settings['templates'][$type]['subject'] ?? $defaults['default_subject'],
                'body' => $global_settings['templates'][$type]['body'],
            ];
        }

        // 3. Fallback to Hardcoded Defaults
        return [
            'subject' => $defaults['default_subject'],
            'body' => $defaults['default_body'],
        ];
    }

    /**
     * Prepare variables for replacement
     */
    private function prepare_variables($booking, $vendor_id) {
        $vendor = get_userdata($vendor_id);
        $product = wc_get_product($booking->get('product_id'));

        // Get total from pricing_snapshot (bookings table has no total_amount column)
        $pricing = $booking->get('pricing_snapshot');
        $total = 0;
        if (is_array($pricing) && isset($pricing['total'])) {
            $total = floatval($pricing['total']);
        }

        // Strip HTML from wc_price() — the email body is esc_html()'d later,
        // so raw HTML spans would show as visible tags
        $formatted_price = wp_strip_all_tags(wc_price($total));

        // Build payment summary for completed bookings
        $payment_summary = $this->build_payment_summary($booking);

        return [
            '{booking_id}' => $booking->get_id(),
            '{customer_name}' => $booking->get('customer_name'),
            '{vendor_name}' => $vendor ? $vendor->display_name : 'Vendor',
            '{product_name}' => $product ? $product->get_name() : 'Product',
            '{start_date}' => date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($booking->get('start_dt'))),
            '{end_date}' => date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($booking->get('end_dt'))),
            '{price}' => $formatted_price,
            '{payment_summary}' => $payment_summary,
            '{dashboard_link}' => wahrb_get_dashboard_url('bookings'),
            '{reason}' => '', // To be filled if context available or passed ?
            '{name}' => $booking->get('customer_name'), // Generic name for 'cancelled' context
        ];
    }

    /**
     * Build a text-based payment summary for the completed booking email
     *
     * @param WAHRB_Booking $booking
     * @return string
     */
    private function build_payment_summary($booking) {
        $schedule = $booking->get_payment_schedule();
        if (!$schedule) {
            $pricing = $booking->get('pricing_snapshot');
            $total = is_array($pricing) && isset($pricing['total']) ? floatval($pricing['total']) : 0;
            /* translators: %s: formatted total amount */
            return sprintf(__('Total: %s', 'wahra-rentals-bookings'), wp_strip_all_tags(wc_price($total)));
        }

        $lines = [];

        // Deposit
        if (!empty($schedule['deposit_enabled'])) {
            $dep_amount = wp_strip_all_tags(wc_price(floatval($schedule['deposit_amount_final'] ?? 0)));
            $dep_status = $this->translate_payment_status($schedule['deposit_status'] ?? 'not_due');
            /* translators: 1: deposit amount, 2: deposit status */
            $lines[] = sprintf(__('Deposit: %1$s (%2$s)', 'wahra-rentals-bookings'), $dep_amount, $dep_status);
        }

        // Security deposit
        if (!empty($schedule['security_deposit_enabled'])) {
            $sec_amount = wp_strip_all_tags(wc_price(floatval($schedule['security_deposit_amount_final'] ?? 0)));
            $sec_status = $this->translate_payment_status($schedule['security_status'] ?? 'not_due');
            /* translators: 1: security deposit amount, 2: security deposit status */
            $lines[] = sprintf(__('Security deposit: %1$s (%2$s)', 'wahra-rentals-bookings'), $sec_amount, $sec_status);

            // Damage claim if any
            $damage = floatval($schedule['security_damage_claim'] ?? 0);
            if ($damage > 0) {
                $damage_formatted = wp_strip_all_tags(wc_price($damage));
                /* translators: %s: damage amount */
                $lines[] = sprintf(__('Damage deducted: %s', 'wahra-rentals-bookings'), $damage_formatted);
            }
        }

        // Balance
        if (!empty($schedule['balance_enabled'])) {
            $bal_amount = wp_strip_all_tags(wc_price(floatval($schedule['balance_amount'] ?? 0)));
            $bal_status = $this->translate_payment_status($schedule['balance_status'] ?? 'not_due');
            /* translators: 1: balance amount, 2: balance status */
            $lines[] = sprintf(__('Balance: %1$s (%2$s)', 'wahra-rentals-bookings'), $bal_amount, $bal_status);
        }

        // Total
        $pricing = $booking->get('pricing_snapshot');
        $total = is_array($pricing) && isset($pricing['total']) ? floatval($pricing['total']) : 0;
        $total_formatted = wp_strip_all_tags(wc_price($total));
        /* translators: %s: total booking amount */
        $lines[] = sprintf(__('Total: %s', 'wahra-rentals-bookings'), $total_formatted);

        return implode("\n", $lines);
    }

    /**
     * Translate a payment status key to a human-readable label
     *
     * @param string $status
     * @return string
     */
    private function translate_payment_status($status) {
        $labels = [
            'not_due'           => __('Not due', 'wahra-rentals-bookings'),
            'pending'           => __('Pending', 'wahra-rentals-bookings'),
            'paid'              => __('Paid', 'wahra-rentals-bookings'),
            'failed'            => __('Failed', 'wahra-rentals-bookings'),
            'refunded'          => __('Refunded', 'wahra-rentals-bookings'),
            'partial'           => __('Partial', 'wahra-rentals-bookings'),
            'authorized'        => __('Authorized', 'wahra-rentals-bookings'),
            'captured'          => __('Captured', 'wahra-rentals-bookings'),
            'released'          => __('Released', 'wahra-rentals-bookings'),
            'forfeited'         => __('Forfeited', 'wahra-rentals-bookings'),
            'partial_forfeited' => __('Partial forfeited', 'wahra-rentals-bookings'),
        ];
        return $labels[$status] ?? $status;
    }

    /**
     * Replace variables in text
     */
    private function replace_variables($text, $variables) {
        return str_replace(array_keys($variables), array_values($variables), $text);
    }

    /**
     * Log an email to the email_logs table
     *
     * @param int    $booking_id Booking ID.
     * @param string $email_type Email type key.
     * @param string $recipient  Recipient email.
     * @param string $subject    Email subject.
     * @param string $body       Email body (HTML).
     * @param bool   $success    Whether wp_mail succeeded.
     */
    private function log_email(int $booking_id, string $email_type, string $recipient, string $subject, string $body, bool $success): void {
        global $wpdb;
        $db = WAHRB_Database::instance();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $wpdb->insert(
            $db->table('email_logs'),
            [
                'booking_id'    => $booking_id,
                'email_type'    => $email_type,
                'recipient'     => $recipient,
                'subject'       => $subject,
                'body'          => $body,
                'status'        => $success ? 'sent' : 'failed',
                'error_message' => $success ? null : __('wp_mail returned false', 'wahra-rentals-bookings'),
            ],
            ['%d', '%s', '%s', '%s', '%s', '%s', '%s']
        );
    }

    /**
     * Get email logs for a booking
     *
     * @param int $booking_id Booking ID.
     * @return array
     */
    public function get_email_logs(int $booking_id): array {
        global $wpdb;
        $db = WAHRB_Database::instance();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $logs = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM {$db->table('email_logs')} WHERE booking_id = %d ORDER BY sent_at DESC",
                $booking_id
            ),
            ARRAY_A
        );

        return $logs ?: [];
    }

    /**
     * Get SMS logs for a booking (from sms_logs table)
     *
     * @param int $booking_id Booking ID.
     * @return array
     */
    public function get_sms_logs(int $booking_id): array {
        global $wpdb;
        $db = WAHRB_Database::instance();

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $logs = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM {$db->table('sms_logs')} WHERE booking_id = %d ORDER BY sent_at DESC",
                $booking_id
            ),
            ARRAY_A
        );

        return $logs ?: [];
    }

    /**
     * Send an ad-hoc email from the booking detail page
     *
     * @param WAHRB_Booking $booking   Booking object.
     * @param string        $recipient Recipient email.
     * @param string        $subject   Email subject.
     * @param string        $body      Email body (plain text).
     * @return bool
     */
    public function send_adhoc(WAHRB_Booking $booking, string $recipient, string $subject, string $body): bool {
        $headers = ['Content-Type: text/html; charset=UTF-8'];

        // Convert to HTML
        $message = nl2br(esc_html($body));

        // Wrap in template
        $site_name = get_bloginfo('name');
        $message = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body style="font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,sans-serif;font-size:15px;line-height:1.6;color:#1e293b;margin:0;padding:0;background-color:#f1f5f9;">'
            . '<div style="max-width:600px;margin:30px auto;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.08);">'
            . '<div style="background:linear-gradient(135deg,#1e40af 0%,#3b82f6 100%);padding:24px 30px;color:#ffffff;">'
            . '<h2 style="margin:0;font-size:20px;font-weight:700;">' . esc_html($site_name) . '</h2>'
            . '</div>'
            . '<div style="padding:30px;">' . $message . '</div>'
            . '<div style="padding:20px 30px;background:#f8fafc;border-top:1px solid #e2e8f0;text-align:center;font-size:12px;color:#94a3b8;">'
            . esc_html($site_name) . '</div>'
            . '</div></body></html>';

        $result = wp_mail($recipient, $subject, $message, $headers);

        // Log it
        $this->log_email($booking->get_id(), 'adhoc', $recipient, $subject, $message, $result);

        // System note
        if (class_exists('WAHRB_Booking_Notes')) {
            $notes = WAHRB_Booking_Notes::instance();
            $status_label = $result ? __('sent', 'wahra-rentals-bookings') : __('failed', 'wahra-rentals-bookings');
            /* translators: 1: recipient, 2: subject, 3: sent/failed */
            $notes->add($booking->get_id(), sprintf(__('Ad-hoc email → %1$s: "%2$s" (%3$s)', 'wahra-rentals-bookings'), $recipient, $subject, $status_label), 'email', false, null);
        }

        return $result;
    }
}
