<?php
/**
 * Customer Account Data Handler
 * Manages account-related data operations for customer account widget
 */

// If this file is called directly, abort.
if (!defined('ABSPATH')) {
    exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

class GGM_Commerce_Customer_Account_Data_Handler {
    
    /**
     * Check if user is logged in
     */
    public function is_user_logged_in() {
        return is_user_logged_in();
    }
    
    /**
     * Get current user ID
     */
    public function get_current_user_id() {
        return get_current_user_id();
    }
    
    /**
     * Get current user data
     */
    public function get_current_user() {
        return wp_get_current_user();
    }
    
    /**
     * Get user orders with pagination
     */
    public function get_user_orders($user_id, $limit = 10, $offset = 0) {
        global $wpdb;
        $orders_table = $wpdb->prefix . 'ggmc_orders';

        // Get user email since orders table uses both user_id and customer_email
        $user = get_userdata($user_id);
        if (!$user) {
            return array();
        }

        // Query by both user_id and email for better matching
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orders_table is safely constructed from $wpdb->prefix
        return $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $orders_table WHERE user_id = %d OR customer_email = %s ORDER BY created_at DESC LIMIT %d OFFSET %d",
            $user_id,
            $user->user_email,
            $limit,
            $offset
        ));
    }

    /**
     * Get total count of user orders (for pagination)
     */
    public function get_user_orders_count($user_id) {
        global $wpdb;
        $orders_table = $wpdb->prefix . 'ggmc_orders';

        $user = get_userdata($user_id);
        if (!$user) {
            return 0;
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orders_table is safely constructed from $wpdb->prefix
        return (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $orders_table WHERE user_id = %d OR customer_email = %s",
            $user_id,
            $user->user_email
        ));
    }
    
    /**
     * Get user meta data
     */
    public function get_user_meta($user_id, $meta_key, $single = true) {
        return get_user_meta($user_id, $meta_key, $single);
    }
    
    /**
     * Update user meta data
     */
    public function update_user_meta($user_id, $meta_key, $meta_value) {
        return update_user_meta($user_id, $meta_key, $meta_value);
    }
    
    /**
     * Get user profile data
     */
    public function get_user_profile($user_id) {
        global $wpdb;

        $user = get_userdata($user_id);
        if (!$user) {
            return null;
        }

        // Get from WordPress user meta first
        $first_name = $this->get_user_meta($user_id, 'first_name');
        $last_name = $this->get_user_meta($user_id, 'last_name');
        $phone = $this->get_user_meta($user_id, 'phone');

        // If WordPress meta is empty, try the ggmc_customers table as fallback
        if (empty($first_name) || empty($last_name)) {
            $customer = $wpdb->get_row($wpdb->prepare(
                "SELECT first_name, last_name, phone FROM {$wpdb->prefix}ggmc_customers
                 WHERE user_id = %d OR email = %s LIMIT 1",
                $user_id,
                $user->user_email
            ));

            if ($customer) {
                if (empty($first_name) && !empty($customer->first_name)) {
                    $first_name = $customer->first_name;
                }
                if (empty($last_name) && !empty($customer->last_name)) {
                    $last_name = $customer->last_name;
                }
                if (empty($phone) && !empty($customer->phone)) {
                    $phone = $customer->phone;
                }
            }
        }

        return [
            'first_name' => $first_name ?: '',
            'last_name' => $last_name ?: '',
            'email' => $user->user_email,
            'phone' => $phone ?: '',
            'display_name' => $user->display_name
        ];
    }
    
    /**
     * Update user profile
     */
    public function update_user_profile($user_id, $profile_data) {
        global $wpdb;
        $result = [];

        // Update basic user data
        if (isset($profile_data['email'])) {
            $user_update = wp_update_user([
                'ID' => $user_id,
                'user_email' => sanitize_email($profile_data['email'])
            ]);

            if (is_wp_error($user_update)) {
                $result['error'] = $user_update->get_error_message();
                return $result;
            }
        }

        // Update WordPress user meta fields
        $meta_fields = ['first_name', 'last_name', 'phone'];
        foreach ($meta_fields as $field) {
            if (isset($profile_data[$field])) {
                $this->update_user_meta($user_id, $field, sanitize_text_field($profile_data[$field] ?? ''));
            }
        }

        // Also update the ggmc_customers table to keep data in sync
        $user = get_userdata($user_id);
        if ($user) {
            $customer = $wpdb->get_row($wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}ggmc_customers WHERE user_id = %d OR email = %s LIMIT 1",
                $user_id,
                $user->user_email
            ));

            $customer_data = [];
            if (isset($profile_data['first_name'])) {
                $customer_data['first_name'] = sanitize_text_field($profile_data['first_name']);
            }
            if (isset($profile_data['last_name'])) {
                $customer_data['last_name'] = sanitize_text_field($profile_data['last_name']);
            }
            if (isset($profile_data['phone'])) {
                $customer_data['phone'] = sanitize_text_field($profile_data['phone']);
            }
            if (isset($profile_data['email'])) {
                $customer_data['email'] = sanitize_email($profile_data['email']);
            }

            if (!empty($customer_data)) {
                if ($customer) {
                    // Update existing customer record
                    $wpdb->update(
                        "{$wpdb->prefix}ggmc_customers",
                        $customer_data,
                        ['id' => $customer->id]
                    );
                } else {
                    // Create new customer record
                    $customer_data['user_id'] = $user_id;
                    if (!isset($customer_data['email'])) {
                        $customer_data['email'] = $user->user_email;
                    }
                    $wpdb->insert("{$wpdb->prefix}ggmc_customers", $customer_data);
                }
            }
        }

        $result['success'] = true;
        return $result;
    }
    
    /**
     * Get default billing address for user from customer_addresses table
     */
    public function get_billing_address($user_id) {
        global $wpdb;

        // First, get the customer_id from the customers table
        $user = get_userdata($user_id);
        if (!$user) {
            return $this->empty_address();
        }

        $customer = $wpdb->get_row($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}ggmc_customers WHERE user_id = %d OR email = %s LIMIT 1",
            $user_id,
            $user->user_email
        ));

        if (!$customer) {
            return $this->empty_address();
        }

        // Get default billing address
        $address = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_customer_addresses
             WHERE customer_id = %d AND address_type = 'billing' AND is_default = 1
             LIMIT 1",
            $customer->id
        ));

        // If no default, get the most recent billing address
        if (!$address) {
            $address = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}ggmc_customer_addresses
                 WHERE customer_id = %d AND address_type = 'billing'
                 ORDER BY created_at DESC
                 LIMIT 1",
                $customer->id
            ));
        }

        if (!$address) {
            return $this->empty_address();
        }

        return [
            'address_1' => $address->address_1 ?? '',
            'address_2' => $address->address_2 ?? '',
            'city' => $address->city ?? '',
            'state' => $address->state ?? '',
            'postcode' => $address->postcode ?? '',
            'country' => $address->country ?? ''
        ];
    }

    /**
     * Get default shipping address for user from customer_addresses table
     */
    public function get_shipping_address($user_id) {
        global $wpdb;

        // First, get the customer_id from the customers table
        $user = get_userdata($user_id);
        if (!$user) {
            return $this->empty_address();
        }

        $customer = $wpdb->get_row($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}ggmc_customers WHERE user_id = %d OR email = %s LIMIT 1",
            $user_id,
            $user->user_email
        ));

        if (!$customer) {
            return $this->empty_address();
        }

        // Get default shipping address
        $address = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_customer_addresses
             WHERE customer_id = %d AND address_type = 'shipping' AND is_default = 1
             LIMIT 1",
            $customer->id
        ));

        // If no default, get the most recent shipping address
        if (!$address) {
            $address = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}ggmc_customer_addresses
                 WHERE customer_id = %d AND address_type = 'shipping'
                 ORDER BY created_at DESC
                 LIMIT 1",
                $customer->id
            ));
        }

        if (!$address) {
            return $this->empty_address();
        }

        return [
            'address_1' => $address->address_1 ?? '',
            'address_2' => $address->address_2 ?? '',
            'city' => $address->city ?? '',
            'state' => $address->state ?? '',
            'postcode' => $address->postcode ?? '',
            'country' => $address->country ?? ''
        ];
    }

    /**
     * Get all addresses for a customer
     */
    public function get_customer_addresses($user_id, $address_type = null) {
        global $wpdb;

        $user = get_userdata($user_id);
        if (!$user) {
            return [];
        }

        $customer = $wpdb->get_row($wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}ggmc_customers WHERE user_id = %d OR email = %s LIMIT 1",
            $user_id,
            $user->user_email
        ));

        if (!$customer) {
            return [];
        }

        $query = "SELECT * FROM {$wpdb->prefix}ggmc_customer_addresses WHERE customer_id = %d";
        $params = [$customer->id];

        if ($address_type) {
            $query .= " AND address_type = %s";
            $params[] = $address_type;
        }

        $query .= " ORDER BY is_default DESC, created_at DESC";

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $query is built safely above with conditionals
        return $wpdb->get_results($wpdb->prepare($query, $params));
    }

    /**
     * Return empty address array
     */
    private function empty_address() {
        return [
            'address_1' => '',
            'address_2' => '',
            'city' => '',
            'state' => '',
            'postcode' => '',
            'country' => ''
        ];
    }
    
    /**
     * Update user address
     */
    public function update_user_address($user_id, $address_type, $address_data) {
        $prefix = $address_type === 'billing' ? 'billing_' : 'shipping_';
        $fields = ['address_1', 'address_2', 'city', 'state', 'postcode', 'country'];
        
        foreach ($fields as $field) {
            if (isset($address_data[$field])) {
                $meta_key = $prefix . $field;
                $this->update_user_meta($user_id, $meta_key, sanitize_text_field($address_data[$field] ?? ''));
            }
        }
        
        return ['success' => true];
    }
    
    /**
     * Register new user
     */
    public function register_user($username, $email, $password, $additional_data = []) {
        global $wpdb;

        // Check if user exists
        if (username_exists($username) || email_exists($email)) {
            return ['error' => __('Username or email already exists.', 'ggm-commerce')];
        }

        // Create user
        $user_id = wp_create_user($username, $password, $email);

        if (is_wp_error($user_id)) {
            return ['error' => $user_id->get_error_message()];
        }

        // Extract account type and business fields before processing meta
        $account_type = isset($additional_data['account_type']) ? sanitize_text_field($additional_data['account_type']) : 'individual';
        $company_name = isset($additional_data['company_name']) ? sanitize_text_field($additional_data['company_name']) : '';
        $tax_id = isset($additional_data['tax_id']) ? sanitize_text_field($additional_data['tax_id']) : '';

        // Remove these from additional_data so they're not saved as user meta
        unset($additional_data['account_type']);
        unset($additional_data['company_name']);
        unset($additional_data['tax_id']);

        // Update additional user data (first_name, last_name, etc.)
        if (!empty($additional_data)) {
            foreach ($additional_data as $key => $value) {
                $this->update_user_meta($user_id, $key, sanitize_text_field($value ?? ''));
            }
        }

        // Create customer record with account type
        $customer_data = [
            'user_id' => $user_id,
            'email' => $email,
            'first_name' => isset($additional_data['first_name']) ? $additional_data['first_name'] : '',
            'last_name' => isset($additional_data['last_name']) ? $additional_data['last_name'] : '',
            'account_type' => $account_type,
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ];

        // Add business fields if account type is business
        if ($account_type === 'business') {
            $customer_data['company'] = $company_name;
            $customer_data['tax_id'] = $tax_id;

            // Set up tax exemption if tax ID is provided
            if (!empty($tax_id)) {
                $customer_data['is_tax_exempt'] = 1;
                $tax = ggm_commerce_tax();
                $customer_data['tax_exempt_status'] = $tax->is_b2b_validation_required() ? 'pending' : 'approved';
            }
        }

        $wpdb->insert("{$wpdb->prefix}ggmc_customers", $customer_data);

        return ['success' => true, 'user_id' => $user_id];
    }
    
    /**
     * Authenticate user login
     */
    public function login_user($username, $password, $remember = false) {
        $credentials = [
            'user_login' => $username,
            'user_password' => $password,
            'remember' => $remember
        ];
        
        $user = wp_signon($credentials);
        
        if (is_wp_error($user)) {
            return ['error' => $user->get_error_message()];
        }
        
        return ['success' => true, 'user' => $user];
    }
    
    /**
     * Get logout URL
     */
    public function get_logout_url($redirect = '') {
        if (empty($redirect)) {
            $redirect = home_url();
        }
        return wp_logout_url($redirect);
    }
    
    /**
     * Format order status
     */
    public function format_order_status($status) {
        $statuses = [
            'pending' => __('Pending', 'ggm-commerce'),
            'processing' => __('Processing', 'ggm-commerce'),
            'shipped' => __('Shipped', 'ggm-commerce'),
            'delivered' => __('Delivered', 'ggm-commerce'),
            'cancelled' => __('Cancelled', 'ggm-commerce'),
            'refunded' => __('Refunded', 'ggm-commerce')
        ];
        
        return isset($statuses[$status]) ? $statuses[$status] : ucfirst($status);
    }
    
    /**
     * Get order details by ID
     */
    public function get_order_details($order_id) {
        global $wpdb;
        $orders_table = $wpdb->prefix . 'ggmc_orders';
        $order_items_table = $wpdb->prefix . 'ggmc_order_items';
        
        // Get order
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orders_table is safely constructed from $wpdb->prefix
        $order = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $orders_table WHERE id = %d",
            $order_id
        ));

        if (!$order) {
            return null;
        }

        // Get order items
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $order_items_table is safely constructed from $wpdb->prefix
        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $order_items_table WHERE order_id = %d",
            $order_id
        ));
        
        $order->items = $items;
        return $order;
    }
    
    /**
     * Validate email format
     */
    public function validate_email($email) {
        return is_email($email);
    }
    
    /**
     * Validate password strength
     */
    public function validate_password($password, $min_length = 6) {
        if (strlen($password) < $min_length) {
            /* translators: %d: minimum password length */
            return ['valid' => false, 'message' => sprintf(__('Password must be at least %d characters long.', 'ggm-commerce'), $min_length)];
        }
        
        return ['valid' => true];
    }
    
    /**
     * Get countries list for address forms
     */
    public function get_countries() {
        return [
            'US' => __('United States', 'ggm-commerce'),
            'CA' => __('Canada', 'ggm-commerce'),
            'GB' => __('United Kingdom', 'ggm-commerce'),
            'AU' => __('Australia', 'ggm-commerce'),
            'DE' => __('Germany', 'ggm-commerce'),
            'FR' => __('France', 'ggm-commerce'),
            'IT' => __('Italy', 'ggm-commerce'),
            'ES' => __('Spain', 'ggm-commerce'),
            'NL' => __('Netherlands', 'ggm-commerce'),
            'BE' => __('Belgium', 'ggm-commerce'),
            'CH' => __('Switzerland', 'ggm-commerce'),
            'AT' => __('Austria', 'ggm-commerce'),
            'SE' => __('Sweden', 'ggm-commerce'),
            'NO' => __('Norway', 'ggm-commerce'),
            'DK' => __('Denmark', 'ggm-commerce'),
            'FI' => __('Finland', 'ggm-commerce'),
            'JP' => __('Japan', 'ggm-commerce'),
            'KR' => __('South Korea', 'ggm-commerce'),
            'SG' => __('Singapore', 'ggm-commerce'),
            'HK' => __('Hong Kong', 'ggm-commerce'),
            'NZ' => __('New Zealand', 'ggm-commerce'),
            'MX' => __('Mexico', 'ggm-commerce'),
            'BR' => __('Brazil', 'ggm-commerce'),
            'AR' => __('Argentina', 'ggm-commerce'),
            'CL' => __('Chile', 'ggm-commerce'),
            'IN' => __('India', 'ggm-commerce'),
            'CN' => __('China', 'ggm-commerce'),
            'RU' => __('Russia', 'ggm-commerce'),
            'ZA' => __('South Africa', 'ggm-commerce'),
            'EG' => __('Egypt', 'ggm-commerce'),
            'NG' => __('Nigeria', 'ggm-commerce'),
            'KE' => __('Kenya', 'ggm-commerce'),
            'MA' => __('Morocco', 'ggm-commerce'),
            'TN' => __('Tunisia', 'ggm-commerce'),
            'GH' => __('Ghana', 'ggm-commerce'),
            'UG' => __('Uganda', 'ggm-commerce'),
            'TZ' => __('Tanzania', 'ggm-commerce'),
            'ZW' => __('Zimbabwe', 'ggm-commerce'),
            'BW' => __('Botswana', 'ggm-commerce'),
            'ZM' => __('Zambia', 'ggm-commerce'),
            'MW' => __('Malawi', 'ggm-commerce'),
            'MZ' => __('Mozambique', 'ggm-commerce'),
            'AO' => __('Angola', 'ggm-commerce'),
            'NA' => __('Namibia', 'ggm-commerce'),
            'SZ' => __('Eswatini', 'ggm-commerce'),
            'LS' => __('Lesotho', 'ggm-commerce'),
        ];
    }
    
    /**
     * Sanitize user input data
     */
    public function sanitize_user_data($data) {
        $sanitized = [];
        
        foreach ($data as $key => $value) {
            switch ($key) {
                case 'email':
                    $sanitized[$key] = sanitize_email($value ?? '');
                    break;
                case 'phone':
                    $sanitized[$key] = preg_replace('/[^0-9+\-\s\(\)]/', '', $value ?? '');
                    break;
                default:
                    $sanitized[$key] = sanitize_text_field($value ?? '');
                    break;
            }
        }
        
        return $sanitized;
    }
    
    /**
     * Get user capabilities
     */
    public function get_user_capabilities($user_id) {
        $user = get_userdata($user_id);
        return $user ? $user->allcaps : [];
    }
    
    /**
     * Check if user can perform action
     */
    public function user_can($user_id, $capability) {
        return user_can($user_id, $capability);
    }

    /**
     * Get GGM Commerce customer record by WordPress user ID
     */
    public function get_customer_by_user_id($user_id) {
        global $wpdb;

        $user = get_userdata($user_id);
        if (!$user) {
            return null;
        }

        // Query by both user_id and email
        return $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_customers WHERE user_id = %d OR email = %s LIMIT 1",
            $user_id,
            $user->user_email
        ));
    }

    /**
     * Update customer business details (company, tax ID, exemption status)
     * Also handles account type upgrade from Individual to Business
     */
    public function update_customer_business($user_id, $business_data) {
        global $wpdb;

        $user = get_userdata($user_id);
        if (!$user) {
            return ['error' => 'User not found'];
        }

        // Get or create customer record
        $customer = $this->get_customer_by_user_id($user_id);

        $update_data = [];

        if (isset($business_data['company_name'])) {
            $update_data['company'] = sanitize_text_field($business_data['company_name']);
        }

        if (isset($business_data['tax_id'])) {
            $update_data['tax_id'] = sanitize_text_field($business_data['tax_id']);

            // If tax ID is provided and not empty, set up exemption
            if (!empty($business_data['tax_id'])) {
                $update_data['is_tax_exempt'] = 1;

                // Check if validation is required
                $tax = ggm_commerce_tax();
                if ($tax->is_b2b_validation_required()) {
                    // Set to pending if validation required and not already approved
                    if (!$customer || $customer->tax_exempt_status !== 'approved') {
                        $update_data['tax_exempt_status'] = 'pending';
                    }
                } else {
                    // Auto-approve if validation not required
                    $update_data['tax_exempt_status'] = 'approved';
                }

                // If Individual customer is adding business details, upgrade to Business account
                if ($customer && $customer->account_type === 'individual') {
                    $update_data['account_type'] = 'business';
                }
            } else {
                // Clear exemption if tax ID is removed
                $update_data['is_tax_exempt'] = 0;
                $update_data['tax_exempt_status'] = 'none';
            }
        }

        $update_data['updated_at'] = current_time('mysql');

        if ($customer) {
            // Update existing record
            $result = $wpdb->update(
                "{$wpdb->prefix}ggmc_customers",
                $update_data,
                ['id' => $customer->id]
            );
        } else {
            // Create new customer record
            $update_data['user_id'] = $user_id;
            $update_data['email'] = $user->user_email;
            $update_data['first_name'] = get_user_meta($user_id, 'first_name', true) ?: '';
            $update_data['last_name'] = get_user_meta($user_id, 'last_name', true) ?: '';
            $update_data['account_type'] = 'business'; // Creating via business tab means they want to be business
            $update_data['created_at'] = current_time('mysql');

            $result = $wpdb->insert("{$wpdb->prefix}ggmc_customers", $update_data);
        }

        if ($result === false) {
            return ['error' => 'Failed to update business details'];
        }

        // Get updated customer data
        $updated_customer = $this->get_customer_by_user_id($user_id);

        return [
            'success' => true,
            'tax_exempt_status' => $updated_customer->tax_exempt_status ?? 'none',
            'account_type' => $updated_customer->account_type ?? 'individual',
            'message' => __('Business details saved successfully.', 'ggm-commerce')
        ];
    }

    /**
     * Update customer price display preference
     */
    public function update_price_display_preference($user_id, $preference) {
        $valid_preferences = ['default', 'excluding', 'including'];

        if (!in_array($preference, $valid_preferences, true)) {
            return ['error' => 'Invalid preference'];
        }

        update_user_meta($user_id, 'ggmc_price_display_preference', $preference);

        return [
            'success' => true,
            'message' => __('Price display preference saved.', 'ggm-commerce')
        ];
    }

    /**
     * Get customer downloads (digital products purchased)
     */
    public function get_customer_downloads($user_id) {
        // Check if downloads feature is available
        if (!class_exists('GGM_Commerce_Downloads')) {
            return [];
        }

        $user = get_userdata($user_id);
        if (!$user) {
            return [];
        }

        $downloads_manager = GGM_Commerce_Downloads::instance();
        return $downloads_manager->get_customer_downloads($user->user_email);
    }

    /**
     * Check if downloads feature is enabled and customer has downloads
     */
    public function customer_has_downloads($user_id) {
        if (!class_exists('GGM_Commerce_Downloads') || !GGM_Commerce_Downloads::is_activated()) {
            return false;
        }

        $downloads = $this->get_customer_downloads($user_id);
        return !empty($downloads);
    }

    /**
     * Check if downloads feature is activated
     */
    public function is_downloads_feature_active() {
        return class_exists('GGM_Commerce_Downloads') && GGM_Commerce_Downloads::is_activated();
    }
}