<?php

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


class Irep_Reservation
{
    protected $wpdb;
    protected $table_name;



    public function __construct()
    {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->table_name = 'irep_reservations';
    }



    public function get_reservations($data)
    {

        if (!$this->is_gold()) {
            irep_upgrade_plan();
        }

        $data = [
            'nonce'        => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'sort_field'   => isset($data['sort_field']) ? sanitize_text_field($data['sort_field']) : '',
            'sort_order'   => isset($data['sort_order']) ? sanitize_text_field($data['sort_order']) : '',
            'page'         => isset($data['page']) ? absint($data['page']) : 1,
            'per_page'     => isset($data['per_page']) ? absint($data['per_page']) : 8,
            'search'       => isset($data['search']) ? sanitize_text_field($data['search']) : '',
        ];



        // Check nonce for security
        irep_check_nonce($data['nonce'], 'irep_nonce');

        // Sanitize and filter sorting parameters
        $data = irep_sanitize_sorting_parameters($data, ['id', 'name', 'phone', 'email']);


        $query = Irep_DB::table($this->table_name);

        $searchTerm = '%' . $data['search'] . '%';

        if (!empty($data['search'])) {
            $query->where('name', 'LIKE', $searchTerm)
                ->orWhere('id', 'LIKE', $searchTerm)
                ->orWhere('phone', 'LIKE', $searchTerm)
                ->orWhere('email', 'LIKE', $searchTerm);
        }


        $results = $query->orderBy($data['sort_field'], $data['sort_order'])
            ->paginate($data['page'], $data['per_page']);



        if (!$results) {
            return [false,  'something went wrong!'];
        }

        $this->enrich_reservations_with_flat_names($results);

        return [true, $results];
    }



    public function create_reservation($data)
    {

        if (!$this->is_gold()) {
            irep_upgrade_plan();
        }


        $data = [
            'project_id'   => isset($data['project_id']) ? absint($data['project_id']) : 0,
            'nonce'        => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'flat_id'      => isset($data['flat_id']) ? absint($data['flat_id']) : 0,
            'name'         => isset($data['name']) ? sanitize_text_field($data['name']) : '',
            'phone'        => isset($data['phone']) ? sanitize_text_field($data['phone']) : '',
            'email'        => isset($data['email']) ? sanitize_text_field($data['email']) : '',
            'comment'      => isset($data['comment']) ? sanitize_text_field($data['comment']) : '',
        ];



        // Check nonce for security
        irep_check_nonce($data['nonce'], 'irep_nonce');

        // Ensure required fields are present
        $required_fields = ['project_id', 'flat_id', 'name', 'phone', 'email'];
        $required_data = irep_check_required_data($data, $required_fields);

        // Sanitize and validate non-required fields
        $non_required_fields = ['comment'];
        $non_required_data = irep_validate_and_sanitize_input($data, $non_required_fields, false);


        $data  = array_merge($non_required_data, $required_data);



        $receiveForms = irep_get_meta_by_key($data['project_id'], 'receive_forms_on_email');


        if (rest_sanitize_boolean($receiveForms)) {
            $this->send_reservation_email($data);
        }

        $project_id = (int) $data['project_id'];
        $flat_id = (int) $data['flat_id'];
        unset($data['project_id']);

        $reservation_id = Irep_DB::table($this->table_name)->create($data);

        if (!$reservation_id) {
            return irep_send_json_response(false, 'something went wrong!');
        }

        $created_reservation = Irep_DB::table($this->table_name)->find($reservation_id);

        if (is_object($created_reservation)) {
            $created_reservation->flat_id    = $flat_id;
            $created_reservation->project_id = $project_id;
        }

        /**
         * Fires after a reservation row is successfully created.
         *
         * @param int         $reservation_id      New reservation primary key.
         * @param object|null $created_reservation Row with flat_id and project_id set for consumers.
         * @param int         $project_id          Project the reservation belongs to.
         * @param int         $flat_id             Flat the reservation is for.
         */
        do_action('irep_reservation_created', $reservation_id, $created_reservation, $project_id, $flat_id);

        return irep_send_json_response(true, $created_reservation);
    }


    public function delete_reservation($data)
    {
        $data = [
            'nonce'        => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'action'       => isset($data['action']) ? sanitize_key($data['action']) : '',
            'record_id'      => isset($data['record_id']) ? absint($data['record_id']) : 0,
        ];

        // Check nonce for security
        irep_check_nonce($data['nonce'], 'irep_nonce');

        // Ensure the block_id is provided
        $record_id = isset($data['record_id']) ? intval($data['record_id']) : null;
        if (!$record_id) {
            irep_send_json_response(false, 'record_id is required');
            return;
        }

        $deleted_block = Irep_DB::table($this->table_name)->where('id', '=',  $record_id)->delete();

        // Handle delete result
        if ($deleted_block) {
            irep_send_json_response(true, 'Record deleted successfully');
        } else {
            irep_send_json_response(false, 'Database error: ' . $deleted_block->last_error);
        }
    }


    /**
     * Adds flat_name (irep_flats.flat_number), project_id and project_name (irep_projects.title) per row.
     *
     * @param array $results Paginate result with 'data' key.
     */
    private function enrich_reservations_with_flat_names(array &$results)
    {
        if (empty($results['data']) || !is_array($results['data'])) {
            return;
        }

        $ids = [];
        foreach ($results['data'] as $row) {
            $fid = is_object($row)
                ? (int) ($row->flat_id ?? 0)
                : (int) ($row['flat_id'] ?? 0);
            if ($fid > 0) {
                $ids[$fid] = $fid;
            }
        }

        $flat_map   = [];
        $project_ids = [];
        $floor_ids  = [];

        if (!empty($ids)) {
            $ids = array_values($ids);
            $flats_table  = $this->wpdb->prefix . 'irep_flats';
            $placeholders = implode(',', array_fill(0, count($ids), '%d'));
            $sql = "SELECT id, flat_number, project_id, floor_id, price, offer_price, conf, is_active
                    FROM {$flats_table} WHERE id IN ({$placeholders})";
            $flats = $this->wpdb->get_results($this->wpdb->prepare($sql, ...$ids));
            if ($flats) {
                foreach ($flats as $flat) {
                    $fid = (int) $flat->id;
                    $pid = (int) $flat->project_id;
                    $flo = (int) ($flat->floor_id ?? 0);
                    $flat_map[$fid] = [
                        'flat_number' => (string) $flat->flat_number,
                        'project_id'  => $pid,
                        'floor_id'    => $flo,
                        'price'       => $flat->price !== null ? (float) $flat->price : null,
                        'offer_price' => $flat->offer_price !== null ? (float) $flat->offer_price : null,
                        'conf'        => (string) ($flat->conf ?? ''),
                        'is_active'   => (bool) $flat->is_active,
                    ];
                    if ($pid > 0) {
                        $project_ids[$pid] = $pid;
                    }
                    if ($flo > 0) {
                        $floor_ids[$flo] = $flo;
                    }
                }
            }
        }

        $project_titles = [];
        if (!empty($project_ids)) {
            $project_ids   = array_values($project_ids);
            $projects_table = $this->wpdb->prefix . 'irep_projects';
            $p_placeholders = implode(',', array_fill(0, count($project_ids), '%d'));
            $p_sql = "SELECT id, title FROM {$projects_table} WHERE id IN ({$p_placeholders})";
            $projects = $this->wpdb->get_results($this->wpdb->prepare($p_sql, ...$project_ids));
            if ($projects) {
                foreach ($projects as $project) {
                    $project_titles[(int) $project->id] = (string) $project->title;
                }
            }
        }

        $floor_numbers = [];
        if (!empty($floor_ids)) {
            $floor_ids    = array_values($floor_ids);
            $floors_table = $this->wpdb->prefix . 'irep_floors';
            $f_placeholders = implode(',', array_fill(0, count($floor_ids), '%d'));
            $f_sql = "SELECT id, floor_number FROM {$floors_table} WHERE id IN ({$f_placeholders})";
            $floors = $this->wpdb->get_results($this->wpdb->prepare($f_sql, ...$floor_ids));
            if ($floors) {
                foreach ($floors as $floor) {
                    $floor_numbers[(int) $floor->id] = (string) $floor->floor_number;
                }
            }
        }

        foreach ($results['data'] as $row) {
            $fid = is_object($row)
                ? (int) ($row->flat_id ?? 0)
                : (int) ($row['flat_id'] ?? 0);

            $flat_name    = '';
            $project_id   = 0;
            $project_name = '';
            $floor_number = '';
            $price        = null;
            $offer_price  = null;
            $conf         = '';
            $is_active    = true;

            if ($fid > 0 && isset($flat_map[$fid])) {
                $fm           = $flat_map[$fid];
                $flat_name    = $fm['flat_number'];
                $project_id   = $fm['project_id'];
                $price        = $fm['price'];
                $offer_price  = $fm['offer_price'];
                $conf         = $fm['conf'];
                $is_active    = $fm['is_active'];
                if ($project_id > 0) {
                    $project_name = $project_titles[$project_id] ?? '';
                }
                $flo = $fm['floor_id'];
                if ($flo > 0) {
                    $floor_number = $floor_numbers[$flo] ?? '';
                }
            }

            if (is_object($row)) {
                $row->flat_name    = $flat_name;
                $row->project_id   = $project_id;
                $row->project_name = $project_name;
                $row->floor_number = $floor_number;
                $row->flat_price   = $price;
                $row->offer_price  = $offer_price;
                $row->flat_conf    = $conf;
                $row->flat_active  = $is_active;
            } else {
                $row['flat_name']    = $flat_name;
                $row['project_id']   = $project_id;
                $row['project_name'] = $project_name;
                $row['floor_number'] = $floor_number;
                $row['flat_price']   = $price;
                $row['offer_price']  = $offer_price;
                $row['flat_conf']    = $conf;
                $row['flat_active']  = $is_active;
            }
        }
    }


    private function is_gold()
    {
        return ire_fs()->is_plan_or_trial('gold', true);
    }


    private function send_reservation_email($data)
    {

        // Prepare email content
        $to = get_option('admin_email'); // Get the admin email from WordPress settings

        $subject = 'New Reservation Form Submission';
        $message = "A new reservation has been submitted with the following details:\n\n";
        $message .= "Flat ID: " . $data['flat_id'] . "\n";
        $message .= "Name: " . $data['name'] . "\n";
        $message .= "Phone: " . $data['phone'] . "\n";
        $message .= "Email: " . $data['email'] . "\n";
        $message .= "Comment: " . $data['comment'] . "\n";

        $headers = ['Content-Type: text/plain; charset=UTF-8'];

        // Send email to administrator
        $sent = wp_mail($to, $subject, $message, $headers);

        if (!$sent) {
            // Log error if email fails to send
            error_log('Failed to send reservation email');
        }

        return $sent;
    }
}

$irep_reservation = new Irep_Reservation();



function irep_get_reservations()
{
    global $irep_reservation;
    $results = $irep_reservation->get_reservations($_POST);

    if (!$results[0]) {
        irep_send_json_response(false, $results[1]);
    } else {
        irep_send_json_response(true, $results[1]);
    }
}


function irep_create_reservation()
{
    global $irep_reservation;
    $irep_reservation->create_reservation($_POST);
}




function irep_delete_reservation()
{
    global $irep_reservation;
    $irep_reservation->delete_reservation($_POST);
}

// Add action hooks
add_action('wp_ajax_irep_get_reservations', 'irep_get_reservations');
add_action('wp_ajax_irep_create_reservation', 'irep_create_reservation');
add_action('wp_ajax_nopriv_irep_create_reservation', 'irep_create_reservation');
add_action('wp_ajax_irep_delete_reservation', 'irep_delete_reservation');
