<?php
namespace Formipay;
use Formipay\Traits\SingletonTrait;

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

class Customer {

    use SingletonTrait;

    private $order_data;

	/**
	 * Initializes the plugin by setting filters and administration functions.
	 */
    
    protected function __construct() {

        add_action( 'init',                                     [$this, 'create_db'] );
        add_action( 'admin_menu',                               [$this, 'add_menu'] );
        add_action( 'admin_enqueue_scripts',                    [$this, 'enqueue'] );
        add_action( 'wp_ajax_formipay-tabledata-customers',        [$this, 'formipay_tabledata_customers'] );
        add_action( 'wp_ajax_formipay_check_for_data_mapping_saved_value', [$this, 'check_data_mapping'] );

        // Add Global & Form Settings
        // add_filter( 'formipay/global-settings',                 [$this, 'global_settings'] );
        add_filter( 'formipay/global-settings/tab:general',    [$this, 'global_settings'], 20 );
        add_filter( 'formipay/form-config',                     [$this, 'add_menu_on_product_setting'], 100 );

        // For Coupon Autocomplete
        add_filter( 'stm_wpcfto_autocomplete_customers',       [$this, 'autocomplete_options'], 100, 2 );

        // Register new customer by order submitted
        add_action( 'formipay/order/new',                       [$this, 'add_customer'] );
    }

    public function create_db() {

        global $wpdb;
        $charset_collate = $wpdb->get_charset_collate();

        $create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_customers` (
            `id` bigint(20) NOT NULL AUTO_INCREMENT,
            `user_id` bigint(20) DEFAULT 0,
            `registered_date` datetime DEFAULT '00-00-00 00:00:00',
            `name` text,
            `phone` text,
            `email` text,
            `purchase_value` float(10, 4) DEFAULT 0,
            `purchase_count` int,
            `meta_data` text, 
            PRIMARY KEY (`id`)
        ) $charset_collate;";

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        dbDelta($create);

    }

    public function submit($args) {

        $args = wp_parse_args( $args, [
            'user_id'           => 0,
            'registered_date'   => '',
            'name'              => NULL,
            'phone'             => NULL,
            'email'             => NULL,
            'purchase_value'    => 0,
            'purchase_count'    => 0,
            'meta_data'         => []
        ] );

        global $wpdb;
        $table = $wpdb->prefix . 'formipay_customers';

        $insert_data = [
            'user_id'           => intval($args['user_id']),
            'registered_date'   => formipay_date('Y-m-d H:i:s'),
            'name'              => sanitize_text_field( $args['name'] ),
            'phone'             => sanitize_text_field( $args['phone'] ),
            'email'             => sanitize_email( $args['email'] ),
            'purchase_value'    => floatval($args['purchase_value']),
            'purchase_count'    => intval($args['purchase_count']),
            'meta_data'         => maybe_serialize($args['meta_data'])
        ];

        if($args['name'] !== ''){
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $wpdb->insert($table, $insert_data);

            return $wpdb->insert_id;
        }
        
        return false;

    }

    public function get($customer_id = 0) {

        global $wpdb;
        $table = $wpdb->prefix .'formipay_customers';
        if($customer_id == 0){
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $get = $wpdb->get_results(
                $wpdb->prepare(
                    "SELECT * FROM %i", $table
                )
            );
        }else{
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $get = $wpdb->get_row(
                $wpdb->prepare(
                    "SELECT * FROM %i WHERE `id` = %d", $table, $customer_id
                )
            );
        }
        
        return $get;

    }

    public function get_by_email($email) {
        global $wpdb;
        $table = $wpdb->prefix .'formipay_customers';
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $get = $wpdb->get_row(
            $wpdb->prepare(
                 "SELECT * FROM %i WHERE `email` = %s", $table, $email 
            ), ARRAY_A
        );
        
        return $get;
    }

    public function update($customer_id, $args) {

        $recent_data = $this->get($customer_id);

        $args = wp_parse_args( $args, [
            'user_id'           => $recent_data->user_id,
            'name'              => $recent_data->name,
            'phone'             => $recent_data->phone,
            'email'             => $recent_data->email,
            'purchase_value'    => $recent_data->purchase_value,
            'purchase_count'    => $recent_data->purchase_count,
            'meta_data'         => maybe_unserialize( $recent_data->meta_data )
        ] );

        global $wpdb;
        $table = $wpdb->prefix . 'formipay_customers';

        $insert_data = [
            'user_id'           => intval($args['user_id']),
            'name'              => sanitize_text_field( $args['name'] ),
            'phone'             => sanitize_text_field( $args['phone'] ),
            'email'             => sanitize_email( $args['email'] ),
            'purchase_value'    => floatval($args['purchase_value']),
            'purchase_count'    => intval($args['purchase_count']),
            'meta_data'         => maybe_serialize($args['meta_data'])
        ];

        $where = [ 'id' => $customer_id ];
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$update = $wpdb->update( $table_name, $new_args, $where );
        
        return $update;

    }

    public function add_menu() {

        add_submenu_page( 
            'formipay', 
            __( 'Customers', 'formipay' ), 
            __( 'Customers', 'formipay' ), 
            'manage_options', 
            'formipay-customers', 
            [$this, 'customers_page'] 
        );

    }

    public function enqueue() {

        global $current_screen;

        if($current_screen->id == 'formipay_page_formipay-customers') {

            $customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
            if(empty($customer_id)){
                wp_enqueue_style( 'page-customers', FORMIPAY_URL . 'admin/assets/css/admin-customers.css', [], FORMIPAY_VERSION, 'all' );
                wp_enqueue_script( 'page-customers', FORMIPAY_URL . 'admin/assets/js/admin-customers.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
            }else{
                wp_enqueue_style( 'bootstrap-icon', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all');
                wp_enqueue_style( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.min.css', [], '5.3.2' );
                wp_enqueue_style( 'page-customers', FORMIPAY_URL . 'admin/assets/css/admin-customer-details.css', [], FORMIPAY_VERSION, 'all' );
                wp_enqueue_script( 'handlebars', FORMIPAY_URL . 'vendor/HandleBars/handlebars.min.js', [], '4.7.7', true);
                wp_enqueue_script( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.bundle.min.js', ['jquery'], '5.3.2', true );
                wp_enqueue_script( 'page-customers', FORMIPAY_URL . 'admin/assets/js/admin-customer-details.js', ['jquery'], FORMIPAY_VERSION, true );
            }

            wp_localize_script( 'page-customers', 'formipay_customers_page', [
                'ajax_url' => admin_url('admin-ajax.php'),
                'site_url' => site_url(),
                'customer_id' => $customer_id,
                'columns' => [
                    'id' => esc_html__( 'ID', 'formipay' ),
                    'name' => esc_html__( 'Name', 'formipay' ),
                    'email' => esc_html__( 'Email', 'formipay' ),
                    'phone' => esc_html__( 'Phone', 'formipay' ),
                    'total_order' => esc_html__( 'Total Order', 'formipay' ),
                ]
            ] );

        }

    }

    public function customers_page() {

        $customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
        if(empty($customer_id)){
            include FORMIPAY_PATH . 'admin/page-customers.php';
        }else{
            include FORMIPAY_PATH . 'admin/page-customer-details.php';
        }

    }

    public function formipay_tabledata_customers() {

        $get_all_customers = $this->get();
        $customers = [];

        if(!empty($get_all_customers)){
            foreach($get_all_customers as $customer){
                $customers[] = [
                    'ID' => $customer->id,
                    'name' => $customer->name,
                    'email' => $customer->email,
                    'phone' => $customer->phone,
                    'total_order' => $customer->purchase_count
                ];
            }
        }
    
        // Prepare response data
        $response = [
            'results' => $customers,
            'total' => count($get_all_customers),
            'posts_report' =>  $customers
        ];
    
        wp_send_json($response);

    }

    public function check_data_mapping() {

        check_ajax_referer( 'formipay-form-editor', '_wpnonce' );

        $form_id = isset($_REQUEST['post']) ? intval($_REQUEST['post']) : 0;

        $saved = [
            'buyer_name' => formipay_get_post_meta($form_id, 'buyer_name'),
            'buyer_country' => formipay_get_post_meta($form_id, 'buyer_country')
        ];

        $medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
        
        if(!empty($medias)){
            foreach($medias as $media) {
                $saved['buyer_'.$media] = formipay_get_post_meta($form_id, 'buyer_'.$media);
            }
        }

        wp_send_json($saved);

    }

    public function global_settings($fields) {
        
        $config = array(
            'customer_field_group' => array(
                'type'  => 'group_title',
                'label' => __( 'Customer Data', 'formipay' ),
                'group' => 'started'
            ),
            'customer_mandatory_data' => array(
                'type' => 'sorter',
                'label' => __( 'Identities', 'formipay' ),
                'options' => array(
                    array(
                        'id' => 'optional',
                        'name' => esc_html__( 'Optional', 'formipay' ),
                        'options' => array(
                            array(
                                'id' => 'phone',
                                'label' => esc_html__( 'Phone', 'formipay' ),
                            ),
                        )
                    ),
                    array(
                        'id' => 'mandatory',
                        'name' => esc_html__( 'Mandatory', 'formipay' ),
                        'options' => array(
                            array(
                                'id' => 'name',
                                'label' => esc_html__( 'Name', 'formipay' ),
                                'icon' => 'fa fa-exclamation',
                                'class' => 'disable'
                            ),
                            array(
                                'id' => 'email',
                                'label' => esc_html__( 'Email', 'formipay' ),
                            ),
                        )
                    )
                ),
                'group' => 'ended'
            )
        );

        $fields = array_merge($fields, $config);

        // $customer_settings = apply_filters( 'formipay/global-settings/tab:customer', $config );

        // if(!empty($customer_settings)){
        //     $fields['customer'] = array(
        //         'name' => __('Customer', 'formipay'),
        //         'fields' => $customer_settings
        //     );
        // }

        return $fields;
    
    }

    public function add_menu_on_product_setting($fields) {
        $medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
        $customer_mandatory_data = formipay_customer_mandatory_data();

        $customer_fields = [
            'notification_buyer_identify' => [
                'type'          => 'group_title',
                'label'         => __( 'Data Mapping', 'formipay' ),
                'group'         => 'started',
                'description'   => __( 'Match the required data for store the customer data, render shortcode and sending notification (if any)', 'formipay' ),
            ],
            'buyer_name' => [
                'type'          => 'select',
                'label'         => __( 'Buyer\'s Name Field ID', 'formipay' ),
                'description'   => __( 'Fill in the field ID that represents the buyer\'s name.', 'formipay' ),
                'required'      => true
            ]
        ];

        foreach($medias as $media){

            $customer_fields['buyer_'.$media] = [
                'type'          => 'select',
                // translators: %s is the media type name.
                'label'         => sprintf( __('Buyer\'s %s Field ID', 'formipay' ), ucfirst($media) ),
                // translators: %s is the media type name.
                'description'   => sprintf( __( 'Fill in the field ID that represents the buyer\'s %s.', 'formipay' ), ucfirst($media) ),
                'required'      => in_array($media, $customer_mandatory_data) ? true : false
            ];

        }

        if(in_array('phone', $medias)){
            $customer_fields['buyer_allow_choose_country_code'] = [
                'type'          => 'checkbox',
                'label'         => __('Buyer\'s can choose their own country code', 'formipay' ),
                'value'    => true,
                'required'      => in_array('phone', $customer_mandatory_data) ? true : false
            ];
            $customer_fields['buyer_country'] = [
                'type'          => 'select',
                'label'         => __('Buyer\'s Country Field', 'formipay' ),
                'description'   => __( 'Fill in the field ID that represents the buyer\'s country. This will define the country phone code.', 'formipay' ),
                'required'      => in_array('phone', $customer_mandatory_data) ? true : false,
                'dependency' => array(
                    'key' => 'buyer_allow_choose_country_code',
                    'value' => 'not_empty'
                )
            ];
            $customer_fields['buyer_phone_country_code'] = [
                'type'          => 'select',
                'label'         => __('Buyer\'s Default Country Code', 'formipay' ),
                'options'       => formipay_phone_country_code_options(),
                'required'      => true,
                'searchable'    => true,
                'required'      => in_array('phone', $customer_mandatory_data) ? true : false,
                'dependency' => array(
                    'key' => 'buyer_allow_choose_country_code',
                    'value' => 'empty'
                )
            ];
        }

        $last_data_mapping_fields = array_key_last($customer_fields);
        $customer_fields[$last_data_mapping_fields]['group'] = 'ended';

        $fields['formipay_form_settings']['customer_data'] = [
            'name' => __('Customer Data', 'formipay'),
            'fields' => $customer_fields
        ];

        return $fields;
    }
    
    public function add_customer($order_data) {

        $this->order_data = $order_data;
        $buyer_name_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
        $buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_email');
        $buyer_phone_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_phone');

        // Fallback Array
        $customer_data = [
            'name' => '',
            'email' => '',
            'phone' => ''
        ];

        if(!empty($buyer_name_field) && !empty($this->order_data['form_data'][$buyer_name_field])) {
            $customer_data['name'] = $this->order_data['form_data'][$buyer_name_field]['value'];
        }

        if(!empty($buyer_email_field) && !empty($this->order_data['form_data'][$buyer_email_field])) {
            $customer_data['email'] = $this->order_data['form_data'][$buyer_email_field]['value'];
        }

        if(!empty($buyer_phone_field) && !empty($this->order_data['form_data'][$buyer_phone_field])) {
            $customer_data['phone'] = $this->order_data['form_data'][$buyer_phone_field]['value'];
        }

        $email_is_exist = false;
        if(!empty($customer_data['email'])){
            $check = $this->get_by_email($customer_data['email']);
            if(!empty($check)){
                $email_is_exist = true;
            }
        }

        if(false == $email_is_exist && !empty($customer_data['name'])){
            $add_customer = $this->submit($customer_data);
        }

    }

    public function autocomplete_options($r, $args) {

        console.log(print_r($args, true));
        return $r;

    }

}