<?php
namespace orderflow;
use orderflow\Core\Base;
class Checkout_Restrictions extends Base {
    use \orderflow\Traits\Core;
    public function __construct() {
        // Use the recommended validation hook for WooCommerce checkout
        add_action('woocommerce_after_checkout_validation', [$this, 'validate_phone_number_length'], 10, 2);
        add_action('woocommerce_after_checkout_validation', [$this, 'validate_blacklisted_customer_data'], 10, 2);
        add_action('woocommerce_after_checkout_validation', [$this, 'enforce_order_limit_by_customer'], 10, 2);
    }

    /**
     * Validate phone number length on checkout
     */
    public function validate_phone_number_length($data, $errors) {
        if (!get_option('ads_validate_phone_number_length_number') || !self::is_license_active()) return;
        $phone = isset($data['billing_phone']) ? $data['billing_phone'] : '';
        $sanitized_phone = self::normalize_phone_number($phone);
        if (strlen($phone) !== 11 || strlen($sanitized_phone) !== 11) {
            $message = 'দয়া করে একটি সঠিক ১১ সংখ্যার বাংলাদেশী ফোন নম্বর প্রদান করুন (যেমন: 01xxxxxxxxx)। দয়া করে +, +88, 88 বা অন্য কোনো অক্ষর ব্যবহার করবেন না।';
            $errors->add('ads_phone_length', $this->get_error_message_with_contact($message));
        }
    }

    /**
     * Validate blacklisted customer data (phone, email, IP) on checkout
     * Now checks one at a time and returns immediately on finding a block
     */
    public function validate_blacklisted_customer_data($data, $errors) {
        if (!self::is_license_active()) return;

        // Updated base message as per requirement
        $base_message = 'দুঃখিত আপনার অর্ডারটি এই মুহুর্তে গ্রহণ করা যাচ্ছে না, আমাদের সাথে যোগাযোগ করুনঃ';
        $full_message = $this->get_error_message_with_contact($base_message);

        // Check IP first
        if (get_option('ads_block_ip_addresses')) {
            $ip_address = \WC_Geolocation::get_ip_address();
            if ($this->is_customer_data_blocked('ip_address', $ip_address)) {
                $errors->add('ads_block_ip', $full_message);
                return; // Stop further checks if IP is blocked
            }
        }

        // Then check phone
        if (get_option('ads_block_phone_numbers')) {
            $phone = isset($data['billing_phone']) ? sanitize_text_field($data['billing_phone']) : '';
            if ($this->is_customer_data_blocked('phone_number', $phone)) {
                $errors->add('ads_block_phone', $full_message);
                return; // Stop further checks if phone is blocked
            }
        }

        // Finally check email
        if (get_option('ads_block_email_addresses')) {
            $email = isset($data['billing_email']) ? sanitize_email($data['billing_email']) : '';
            if ($this->is_customer_data_blocked('email_address', $email)) {
                $errors->add('ads_block_email', $full_message);
            }
        }
    }

    /**
     * Enforce order limit by customer data (phone, email, IP)
     * Now checks one at a time and returns immediately on finding a limit reached
     */
    public function enforce_order_limit_by_customer($data, $errors) {
        if (!get_option('ads_restrict_multiple_orders') || !self::is_license_active()) return;

        $order_limit = (int) get_option('ads_restrict_multiple_orders_limit', 1);
        $time_limit = (int) get_option('ads_restrict_multiple_orders_time', 24);
        $billing_phone = isset($data['billing_phone']) ? $data['billing_phone'] : '';
        $billing_email = isset($data['billing_email']) ? $data['billing_email'] : '';

        if (!$billing_phone && !$billing_email) return;

        // আপডেট করা বার্তা ফরম্যাট
        $base_message = 'আপনি সর্বোচ্চ অর্ডার সীমা পূর্ণ করেছেন। আমাদের পলিসি অনুযায়ী, নির্দিষ্ট এই  ' . $time_limit . '  ঘন্টার মধ্যে ' . $order_limit . '  টি অর্ডার করতে পারবেন। অনুগ্রহ করে নির্দিষ্ট সময় পরে আবার চেষ্টা করুন অথবা আমাদের সাথে যোগাযোগ করুনঃ';

        $full_message = $this->get_error_message_with_contact($base_message);

        // Check IP first
        $ip_address = \WC_Geolocation::get_ip_address();
        if ($this->has_reached_order_limit('customer_ip_address', $ip_address, $order_limit)) {
            $errors->add('ads_order_limit_ip', $full_message);
            return; // Stop further checks if IP limit is reached
        }

        // Then check phone
        if (!empty($billing_phone) && $this->has_reached_order_limit('billing_phone', $billing_phone, $order_limit)) {
            $errors->add('ads_order_limit_phone', $full_message);
            return; // Stop further checks if phone limit is reached
        }

        // Finally check email
        if (!empty($billing_email) && $this->has_reached_order_limit('billing_email', $billing_email, $order_limit)) {
            $errors->add('ads_order_limit_email', $full_message);
        }
    }

    /**
     * Prepare query args for order limit check
     */
    public static function prepare_order_limit_query_args($customer_data_type, $customer_data_value) {
        $time_limit = (int) get_option('ads_restrict_multiple_orders_time', 24);
        $excluded_statuses = ['wc-pending', 'wc-ads-incomplete'];
        $allowed_statuses = array_diff(array_keys(wc_get_order_statuses()), $excluded_statuses);
        return [
            'date_created' => '>=' . (time() - ($time_limit * 3600)),
            'status' => $allowed_statuses,
            $customer_data_type => $customer_data_value,
            'limit' => -1,
            'orderby' => 'date',
            'order' => 'DESC',
            'paginate' => true,
        ];
    }

    /**
     * Check if customer data is blocked (phone, email, or IP)
     */
    private function is_customer_data_blocked($data_type, $data_value) {
        if (empty($data_value)) return false;
        $normalized_value = $this->normalize_customer_data($data_type, $data_value);
        return $this->is_data_blocked_in_db($data_type, $normalized_value);
    }

    /**
     * Normalize customer data before checking/blocking
     */
    private function normalize_customer_data($data_type, $data_value) {
        switch ($data_type) {
            case 'phone_number': return self::normalize_phone_number($data_value);
            case 'email_address': return strtolower(sanitize_email($data_value));
            case 'ip_address': return filter_var($data_value, FILTER_VALIDATE_IP);
            default: return $data_value;
        }
    }

    /**
     * Check blocked data in DB
     */
    private function is_data_blocked_in_db($data_type, $normalized_value) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'ads_customers_data';
        $result = $wpdb->get_var($wpdb->prepare(
            "SELECT data_access FROM {$table_name} WHERE data_type = %s AND data_value = %s LIMIT 1",
            $data_type,
            $normalized_value
        ));
        return $result === 'blocked';
    }

    /**
     * Check if customer has reached order limit
     */
    private function has_reached_order_limit($data_type, $data_value, $order_limit) {
        $args = self::prepare_order_limit_query_args($data_type, $data_value);
        $orders = wc_get_orders($args);
        return $orders->total >= $order_limit;
    }

    /**
     * Add contact info to error message (if available) - Updated format
     */
    private function get_error_message_with_contact($base_message) {
        $contact_phone = get_option('ads_checkout_process_error_contact_phone_number');
        if (!empty($contact_phone)) {
            // Format the message as requested: "দুঃখিত আপনার অর্ডারটি এই মুহুর্তে গ্রহণ করা যাচ্ছে না, আমাদের সাথে যোগাযোগ করুনঃ { ফোন নাম্বার }"
            return $base_message  . $contact_phone ;
        }
        return $base_message;
    }

    /**
     * Normalize phone number for Bangladesh (remove +, +88, 88)
     */
    public static function normalize_phone_number($phone) {
        $phone = preg_replace('/[^\d]/', '', $phone);
        if (strpos($phone, '880') === 0) $phone = substr($phone, 2);
        if (strlen($phone) === 10 && strpos($phone, '0') !== 0) $phone = '0' . $phone;
        return $phone;
    }
}