<?php
/**
 * CSV Exporter for Bookings
 *
 * Handles AJAX-driven CSV export of bookings data for both
 * admin and vendor dashboards.
 *
 * @package WahraRentalsBookings
 */

defined('ABSPATH') || exit;

/**
 * CSV Exporter class
 */
class WAHRB_CSV_Exporter {

    /**
     * Single instance
     *
     * @var WAHRB_CSV_Exporter|null
     */
    private static ?WAHRB_CSV_Exporter $instance = null;

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

    /**
     * Constructor
     */
    private function __construct() {
        add_action('wp_ajax_wahrb_export_bookings_csv', [$this, 'handle_export']);
    }

    /**
     * Handle CSV export AJAX request
     */
    public function handle_export(): void {
        // Verify nonce
        if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'wahrb_export_csv')) {
            wp_die(esc_html__('Security check failed.', 'wahra-rentals-bookings'), 403);
        }

        // Check capabilities
        $is_admin = current_user_can('manage_woocommerce');
        $is_vendor = current_user_can('dokan_manage_own_bookings') || current_user_can('wahrb_manage_bookings');

        if (!$is_admin && !$is_vendor) {
            wp_die(esc_html__('You do not have permission to export bookings.', 'wahra-rentals-bookings'), 403);
        }

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

        // Build query
        $where_clauses = ['b.deleted_at IS NULL'];
        $vendor_id = 0;

        // Vendors can only export their own bookings
        if (!$is_admin) {
            $vendor_id = get_current_user_id();
            $where_clauses[] = $wpdb->prepare('(b.vendor_id = %d OR p.post_author = %d)', $vendor_id, $vendor_id);
        }

        // Apply filters from GET params
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified above
        $filter_status = isset($_GET['status']) ? sanitize_text_field(wp_unslash($_GET['status'])) : '';
        if ($filter_status) {
            $where_clauses[] = $wpdb->prepare('b.status = %s', $filter_status);
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified above
        $filter_date_from = isset($_GET['date_from']) ? sanitize_text_field(wp_unslash($_GET['date_from'])) : '';
        if ($filter_date_from && strtotime($filter_date_from)) {
            $where_clauses[] = $wpdb->prepare('b.start_dt >= %s', $filter_date_from . ' 00:00:00');
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified above
        $filter_date_to = isset($_GET['date_to']) ? sanitize_text_field(wp_unslash($_GET['date_to'])) : '';
        if ($filter_date_to && strtotime($filter_date_to)) {
            $where_clauses[] = $wpdb->prepare('b.end_dt <= %s', $filter_date_to . ' 23:59:59');
        }

        $where = implode(' AND ', $where_clauses);

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, PluginCheck.Security.DirectDB.UnescapedDBParameter -- $where clauses prepared above
        $bookings = $wpdb->get_results(
            "SELECT b.*, u.display_name as vendor_name, p.post_title as product_name,
                    ps.total_amount, ps.deposit_amount_final, ps.deposit_status,
                    ps.security_deposit_amount_final, ps.security_status,
                    ps.balance_amount_final, ps.balance_status
             FROM {$db->table('bookings')} b
             LEFT JOIN {$wpdb->users} u ON b.vendor_id = u.ID
             LEFT JOIN {$wpdb->posts} p ON b.product_id = p.ID
             LEFT JOIN {$db->table('payment_schedule')} ps ON b.booking_id = ps.booking_id
             WHERE {$where}
             ORDER BY b.created_at DESC",
            ARRAY_A
        );

        // Set headers for CSV download
        $filename = 'bookings-export-' . gmdate('Y-m-d-His') . '.csv';
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Pragma: no-cache');
        header('Expires: 0');

        // BOM for Excel UTF-8 compatibility
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV binary data
        echo "\xEF\xBB\xBF";

        $output = fopen('php://output', 'w');

        // Write header row
        $headers = [
            __('Booking No.', 'wahra-rentals-bookings'),
            __('Status', 'wahra-rentals-bookings'),
            __('Product', 'wahra-rentals-bookings'),
            __('Vendor', 'wahra-rentals-bookings'),
            __('Customer Name', 'wahra-rentals-bookings'),
            __('Customer Email', 'wahra-rentals-bookings'),
            __('Customer Phone', 'wahra-rentals-bookings'),
            __('Start Date', 'wahra-rentals-bookings'),
            __('End Date', 'wahra-rentals-bookings'),
            __('Quantity', 'wahra-rentals-bookings'),
            __('Total Amount', 'wahra-rentals-bookings'),
            __('Deposit Amount', 'wahra-rentals-bookings'),
            __('Deposit Status', 'wahra-rentals-bookings'),
            __('Security Deposit', 'wahra-rentals-bookings'),
            __('Security Status', 'wahra-rentals-bookings'),
            __('Balance Amount', 'wahra-rentals-bookings'),
            __('Balance Status', 'wahra-rentals-bookings'),
            __('Booking Mode', 'wahra-rentals-bookings'),
            __('Customer Notes', 'wahra-rentals-bookings'),
            __('Created At', 'wahra-rentals-bookings'),
        ];
        fputcsv($output, $headers);

        // Write data rows
        foreach ($bookings as $booking) {
            $row = [
                $booking['booking_number'],
                ucfirst($booking['status']),
                $booking['product_name'] ?: 'Product #' . $booking['product_id'],
                $booking['vendor_name'] ?: 'Vendor #' . $booking['vendor_id'],
                $booking['customer_name'],
                $booking['customer_email'],
                $booking['customer_phone'],
                date_i18n('Y-m-d H:i', strtotime($booking['start_dt'])),
                date_i18n('Y-m-d H:i', strtotime($booking['end_dt'])),
                $booking['qty'],
                number_format(floatval($booking['total_amount'] ?? 0), 2, '.', ''),
                number_format(floatval($booking['deposit_amount_final'] ?? 0), 2, '.', ''),
                $booking['deposit_status'] ?? '',
                number_format(floatval($booking['security_deposit_amount_final'] ?? 0), 2, '.', ''),
                $booking['security_status'] ?? '',
                number_format(floatval($booking['balance_amount_final'] ?? 0), 2, '.', ''),
                $booking['balance_status'] ?? '',
                $booking['booking_mode'],
                $booking['notes_customer'] ?? '',
                date_i18n('Y-m-d H:i', strtotime($booking['created_at'])),
            ];
            fputcsv($output, $row);
        }

        fclose($output);
        exit;
    }

    /**
     * Get the CSV export URL with nonce
     *
     * @param array $args Optional filter args (status, date_from, date_to).
     * @return string
     */
    public static function get_export_url(array $args = []): string {
        $base_args = [
            'action'   => 'wahrb_export_bookings_csv',
            '_wpnonce' => wp_create_nonce('wahrb_export_csv'),
        ];

        return add_query_arg(array_merge($base_args, $args), admin_url('admin-ajax.php'));
    }
}
