<?php

namespace BookWellAB;

defined('ABSPATH') || exit;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

if (!class_exists('BookWellAB_Customers')) {

    class BookWellAB_Customers
    {
        private static $instance = null;
        private $bookwell_page = 'customers';
        private $bwdb;

        public static function get_instance()
        {
            if (self::$instance === null) {
                self::$instance = new self();
            }
            return self::$instance;
        }

        public function __construct()
        {
            global $BOOKWELLAB;
            $this->bwdb = new BookWellAB_Database();
            $current_page = (isset($BOOKWELLAB) && $BOOKWELLAB instanceof BOOKWELL)
                ? $BOOKWELLAB->get_bookwell_admin_page()
                : '';

            if (is_admin() && $current_page == $this->bookwell_page) {
                add_filter('bookwellab_admin_script_vriable_data', [$this, 'bookwellab_admin_script_vriable_data'], 10, 2);
                add_action('bookwellab_customers_admin_html', [$this, 'bookwellab_customers_admin_html_func'], 10);
                add_filter('bookwellab_page_method_data', [$this, 'bookwellab_page_method_data_func'], 10, 2);
                add_filter('bookwellab_page_mounted_data', [$this, 'bookwellab_page_mounted_data_func'], 10, 2);
                add_action('admin_enqueue_scripts', [$this, 'admin_assets']);
            }

            add_action('wp_ajax_bookwellab_get_customers', [$this, 'bookwellab_get_customers_func']);
            add_action('wp_ajax_bookwellab_add_customer', [$this, 'bookwellab_add_customer_func']);
            add_action('wp_ajax_bookwellab_delete_customer', [$this, 'bookwellab_delete_customer_func']);
        }

        public function bookwellab_customers_admin_html_func()
        {
            require_once BOOKWELLAB_HTML_PATH . 'customers_view.php';
        }

        public function admin_assets($hook)
        {
            global $BOOKWELLAB;
            if ($BOOKWELLAB->get_bookwell_admin_page() == $this->bookwell_page) {
                \BookWellAB\BookWellAB_Frontend::enqueue_intl_tel_input_assets();
            }
        }

        public function bookwellab_admin_script_vriable_data($bookwellab_admin_script_vriable_data, $bookwellpage)
        {
            if ($this->bookwell_page != $bookwellpage) {
                return $bookwellab_admin_script_vriable_data;
            }

            $filter = [
                'search' => '',
            ];

            $bookwellab_admin_script_vriable_data['filter'] = $filter;
            $bookwellab_admin_script_vriable_data['filter_reset'] = $filter;

            $bookwellab_admin_script_vriable_data['pagination'] = [
                'page' => 1,
                'limit' => 10,
                'total' => 0
            ];

            $bookwellab_admin_script_vriable_data['customer_form'] = array();
            $bookwellab_admin_script_vriable_data['customer_form_reset'] = [
                'bw_customer_id' => 0,
                'bw_first_name' => '',
                'bw_last_name' => '',
                'bw_email' => '',
                'bw_phone_code' => '',
                'bw_phone' => '',
                'bw_country_slug' => '',
            ];

            $bookwellab_admin_script_vriable_data['form_rules'] = [
                'bw_first_name' => [
                    ['required' => true, 'message' => __('Please enter first name', 'bookwellnow-appointment-booking'), 'trigger' => 'blur']
                ],
                'bw_last_name' => [
                    ['required' => true, 'message' => __('Please enter last name', 'bookwellnow-appointment-booking'), 'trigger' => 'blur']
                ],
                'bw_email' => [
                    ['required' => true, 'message' => __('Please enter email', 'bookwellnow-appointment-booking'), 'trigger' => 'blur'],
                    ['type' => 'email', 'message' => __('Please enter valid email', 'bookwellnow-appointment-booking'), 'trigger' => 'blur']
                ]
            ];

            $bookwellab_admin_script_vriable_data['customer_form'] = $bookwellab_admin_script_vriable_data['customer_form_reset'];
            $bookwellab_admin_script_vriable_data['list_data'] = array();
            $bookwellab_admin_script_vriable_data['insert_loader'] = false;

            return $bookwellab_admin_script_vriable_data;
        }

        public function bookwellab_page_mounted_data_func($bookwellab_page_mounted_data, $bookwellpage)
        {
            if ($this->bookwell_page != $bookwellpage) {
                return $bookwellab_page_mounted_data;
            }

            $bookwellab_page_mounted_data .= '
                const vuedata = this;
                vuedata.bwab_getCustomers();
            ';

            return $bookwellab_page_mounted_data;
        }

        public function bookwellab_page_method_data_func($bookwellab_page_method_data, $bookwellpage)
        {
            if ($this->bookwell_page != $bookwellpage) {
                return $bookwellab_page_method_data;
            }

            $bookwellab_page_method_data .= '
                async bwab_getCustomers(show_loader = true) {
                    var ajax_url = bookwellab_ajax_obj.ajax_url;
                    const vuedata = this;
                    
                    if(show_loader) {
                        vuedata.bw_list_loader = "1";
                    }
                    
                    var postData = {
                        action: "bookwellab_get_customers",
                        _wpnonce: bookwellab_ajax_obj.bookwellab_nonce,
                        filter: vuedata.filter,
                        page: vuedata.pagination.page,
                        limit: vuedata.pagination.limit
                    };
                    
                    axios.post(ajax_url, Qs.stringify(postData))
                    .then(function(response) {
                        vuedata.bw_list_loader = "0";
                        if(response.data.type == "success") {
                            vuedata.list_data = response.data.list_data;
                            vuedata.pagination.total = parseInt(response.data.total);
                        }
                    }).catch(function(error) {
                        vuedata.bw_list_loader = "0";
                        vuedata.bwab_error_handler();
                    });
                },
                bwab_handleSizeChange(val) {
                    this.pagination.limit = val;
                    this.pagination.page = 1;
                    this.bwab_getCustomers();
                },
                bwab_handleCurrentChange(val) {
                    this.pagination.page = val;
                    this.bwab_getCustomers();
                },
                bwab_openAddPopup() {
                    this.customer_form = JSON.parse(JSON.stringify(this.customer_form_reset));
                    this.bw_add_edit_popup = true;
                    this.$nextTick(() => {
                        this.bwab_init_iti();
                    });
                },
                bwab_editRow(row) {
                    this.customer_form = JSON.parse(JSON.stringify(row));
                    this.bw_add_edit_popup = true;
                    this.$nextTick(() => {
                        this.bwab_init_iti();
                    });
                },
                bwab_init_iti() {
                    const input = document.querySelector("#bw_customer_phone");
                    if (input) {
                        if(window.iti_admin) {
                            window.iti_admin.destroy();
                        }
                        const default_country = (typeof bookwellab_admin_script_vriable_data !== "undefined" && bookwellab_admin_script_vriable_data.settings_form && bookwellab_admin_script_vriable_data.settings_form.general) ? bookwellab_admin_script_vriable_data.settings_form.general.default_country : "us";
                        const itiOptions = {
                            separateDialCode: true,
                            initialCountry: default_country
                        };
                        window.iti_admin = window.intlTelInput(input, itiOptions);

                        if (this.customer_form && this.customer_form.bw_phone) {
                            const savedPhone = String(this.customer_form.bw_phone).trim();
                            const savedCountrySlug = String(this.customer_form.bw_country_slug || "").toLowerCase();

                            if (savedCountrySlug) {
                                window.iti_admin.setCountry(savedCountrySlug);
                            } else if (this.customer_form.bw_phone_code) {
                                const savedDialCode = String(this.customer_form.bw_phone_code).replace("+", "");
                                const countryDataList = (typeof window.intlTelInput.getCountryData === "function")
                                    ? window.intlTelInput.getCountryData()
                                    : [];
                                const matchedCountry = countryDataList.find((country) => String(country.dialCode) === savedDialCode);

                                if (matchedCountry && matchedCountry.iso2) {
                                    window.iti_admin.setCountry(matchedCountry.iso2);
                                }
                            }

                            input.value = savedPhone;
                            this.customer_form.bw_phone = savedPhone;
                        }
                    }
                },
                bwab_deleteRow(row, index) {
                    const vuedata = this;
                    var ajax_url = bookwellab_ajax_obj.ajax_url;
                    
                    vuedata.$confirm(\'Are you sure you want to delete this customer?\', \'Warning\', {
                        confirmButtonText: \'OK\',
                        cancelButtonText: \'Cancel\',
                        type: \'warning\'
                    }).then(() => {
                        row.delete_loader = "1";
                        var postData = {
                            action: "bookwellab_delete_customer",
                            id: row.bw_customer_id,
                            _wpnonce: bookwellab_ajax_obj.bookwellab_nonce
                        };
                        
                        axios.post(ajax_url, Qs.stringify(postData))
                        .then(function(response) {
                            row.delete_loader = "0";
                            vuedata.$notify({
                                title: response.data.title,
                                message: response.data.msg,
                                type: response.data.type,
                                duration: 2000
                            });
                            if(response.data.type == "success") {
                                vuedata.bwab_getCustomers();
                            }
                        }).catch(function(error) {
                            row.delete_loader = "0";
                            vuedata.bwab_error_handler();
                        });
                    });
                },
                bwab_saveCustomer() {
                    const vuedata = this;
                    var ajax_url = bookwellab_ajax_obj.ajax_url;
                    
                    vuedata.$refs["bw_customer_frm"].validate((valid) => {
                        if(valid) {
                            vuedata.insert_loader = "1";
                            if(window.iti_admin) {
                                const countryData = window.iti_admin.getSelectedCountryData();
                                if (countryData && countryData.dialCode) {
                                    vuedata.customer_form.bw_phone_code = "+" + countryData.dialCode;
                                }
                                if (countryData && countryData.iso2) {
                                    vuedata.customer_form.bw_country_slug = String(countryData.iso2).toLowerCase();
                                }
                                vuedata.customer_form.bw_phone = String(vuedata.customer_form.bw_phone || "").replace(/\D/g, "");
                            }
                            
                            var pass_data = {
                                action: "bookwellab_add_customer",
                                customer_data: JSON.stringify(vuedata.customer_form),
                                _wpnonce: bookwellab_ajax_obj.bookwellab_nonce
                            };
                            
                            axios.post(ajax_url, Qs.stringify(pass_data))
                            .then(function(response) {
                                vuedata.insert_loader = "0";
                                vuedata.$notify({
                                    title: response.data.title,
                                    message: response.data.msg,
                                    type: response.data.type,
                                    duration: 2000
                                });
                                if(response.data.type == "success") {
                                    vuedata.bw_add_edit_popup = false;
                                    vuedata.bwab_getCustomers();
                                }
                            }).catch(function(error) {
                                vuedata.insert_loader = "0";
                                vuedata.bwab_error_handler();
                            });
                        }
                    });
                },
                bwab_resetFilter() {
                    this.filter = JSON.parse(JSON.stringify(this.filter_reset));
                    this.bwab_getCustomers();
                },
                bwab_error_handler() {
                    this.$notify({
                        title: "Error",
                        message: "Something went wrong",
                        type: "error",
                        duration: 2000
                    });
                },
                bwab_formatDate(dateStr) {
                    if(!dateStr) return "";
                    var format = bookwellab_admin_script_vriable_data.date_format || "Y-m-d";
                    var d = new Date(dateStr);
                    if(isNaN(d)) return dateStr;
                    
                    var options = {};
                    if(format.includes("F") || format.includes("M")) options.month = "long";
                    else if(format.includes("m")) options.month = "2-digit";
                    else options.month = "numeric";
                    
                    if(format.includes("d")) options.day = "2-digit";
                    else options.day = "numeric";
                    
                    if(format.includes("Y")) options.year = "numeric";
                    else options.year = "2-digit";
                    
                    // Allow simple override for testing: if format is just Y-m-d, use iso slice
                    if(format == "Y-m-d") return dateStr; 

                    return d.toLocaleDateString(undefined, options);
                }
            ';

            return $bookwellab_page_method_data;
        }

        public function bookwellab_get_customers_func()
        {
            global $wpdb;

            if (!\BookWellAB\BookWellAB_Permissions::has_permission('bookwellab_manage_customers')) {
                wp_send_json_error(['msg' => esc_html__('Unauthorized', 'bookwellnow-appointment-booking')]);
            }

            if (!check_ajax_referer('bw_wp_nonce', '_wpnonce', false)) {
                wp_send_json_error(['msg' => esc_html__('Security token mismatch.', 'bookwellnow-appointment-booking')]);
            }

            $customer_table = esc_sql($this->bwdb->get_table_name('customers'));
            $appointments_table = esc_sql($this->bwdb->get_table_name('appointments'));

            $where = '1=1';
            $where_args = [];
            $filter = [];
            // BookWellAB_Input: scalars sanitized via map_deep; filter keys sanitized again below before query.
            $filter_raw = BookWellAB_Input::get_post_array('filter');
            if (!empty($filter_raw)) {
                $filter = [
                    'search' => isset($filter_raw['search']) ? sanitize_text_field($filter_raw['search']) : '',
                ];
            }

            if (!empty($filter['search'])) {
                $s = '%' . $filter['search'] . '%';
                $where .= " AND (bw_first_name LIKE %s OR bw_last_name LIKE %s OR bw_email LIKE %s OR bw_phone LIKE %s)";
                array_push($where_args, $s, $s, $s, $s);
            }

            $limit = isset($_POST['limit']) ? intval(wp_unslash($_POST['limit'])) : 20;
            $page = isset($_POST['page']) ? intval(wp_unslash($_POST['page'])) : 1;
            $offset = ($page - 1) * $limit;
            $limit = max(1, $limit);
            $offset = max(0, $offset);

            $count_sql = "SELECT COUNT(*) FROM $customer_table WHERE $where";
            if (empty($where_args)) {
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name and WHERE are plugin-controlled.
                $total = (int) $wpdb->get_var($count_sql);
            } else {
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name and WHERE are plugin-controlled; values are bound via prepare().
                $total = (int) $wpdb->get_var($wpdb->prepare($count_sql, $where_args));
            }

            $list_sql = "SELECT * FROM $customer_table WHERE $where ORDER BY bw_customer_id DESC LIMIT %d OFFSET %d";
            $list_args = array_merge($where_args, [$limit, $offset]);

            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table names/WHERE are plugin-controlled and values are bound via prepare().
            $customers = $wpdb->get_results($wpdb->prepare($list_sql, $list_args), ARRAY_A);

            if (!empty($customers)) {
                $customer_ids = array_map(
                    static function ($customer_row) {
                        return (int) $customer_row['bw_customer_id'];
                    },
                    $customers
                );
                $placeholders = implode(',', array_fill(0, count($customer_ids), '%d'));
                $stats_sql = "SELECT bw_customer_id, MAX(bw_date) AS recent_appointment, COUNT(bw_appointment_id) AS total_appointments
                              FROM $appointments_table
                              WHERE bw_customer_id IN ($placeholders)
                              GROUP BY bw_customer_id";

                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is plugin-controlled; IDs are bound via prepare().
                $stats_rows = $wpdb->get_results($wpdb->prepare($stats_sql, $customer_ids), ARRAY_A);
                $stats_map = [];

                foreach ($stats_rows as $stats_row) {
                    $stats_map[(int) $stats_row['bw_customer_id']] = $stats_row;
                }

                foreach ($customers as &$customer_row) {
                    $customer_id = (int) $customer_row['bw_customer_id'];
                    $customer_row['recent_appointment'] = $stats_map[$customer_id]['recent_appointment'] ?? null;
                    $customer_row['total_appointments'] = isset($stats_map[$customer_id])
                        ? (int) $stats_map[$customer_id]['total_appointments']
                        : 0;
                }
                unset($customer_row);
            }

            wp_send_json([
                'type' => 'success',
                'list_data' => $customers,
                'total' => $total
            ]);
            exit;
        }

        public function bookwellab_add_customer_func()
        {
            global $wpdb;

            if (!\BookWellAB\BookWellAB_Permissions::has_permission('bookwellab_manage_customers')) {
                wp_send_json_error(['msg' => esc_html__('Unauthorized', 'bookwellnow-appointment-booking')]);
            }

            if (!check_ajax_referer('bw_wp_nonce', '_wpnonce', false)) {
                wp_send_json(['type' => 'error', 'msg' => esc_html__('Security token mismatch.', 'bookwellnow-appointment-booking')]);
                exit;
            }

            // BookWellAB_Input: decoded JSON only; each field sanitized in $data array below before DB upsert.
            $customer_data = BookWellAB_Input::get_post_json('customer_data');
            $id = 0;
            if (isset($customer_data['bw_customer_id']) && !empty($customer_data['bw_customer_id'])) {
                $id = intval($customer_data['bw_customer_id']);
            }

            $data = [
                'bw_first_name' => sanitize_text_field($customer_data['bw_first_name']),
                'bw_last_name' => sanitize_text_field($customer_data['bw_last_name']),
                'bw_email' => sanitize_email($customer_data['bw_email']),
                'bw_phone_code' => sanitize_text_field($customer_data['bw_phone_code']),
                'bw_phone' => sanitize_text_field($customer_data['bw_phone']),
                'bw_country_slug' => BookWellAB_Input::sanitize_country_slug($customer_data['bw_country_slug'] ?? ''),
            ];

            $table = esc_sql($this->bwdb->get_table_name('customers'));

            if ($id == 0) {
                // Check if email already exists
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is plugin-controlled and escaped.
                $exists = $wpdb->get_var($wpdb->prepare("SELECT bw_customer_id FROM $table WHERE bw_email = %s", $data['bw_email']));
                if ($exists) {
                    wp_send_json(['type' => 'error', 'title' => 'Error', 'msg' => __('Customer with this email already exists.', 'bookwellnow-appointment-booking')]);
                    exit;
                }
                $this->bwdb->upsert($table, $data);
                $msg = __('Customer added successfully.', 'bookwellnow-appointment-booking');
            } else {
                $this->bwdb->upsert($table, $data, ['bw_customer_id' => $id]);
                $msg = __('Customer updated successfully.', 'bookwellnow-appointment-booking');
            }

            wp_send_json(['type' => 'success', 'title' => 'Success', 'msg' => $msg]);
            exit;
        }

        public function bookwellab_delete_customer_func()
        {
            global $wpdb;

            if (!\BookWellAB\BookWellAB_Permissions::has_permission('bookwellab_manage_customers')) {
                wp_send_json_error(['msg' => esc_html__('Unauthorized', 'bookwellnow-appointment-booking')]);
            }

            if (!check_ajax_referer('bw_wp_nonce', '_wpnonce', false)) {
                wp_send_json(['type' => 'error', 'msg' => esc_html__('Security token mismatch.', 'bookwellnow-appointment-booking')]);
                exit;
            }

            $id = isset($_POST['id']) ? intval(wp_unslash($_POST['id'])) : 0;
            if ($id <= 0) {
                wp_send_json(['type' => 'error', 'msg' => 'Invalid ID']);
                exit;
            }

            $table = $this->bwdb->get_table_name('customers');
            $wpdb->delete($table, ['bw_customer_id' => $id]);

            wp_send_json(['type' => 'success', 'title' => 'Success', 'msg' => __('Customer deleted successfully.', 'bookwellnow-appointment-booking')]);
            exit;
        }
    }
}
// phpcs:enable
