<?php

if (!defined('ABSPATH')) {
    exit;
}
/**
 * Class Irep_Flat
 *
 * Handles operations related to flats in the project management system.
 * Provides methods to create, update, retrieve, and delete flats from the database.
 */
class Irep_Flat
{
    private $wpdb;
    private $table_name;

    /**
     * Irep_Flat constructor.
     *
     * Initializes the global $wpdb object and sets the table name for flats.
     */
    public function __construct()
    {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->table_name =  'irep_flats';
    }

    /**
     * Retrieves flats from the database based on given parameters.
     *
     * @param array $data An associative array containing the request data:
     * 
     * @return array A two-element array:
     *               - bool: Success status of the operation.
     *               - array: The data, containing the flat records, total count, page, and per-page values.
     */
    public function get_flats($data)
    {
        $data = [
            'nonce'        => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'project_id'   => isset($data['project_id']) ? absint($data['project_id']) : 0,
            'sort_field'   => isset($data['sort_field']) ? sanitize_text_field($data['sort_field']) : '',
            'sort_order'   => isset($data['sort_order']) ? sanitize_text_field($data['sort_order']) : '',
            'block'        => isset($data['block']) && $data['block'] !== 'null' ? sanitize_text_field($data['block']) : 'null',
            'floor'        => isset($data['floor']) && is_numeric($data['floor']) ? absint($data['floor']) : null,
            'search'       => isset($data['search']) ? sanitize_text_field($data['search']) : '',
            'page'         => isset($data['page']) ? absint($data['page']) : 1,
            'per_page'     => isset($data['per_page']) ? absint($data['per_page']) : 8,
            'offset'       => isset($data['page']) ? (absint($data['page']) - 1) * absint($data['per_page']) : 0,
            'active'    => isset($data['active']) && rest_sanitize_boolean($data['active']),
        ];

        irep_check_nonce($data['nonce'], 'irep_nonce');
        irep_has_project_id($data);

        if (empty($data['project_id']) || $data['project_id'] <= 0) {
            irep_send_json_response(false, 'Invalid project_id provided!');
            return;
        }

        // Sanitize and filter sorting parameters
        $data = irep_sanitize_sorting_parameters($data, ['id', 'is_active',  'title', 'floor_id', 'price', 'offer_price', 'conf', 'block_id']);

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

        $query->where('project_id', '=', $data['project_id']);

        // Filter by block if provided
        if (!empty($data['block']) && $data['block'] != 'null') {
            if ($data['block'] !== 'all') {

                $query->where('block_id', '=', $data['block']);
            }
        } else {
            $query->where('block_id', 'IS', 'NULL');
        }


        if (!empty($data['floor']) || $data['floor'] === 0) {
            $query->where('floor_id', '=', $data['floor']);
        }


        if (!empty($data['active']) && $data['active']) {
            $query->where('is_active', '=', true);
        }



        $searchTerm = '%' . $data['search'] . '%';
        if (!empty($data['search'])) {
            $query->where('flat_number', 'LIKE', $searchTerm)
                ->orWhere('id', 'LIKE', $searchTerm)
                ->orWhere('price', 'LIKE', $searchTerm)
                ->orWhere('offer_price', 'LIKE', $searchTerm);
        }


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



        if (!$results) {
            return [false,  'something went wrong!'];
        } else {
            // Map the block data to a more usable format
            if ($results['data']) {

                $results['data'] = array_map([$this, 'map_flats'], $results['data']);
            }

            return [true, $results];
        }
    }

    /**
     * Creates a new flat and inserts it into the database.
     *
     * @param array $data An associative array containing the flat data:
     * 
     * @return void
     */
    public function create_flat($data)
    {

        $data = [
            'nonce'        => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'action'       => isset($data['action']) ? sanitize_key($data['action']) : '',
            'flat_id'      => isset($data['flat_id']) ? absint($data['flat_id']) : 0,
            'flat_number'  => isset($data['flat_number']) ? sanitize_text_field($data['flat_number']) : '',
            'conf'         => isset($data['conf']) ? sanitize_text_field($data['conf']) : '',
            'type_id'      => isset($data['type_id']) ? absint($data['type_id']) : 0,
            'floor_id'     => isset($data['floor_id']) ? sanitize_text_field($data['floor_id']) : null,
            'request_price' => isset($data['request_price']) && rest_sanitize_boolean($data['request_price']),
            'price'        => isset($data['price']) ? floatval($data['price']) : 0.0,
            'offer_price'  => isset($data['offer_price']) ? floatval($data['offer_price']) : 0.0,
            'block_id'     => isset($data['block_id']) ? absint($data['block_id']) : 0,
            'click_action' => isset($data['click_action']) ? sanitize_text_field($data['click_action']) : '',
            'follow_link'  => [
                'link'        => isset($data['follow_link']['link']) ? sanitize_text_field($data['follow_link']['link']) : '',
                'target'      => isset($data['follow_link']['target']) ? sanitize_text_field($data['follow_link']['target']) : '',
            ],
            'whatsapp' => [
                'type'    => isset($data['whatsapp']['type'])    ? sanitize_text_field($data['whatsapp']['type'])    : 'whatsapp',
                'phone'   => isset($data['whatsapp']['phone'])   ? sanitize_text_field($data['whatsapp']['phone'])   : '',
                'url'     => isset($data['whatsapp']['url'])     ? sanitize_url($data['whatsapp']['url'])            : '',
                'message' => isset($data['whatsapp']['message']) ? sanitize_textarea_field($data['whatsapp']['message']) : '',
                'use_custom' => isset($data['whatsapp']['use_custom']) && rest_sanitize_boolean($data['whatsapp']['use_custom']),
            ],
            'type' => [
                'title'       => isset($data['type']['title']) ? sanitize_text_field($data['type']['title']) : '',
                'teaser'      => isset($data['type']['teaser']) ? sanitize_textarea_field($data['type']['teaser']) : '',
                'area_m2'     => isset($data['type']['area_m2']) ? floatval($data['type']['area_m2']) : 0.0,
                'rooms_count' => isset($data['type']['rooms_count']) ? floatval($data['type']['rooms_count']) : 0.0,
                'other'           => $this->sanitize_other_field(isset($data['type']['other']) ? $data['type']['other'] : []),
                'image_2d'    => isset($data['type']['image_2d']) && is_array($data['type']['image_2d'])
                    ? irep_sanitize_media_list($data['type']['image_2d'])
                    : [],
                'image_3d'    => isset($data['type']['image_3d']) && is_array($data['type']['image_3d'])
                    ? irep_sanitize_media_list($data['type']['image_3d'])
                    : [],
            ],
            'project_id'   => isset($data['project_id']) ? absint($data['project_id']) : 0,
            'use_type'     => isset($data['use_type']) && rest_sanitize_boolean($data['use_type']),
            'files'    => isset($data['files']) && is_array($data['files'])
                ? array_map('absint', $data['files'])
                : [],
        ];


        $this->canUserAddFlat($data);

        irep_check_nonce($data['nonce'], 'irep_nonce');

        // Define required and non-required fields
        $required_fields = ['flat_number', 'project_id'];
        $non_required_fields = ['request_price', 'floor_id', 'price', 'offer_price', 'conf', 'block_id', 'use_type', 'click_action', 'follow_link', 'files', 'whatsapp'];

        // Adjust required fields based on use type
        if ($data['use_type']) {
            $required_fields[] = 'type_id';
        } else {
            $non_required_fields[] = 'type_id';
        }

        // Sanitize and validate required and non-required data
        $required_data = irep_check_required_data($data, $required_fields);
        $non_required_data = irep_validate_and_sanitize_input($data, $non_required_fields, false);

        // Merge the data and prepare it for insertion
        $params = array_merge($required_data, $non_required_data);


        // Handle the type data as JSON
        $params['type'] = irep_handle_json_data($data['type']);
        $params['follow_link'] = irep_handle_json_data($data['follow_link']);
        $params['whatsapp'] = irep_handle_json_data($data['whatsapp']);
        $params['price'] = $params['price'] ?? 0;

        if (isset($params['files'])) {
            $params['files'] = wp_json_encode($params['files']);
        }

        $flat_id = Irep_DB::table($this->table_name)->create($params);

        if (!$flat_id) {
            irep_send_json_response(false, 'Database error');
        } else {
            do_action(
                'irep_flat_saved',
                $flat_id,
                $data['project_id'],
                0.0,
                floatval($params['price']),
                $data['request_price']
            );

            $created_type =  Irep_DB::table($this->table_name)->find($flat_id);
            $transformed = $this->map_flats($created_type);

            irep_send_json_response(true, $transformed);
        }
    }

    /**
     * Updates an existing flat with new data.
     *
     * @param array $data An associative array containing the updated flat data:
     * 
     * @return void
     */
    public function update_flat($data)
    {

        $data = [
            'nonce'            => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'action'           => isset($data['action']) ? sanitize_key($data['action']) : '',
            'flat_id'          => isset($data['flat_id']) ? absint($data['flat_id']) : 0,
            'is_active'        => isset($data['is_active']) && rest_sanitize_boolean($data['is_active']),
            'flat_number'      => isset($data['flat_number']) ? sanitize_text_field($data['flat_number']) : '',
            'conf'             => isset($data['conf']) ? sanitize_text_field($data['conf']) : '',
            'type_id'          => isset($data['type_id']) ? absint($data['type_id']) : 0,
            'floor_id'         => isset($data['floor_id']) ? sanitize_text_field($data['floor_id']) : null,
            'request_price'    => isset($data['request_price']) && rest_sanitize_boolean($data['request_price']),
            'price'            => isset($data['price']) ? floatval($data['price']) : 0.0,
            'offer_price'      => isset($data['offer_price']) ? floatval($data['offer_price']) : 0.0,
            'block_id'         => isset($data['block_id']) ? absint($data['block_id']) : 0,
            'click_action'     => isset($data['click_action']) ? sanitize_text_field($data['click_action']) : '',
            'follow_link'      => [
                'link'             => isset($data['follow_link']['link']) ? sanitize_text_field($data['follow_link']['link']) : '',
                'target'           => isset($data['follow_link']['target']) ? sanitize_text_field($data['follow_link']['target']) : '',
            ],
            'whatsapp' => [
                'type'    => isset($data['whatsapp']['type'])    ? sanitize_text_field($data['whatsapp']['type'])    : 'whatsapp',
                'phone'   => isset($data['whatsapp']['phone'])   ? sanitize_text_field($data['whatsapp']['phone'])   : '',
                'url'     => isset($data['whatsapp']['url'])     ? sanitize_url($data['whatsapp']['url'])            : '',
                'message' => isset($data['whatsapp']['message']) ? sanitize_textarea_field($data['whatsapp']['message']) : '',
                'use_custom' => isset($data['whatsapp']['use_custom']) && rest_sanitize_boolean($data['whatsapp']['use_custom']),
            ],
            'type' => [
                'title'                => isset($data['type']['title']) ? sanitize_text_field($data['type']['title']) : '',
                'teaser'               => isset($data['type']['teaser']) ? sanitize_textarea_field($data['type']['teaser']) : '',
                'area_m2'              => isset($data['type']['area_m2']) ? floatval($data['type']['area_m2']) : 0.0,
                'rooms_count'          => isset($data['type']['rooms_count']) ? floatval($data['type']['rooms_count']) : 0.0,
                'other'                => $this->sanitize_other_field(isset($data['type']['other']) ? $data['type']['other'] : []),
                'image_2d'             => isset($data['type']['image_2d']) && is_array($data['type']['image_2d'])
                    ? irep_sanitize_media_list($data['type']['image_2d'])
                    : [],
                'image_3d'             => isset($data['type']['image_3d']) && is_array($data['type']['image_3d'])
                    ? irep_sanitize_media_list($data['type']['image_3d'])
                    : [],

            ],
            'project_id'       => isset($data['project_id']) ? absint($data['project_id']) : 0,
            'use_type'         => isset($data['use_type']) && rest_sanitize_boolean($data['use_type']),
            'files'    => isset($data['files']) && is_array($data['files'])
                ? array_map('absint', $data['files'])
                : [],
        ];


        irep_check_nonce($data['nonce'], 'irep_nonce');

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

        // Define required fields
        $required_fields = ['flat_number'];
        if (isset($data['use_type']) && $data['use_type']) {
            $required_fields[] = 'type_id';
        }

        // Sanitize and validate required fields
        $required_data = irep_check_required_data($data, $required_fields);

        // Define and validate optional fields
        $keys = ['floor_id', 'project_id', 'block_id', 'price', 'request_price', 'offer_price', 'conf', 'use_type', 'click_action', 'follow_link', 'files', 'whatsapp'];

        if ($this->hasUserGoldPlan()) {
            $keys[] = 'is_active';
        }

        $params = irep_validate_and_sanitize_input($data, $keys, false);

        // Merge required and optional fields
        $params = array_merge($required_data, $params);

        // Handle block ID and type data
        if (!isset($params['block_id'])) {
            $params['block_id'] = null;
        }

        $params['type'] = irep_handle_json_data($data['type']);
        $params['follow_link'] = irep_handle_json_data($data['follow_link']);
        $params['whatsapp'] = irep_handle_json_data($data['whatsapp']);
        $params['price'] = $params['price'] ?? 0;

        if (isset($params['files'])) {
            $params['files'] = wp_json_encode($params['files']);
        }

        $old_flat = Irep_DB::table($this->table_name)->find($flat_id);
        $old_price = $old_flat ? floatval($old_flat['price']) : 0.0;

        $updated_flat = Irep_DB::table($this->table_name)->where('id', '=',  $flat_id)->update($params);


        if ($updated_flat->last_error) {
            irep_send_json_response(false, 'Database error');
        } else {
            do_action(
                'irep_flat_saved',
                $flat_id,
                $data['project_id'],
                $old_price,
                floatval($params['price']),
                $data['request_price']
            );

            irep_send_json_response(true, 'Flat updated successfully');
        }
    }

    /**
     * Deletes a flat from the database.
     *
     * @param array $data An associative array containing the flat ID and nonce:
     *                    - nonce (string) The nonce for security validation.
     *                    - flat_id (int) The ID of the flat to delete.
     * 
     * @return void
     */
    public function delete_flat($data)
    {
        irep_check_nonce($data['nonce'], 'irep_nonce');

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


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


        if ($deleted_flat) {
            irep_send_json_response(true, 'Flat deleted successfully');
        } else {
            irep_send_json_response(false, 'Database error: ' . $this->wpdb->last_error);
        }
    }


    // -------------------------------------------------------------------------
    // Flat settings storage helpers
    // -------------------------------------------------------------------------

    private function get_flat_settings_data(): array
    {
        $global = get_option('irep_global_settings', []);

        if (isset($global['flat']['customFields'])) {
            return $global['flat'];
        }

        // Migration fallback: read from legacy key
        $fields = irep_handle_json_data(get_option('irep_flats_custom_fields', ''));
        if (empty($fields)) {
            $fields = [];
        }

        return ['customFields' => $fields];
    }

    private function save_flat_settings_data(array $flat): void
    {
        $global         = get_option('irep_global_settings', []);
        $global['flat'] = $flat;
        update_option('irep_global_settings', $global);
    }

    // -------------------------------------------------------------------------
    // New consolidated AJAX actions
    // -------------------------------------------------------------------------

    public function get_all_flat_settings($data = null)
    {
        if (!is_array($data)) {
            $data = $_POST;
        }
        irep_check_nonce($data['nonce'], 'irep_nonce');

        $s = $this->get_flat_settings_data();
        irep_send_json_response(true, ['customFields' => $s['customFields'] ?? []]);
    }

    public function save_all_flat_settings($data = null)
    {
        if (!is_array($data)) {
            $data = $_POST;
        }
        irep_check_nonce($data['nonce'], 'irep_nonce');
        $this->canUserChangeFlatStatus();

        $rawFields = $data['fields'] ?? [];
        if (is_string($rawFields)) {
            $fields = json_decode($rawFields, true) ?? [];
        } else {
            $fields = is_array($rawFields) ? $rawFields : [];
        }

        $this->save_flat_settings_data(['customFields' => $fields]);
        irep_send_json_response(true, 'Flat settings saved successfully');
    }

    // -------------------------------------------------------------------------
    // Legacy methods — now read/write from consolidated storage
    // -------------------------------------------------------------------------

    public function add_custom_flat_fields($data)
    {
        irep_check_nonce($data['nonce'], 'irep_nonce');
        $this->canUserChangeFlatStatus();

        $fields = isset($data['fields']) ? irep_handle_json_data($data['fields']) : [];
        $this->save_flat_settings_data(['customFields' => $fields]);

        irep_send_json_response(true, 'Fields saved successfully');
    }

    public function get_flat_fields($data, $returnArray = false)
    {
        irep_check_nonce($data['nonce'], 'irep_nonce');

        $fields = $this->get_flat_settings_data()['customFields'] ?? [];
        if (empty($fields)) {
            $fields = [];
        }

        if ($returnArray) {
            return $fields;
        }
        irep_send_json_response(true, $fields);
    }

    public function change_flat_status($data)
    {
        irep_check_nonce($data['nonce'], 'irep_nonce');

        $this->canUserChangeFlatStatus();

        $data = [
            'nonce'     => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'action'    => isset($data['action']) ? sanitize_key($data['action']) : '',
            'flat_id'   => isset($data['flat_id']) ? absint($data['flat_id']) : 0,
            'is_active'    => isset($data['is_active']) && rest_sanitize_boolean($data['is_active']),
        ];


        $flat_id = isset($data['flat_id']) ? intval($data['flat_id']) : null;
        $params = ['is_active' => $data['is_active']];


        $updated_flat = Irep_DB::table($this->table_name)->where('id', '=',  $flat_id)->update($params);


        if ($updated_flat->last_error) {
            irep_send_json_response(false,  $updated_flat->last_error);
        } else {
            irep_send_json_response(true,  'Flat status updated');
        }
    }

    public function change_flat_config($data)
    {
        irep_check_nonce($data['nonce'], 'irep_nonce');

        $this->canUserChangeFlatStatus();

        $data = [
            'nonce'     => isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '',
            'action'    => isset($data['action']) ? sanitize_key($data['action']) : '',
            'flat_id'   => isset($data['flat_id']) ? absint($data['flat_id']) : 0,
            'conf'      => isset($data['conf']) ? sanitize_text_field($data['conf']) : null,
        ];


        $flat_id = isset($data['flat_id']) ? intval($data['flat_id']) : null;
        $params = ['conf' => $data['conf']];


        $updated_flat = Irep_DB::table($this->table_name)->where('id', '=',  $flat_id)->update($params);


        if ($updated_flat->last_error) {
            irep_send_json_response(false,  $updated_flat->last_error);
        } else {
            irep_send_json_response(true,  'Flat status updated');
        }
    }




    /**
     * Maps the flat data to a more usable format.
     *
     * @param array $item The flat data to be mapped.
     *
     * @return array The mapped flat data. Filter: `irep_flat_mapped` — receives and must return
     *               the associative flat array; addons may append keys (e.g. `price_history`).
     */
    private function map_flats($item)
    {
        if (is_object($item)) {
            $item = (array) $item;
        }


        // Handle 'use_type' field as a boolean
        $item['use_type'] =  $item['use_type'] === '1';
        $item['is_active'] =  $item['is_active'] === '1';
        $item['request_price'] =  $item['request_price'] === '1';

        // Process the type data if available
        if ($item['type']) {
            $item['type'] = irep_handle_json_data($item['type']);
        }

        if ($item['follow_link']) {
            $item['follow_link'] = irep_handle_json_data($item['follow_link']);

            if (isset($item['follow_link']['target'])) {
                $item['follow_link']['target'] = filter_var($item['follow_link']['target'], FILTER_VALIDATE_BOOLEAN);
            }
        }

        if (!empty($item['whatsapp'])) {
            $item['whatsapp'] = irep_handle_json_data($item['whatsapp']);
        }

        if (isset($item['files']) && !empty($item['files'])) {

            // Ensure it's an array
            if (!is_array($item['files'])) {
                $item['files'] = json_decode($item['files'], true);
            }

            if (is_array($item['files']) && count($item['files']) > 0) {
                $item['files'] = array_map('irep_get_image_instance', $item['files']);
            } else {
                $item['files'] = [];
            }
        }

        // Process image data for 2D and 3D images, if available
        if (is_array($item['type'])) {
            // Process image arrays
            foreach (['image_2d', 'image_3d'] as $imageType) {
                if (!empty($item['type'][$imageType])) {
                    $item['type'][$imageType] = array_values(array_filter(array_map('irep_resolve_media_item', $item['type'][$imageType])));
                }
            }
        }

        return apply_filters('irep_flat_mapped', $item);
    }



    private function sanitize_other_field($other)
    {
        if (!is_array($other)) {
            return [];
        }

        return array_map(function ($item) {
            return [
                'key'   => isset($item['key']) ? sanitize_text_field($item['key']) : '',
                'value' => isset($item['value']) ? sanitize_text_field($item['value']) : '',
            ];
        }, $other);
    }


    public function bulk_delete_flats($data)
    {
        irep_check_nonce(isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '', 'irep_nonce');

        $ids_raw = isset($data['ids']) ? $data['ids'] : null;
        if (is_string($ids_raw)) {
            $ids_raw = json_decode(wp_unslash($ids_raw), true);
        }

        if (!is_array($ids_raw) || empty($ids_raw)) {
            irep_send_json_response(false, 'No IDs provided');
            return;
        }

        $ids = array_filter(array_map('absint', $ids_raw));
        $deleted = 0;

        foreach ($ids as $flat_id) {
            if (Irep_DB::table($this->table_name)->where('id', '=', $flat_id)->delete()) {
                $deleted++;
            }
        }

        irep_send_json_response(true, ['deleted' => $deleted]);
    }

    public function import_flats_from_excel($data)
    {
        $nonce      = isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '';
        $project_id = isset($data['project_id']) ? absint($data['project_id']) : 0;
        $flats_raw  = isset($data['flats']) ? $data['flats'] : null;

        irep_check_nonce($nonce, 'irep_nonce');

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

        if (!$project_id) {
            irep_send_json_response(false, 'project_id is required');
            return;
        }

        if (is_string($flats_raw)) {
            $flats_raw = json_decode(wp_unslash($flats_raw), true);
        }

        if (!is_array($flats_raw) || empty($flats_raw)) {
            irep_send_json_response(false, 'No flat rows provided');
            return;
        }

        $imported = 0;
        $updated  = 0;
        $failed   = 0;

        foreach ($flats_raw as $row) {
            if (!is_array($row) || empty($row['flat_number'])) {
                $failed++;
                continue;
            }

            // Rows carrying an `id` update an existing flat in this project;
            // a mismatched/foreign id is rejected rather than silently creating a duplicate.
            $row_id = isset($row['id']) && $row['id'] !== '' ? absint($row['id']) : 0;
            $existing_flat = null;

            if ($row_id) {
                $existing_flat = Irep_DB::table($this->table_name)->find($row_id);
                if (!$existing_flat || intval($existing_flat['project_id']) !== $project_id) {
                    $failed++;
                    continue;
                }
            }

            $type_raw = isset($row['type']) && is_array($row['type']) ? $row['type'] : [];
            $use_type = !empty($row['use_type']);
            $type_id  = $use_type && !empty($row['type_id']) ? absint($row['type_id']) : null;

            if ($use_type && $type_id) {
                $type_exists = Irep_DB::table('irep_types')->find($type_id);
                if (!$type_exists) {
                    $use_type = false;
                    $type_id  = null;
                }
            }

            $params = [
                'project_id'    => $project_id,
                'is_active'     => isset($row['is_active']) ? (bool) $row['is_active'] : true,
                'flat_number'   => sanitize_text_field($row['flat_number']),
                'price'         => isset($row['price']) ? floatval($row['price']) : 0.0,
                'offer_price'   => isset($row['offer_price']) ? floatval($row['offer_price']) : 0.0,
                'conf'          => isset($row['conf']) ? sanitize_text_field($row['conf']) : '',
                'floor_id'      => isset($row['floor_id']) && $row['floor_id'] !== '' ? absint($row['floor_id']) : null,
                'block_id'      => isset($row['block_id']) && $row['block_id'] !== '' ? absint($row['block_id']) : null,
                'request_price' => isset($row['request_price']) ? (bool) $row['request_price'] : false,
                'use_type'      => $use_type,
                'type_id'       => $type_id,
                'click_action'  => isset($row['click_action']) ? sanitize_text_field($row['click_action']) : '',
                'follow_link'   => wp_json_encode([
                    'link'   => isset($row['follow_link']['link']) ? sanitize_text_field($row['follow_link']['link']) : '',
                    'target' => !empty($row['follow_link']['target']),
                ]),
                'whatsapp'      => wp_json_encode([
                    'type'       => isset($row['whatsapp']['type']) ? sanitize_text_field($row['whatsapp']['type']) : 'none',
                    'phone'      => isset($row['whatsapp']['phone']) ? sanitize_text_field($row['whatsapp']['phone']) : '',
                    'url'        => isset($row['whatsapp']['url']) ? sanitize_url($row['whatsapp']['url']) : '',
                    'message'    => isset($row['whatsapp']['message']) ? sanitize_textarea_field($row['whatsapp']['message']) : '',
                    'use_custom' => !empty($row['whatsapp']['use_custom']),
                ]),
                'type'          => wp_json_encode([
                    'title'       => isset($type_raw['title']) ? sanitize_text_field($type_raw['title']) : '',
                    'teaser'      => isset($type_raw['teaser']) ? sanitize_textarea_field($type_raw['teaser']) : '',
                    'area_m2'     => isset($type_raw['area_m2']) ? floatval($type_raw['area_m2']) : 0.0,
                    'rooms_count' => isset($type_raw['rooms_count']) ? floatval($type_raw['rooms_count']) : 0.0,
                    'other'       => $this->sanitize_other_field(isset($type_raw['other']) ? $type_raw['other'] : []),
                    'image_2d'    => [],
                    'image_3d'    => [],
                ]),
            ];

            if ($existing_flat) {
                $old_price = floatval($existing_flat['price']);

                $updated_flat = Irep_DB::table($this->table_name)->where('id', '=', $row_id)->update($params);

                if ($updated_flat->last_error) {
                    $failed++;
                    continue;
                }

                do_action(
                    'irep_flat_saved',
                    $row_id,
                    $project_id,
                    $old_price,
                    floatval($params['price']),
                    $params['request_price']
                );

                $updated++;
                continue;
            }

            $params['files'] = wp_json_encode([]);
            $flat_id = Irep_DB::table($this->table_name)->create($params);

            if ($flat_id) {
                do_action(
                    'irep_flat_saved',
                    $flat_id,
                    $project_id,
                    0.0,
                    floatval($params['price']),
                    $params['request_price']
                );
                $imported++;
            } else {
                $failed++;
            }
        }

        irep_send_json_response(true, ['imported' => $imported, 'updated' => $updated, 'failed' => $failed]);
    }

    public function export_flats($data)
    {
        $nonce      = isset($data['nonce']) ? sanitize_text_field($data['nonce']) : '';
        $project_id = isset($data['project_id']) ? absint($data['project_id']) : 0;

        irep_check_nonce($nonce, 'irep_nonce');

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

        if (!$project_id) {
            irep_send_json_response(false, 'project_id is required');
            return;
        }

        $results = Irep_DB::table($this->table_name)
            ->where('project_id', '=', $project_id)
            ->orderBy('id', 'ASC')
            ->get();

        $flats = array_map([$this, 'map_flats'], $results);

        irep_send_json_response(true, $flats);
    }

    private function canUserAddFlat($data)
    {
        $flats = $this->get_flats($data)[1]['total'];

        $check = !ire_fs()->can_use_premium_code() && $flats >= 25;

        if ($check) {
            irep_upgrade_plan();
        }
    }


    private function canUserChangeFlatStatus()
    {

        $check = ire_fs()->is_plan_or_trial('gold', true);

        if (!$check) {
            irep_upgrade_plan();
        }
    }

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

// Initialize the class
$irep_flats_manager = new Irep_Flat();

// Action functions

/**
 * Handles the AJAX request to retrieve flats.
 */
function irep_get_flats()
{
    global $irep_flats_manager;

    // Get the results and send the response
    $results = $irep_flats_manager->get_flats($_POST);

    if (is_array($results) && isset($results[0], $results[1])) {
        if (!$results[0]) {
            irep_send_json_response(false, $results[1]);
        } else {
            irep_send_json_response(true, $results[1]);
        }
    } else {
        irep_send_json_response(false, 'No flats found or invalid response format');
    }
}

/**
 * Handles the AJAX request to create a flat.
 */
function irep_create_flat()
{
    global $irep_flats_manager;
    $irep_flats_manager->create_flat($_POST);
}

/**
 * Handles the AJAX request to update a flat.
 */
function irep_update_flat()
{
    global $irep_flats_manager;
    $irep_flats_manager->update_flat($_POST);
}

/**
 * Handles the AJAX request to delete a flat.
 */
function irep_delete_flat()
{
    global $irep_flats_manager;
    $irep_flats_manager->delete_flat($_POST);
}

function irep_add_flat_custom_fields()
{
    global $irep_flats_manager;
    $irep_flats_manager->add_custom_flat_fields($_POST);
}

function irep_get_flat_fields()
{
    global $irep_flats_manager;
    $irep_flats_manager->get_flat_fields($_POST);
}

function irep_get_all_flat_settings()
{
    global $irep_flats_manager;
    $irep_flats_manager->get_all_flat_settings($_POST);
}

function irep_save_all_flat_settings()
{
    global $irep_flats_manager;
    $irep_flats_manager->save_all_flat_settings($_POST);
}


function irep_change_flat_status()
{
    global $irep_flats_manager;
    $irep_flats_manager->change_flat_status($_POST);
}


function irep_change_flat_config()
{
    global $irep_flats_manager;
    $irep_flats_manager->change_flat_config($_POST);
}




// Add action hooks for AJAX requests
add_action('wp_ajax_irep_get_flats', 'irep_get_flats');
add_action('wp_ajax_irep_create_flat', 'irep_create_flat');
add_action('wp_ajax_irep_update_flat', 'irep_update_flat');
add_action('wp_ajax_irep_delete_flat', 'irep_delete_flat');
add_action('wp_ajax_irep_add_flat_custom_fields',  'irep_add_flat_custom_fields');
add_action('wp_ajax_irep_get_flat_fields',         'irep_get_flat_fields');
add_action('wp_ajax_irep_get_all_flat_settings',   'irep_get_all_flat_settings');
add_action('wp_ajax_irep_save_all_flat_settings',  'irep_save_all_flat_settings');
add_action('wp_ajax_irep_change_flat_status', 'irep_change_flat_status');
add_action('wp_ajax_irep_change_flat_config', 'irep_change_flat_config');

function irep_import_flats_excel()
{
    global $irep_flats_manager;
    $irep_flats_manager->import_flats_from_excel($_POST);
}

add_action('wp_ajax_irep_import_flats_excel', 'irep_import_flats_excel');

function irep_export_flats_excel()
{
    global $irep_flats_manager;
    $irep_flats_manager->export_flats($_POST);
}

add_action('wp_ajax_irep_export_flats_excel', 'irep_export_flats_excel');

function irep_bulk_delete_flats()
{
    global $irep_flats_manager;
    $irep_flats_manager->bulk_delete_flats($_POST);
}

add_action('wp_ajax_irep_bulk_delete_flats', 'irep_bulk_delete_flats');
