<?php

namespace WpBookingHotel\Wordpress\ECommerce\WooCommerce;
use WpBookingHotel\Factory;
use  WpBookingHotel\Wordpress\ECommerce\WooCommerce\Versions\WooCommerce_v1\HookPage\CheckOut;
use  WpBookingHotel\Wordpress\ECommerce\WooCommerce\Versions\WooCommerce_v1\HookPage\Cart;
use WpBookingHotel\Factory as FactoryAlias;
use WpBookingHotel\Mvc\Model\Model;
use WpBookingHotel\Utilities\Utility;
use WpBookingHotelAdmin\app\helpers\AdminHelper;
use WpBookingHotelFrontend\app\helpers\FrontendHelper;

/**
 * Class WooCommerce
 * @package WpBookingHotel\Wordpress\ECommerce\WooCommerce
 */
class WooCommerce
{
    /**
     * WooCommerce constructor.
     */
    public function __construct()
    {

    }

    /**
     *
     */
    public function init()
    {

        // Register new status
        add_action( 'init', array($this,'register_customize_order_status_woocommerce') );

        // Add to list of WC Order statuses
        add_filter( 'wc_order_statuses', array($this,'add_customize_to_order_statuses_woocommerce') , 10, 1);

        // Add notice addmin woocommerece
        add_action( 'admin_notices', array($this,'my_order_edit_notice' ) );

        // add column order-detail product

        add_action('woocommerce_admin_order_item_headers', array($this,'my_woocommerce_admin_order_item_headers'));
        add_action('woocommerce_admin_order_item_values', array($this,'my_woocommerce_admin_order_item_values'), 10, 3);
        // ADDING A CUSTOM COLUMN TITLE TO ADMIN PRODUCTS LIST
        add_filter( 'manage_edit-product_columns', array($this,'custom_product_column'),11);

        // ADDING THE DATA FOR EACH PRODUCTS BY COLUMN (EXAMPLE)
        add_action( 'manage_product_posts_custom_column' , array($this,'custom_product_list_column_content'), 10, 2 );
        add_filter( 'woocommerce_product_data_tabs', array($this,'add_my_custom_product_data_tab' ), 99 , 1 );
        add_action( 'woocommerce_product_data_panels', array($this,'add_my_custom_product_data_fields') );
        add_action('save_post_product', array($this,'mp_sync_on_product_save'), 10, 3);

        add_action( 'woocommerce_order_status_changed', array($this,'grab_order_old_status'), 10, 4 );

        // Front-end
        add_filter('woocommerce_add_to_cart_redirect', array($this,'change_woocommerce_add_to_cart_redirect_url'));
        add_action('woocommerce_checkout_order_processed',array($this, 'sync_information_order_to_plugin'),10,3);
        add_action( 'woocommerce_thankyou', array($this,'bacs_order_payment_processing_order_status'), 10, 1 );
        add_action( 'woocommerce_payment_complete', array($this,'my_change_status_function' ));
        add_action( 'woocommerce_scan_qr_code', array($this,'change_order_status_when_scan_qr_code' ));
        add_action('woocommerce_cancel_unpaid_submitted', array($this,'wc_cancel_unpaid_submitted'),10);

    }


    public function register_customize_order_status_woocommerce(){
        register_post_status( 'wc-ready-to-use', array(
            'label'                     => 'Ready to use',
            'public'                    => true,
            'exclude_from_search'       => false,
            'show_in_admin_all_list'    => true,
            'show_in_admin_status_list' => true,
            'label_count'               => _n_noop( 'Ready to use (%s)', 'Ready to use (%s)' )
        ) );
        register_post_status( 'wc-used', array(
            'label'                     => 'Used',
            'public'                    => true,
            'exclude_from_search'       => false,
            'show_in_admin_all_list'    => true,
            'show_in_admin_status_list' => true,
            'label_count'               => _n_noop( 'Used (%s)', 'Used (%s)' )
        ) );
    }

    public function add_customize_to_order_statuses_woocommerce($order_statuses) {
        $new_order_statuses = array();

        // add new order status after processing
        foreach ( $order_statuses as $key => $status ) {

            $new_order_statuses[ $key ] = $status;

            if ( 'wc-processing' === $key ) {
                $new_order_statuses['wc-ready-to-use'] = 'Ready to use';
            }
            if ( 'wc-completed' === $key ) {
                $new_order_statuses['wc-used'] = 'Used';
            }
        }

        return $new_order_statuses;
    }

    public  function my_order_edit_notice() {
        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ;}
        if(get_post_type() != 'shop_order') { return; }
        if(!AdminHelper::checkSyncOrderstatus()) {
            ob_start();
            ?>
                <div class="notice is-dismissible notice-error"> <!-- can use 'notice-error' or 'notice-success' as well -->
                    <p>
                        <?php _e( 'You have not synchronized the order status of Appointment Plugin with woocommerce! !', 'wpbookingpro' ); ?>
                        <a href="<?php echo (Factory::getRootUrl().'/wp-admin/admin.php?page=wb_orderstatus')?>"><?php esc_html_e('Sync this here','wpbookingpro');?></a>
                    </p>
                </div>
            <?php
            $content = ob_get_clean();
            echo ($content);
        }

    }

    public static function change_order_status_when_scan_qr_code($order_id) {
        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return; }

        $db = Factory::getDBO();
        $query = $db->getQuery(true);
        $appConfig = Factory::getAppConfig();
        $order_status_config_when_scan = $appConfig->get('order_status_config_when_scan', '');
        $query->update(Utility::getTableName('order').' AS wborder')
            ->set('wborder.open_source_order_status_id='.$query->quote($order_status_config_when_scan))
            ->where('wborder.open_source_order_id='.(int)$order_id)
        ;
        $db->setQuery($query)->execute();

    }

    public static function wc_cancel_unpaid_submitted($order_id) {
        $order = wc_get_order( $order_id );
        $order -> update_status( 'cancelled', __( 'Unpaid submission expired after hours set in payment plugin options..', 'woocommerce') );
    }

    public static function my_change_status_function( $order_id ) {
        $wordpress=Factory::getWordpress(0);
        if(!$wordpress->checkInstalled()) { return ;}

        $order = wc_get_order( $order_id );
        $order->update_status( 'completed' );
        $db = FactoryAlias::getDBO();
        $query= $db->getQuery(true);
        $query->update(Utility::getTableName('order').' AS wborder')
            ->set('wborder.open_source_order_status_id='.$query->quote('completed'))
            ->where('wborder.open_source_order_id='.(int)$order_id)
        ;
        $db->setQuery($query)->execute();

    }

    public static function grab_order_old_status( $order_id, $status_from, $status_to, $order ) {
        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ; }

        $db = Factory::getDBO();
        $query = $db->getQuery(true);
        $query->update(Utility::getTableName('order').' AS wborder')
            ->set('wborder.open_source_order_status_id='.$query->quote($status_to))
            ->where('wborder.open_source_order_id='.(int)$order_id)
        ;
        $db->setQuery($query)->execute();
    }

    public static function bacs_order_payment_processing_order_status( $order_id ) {
        $wordpress=Factory::getWordpress(0);

        if ( ! $order_id ) {
            return;
        }
        if(!$wordpress->checkInstalled()) { return ; }

        // Get an instance of the WC_Order object
        $order = new \WC_Order( $order_id );
        if ( ( get_post_meta($order->get_id(), '_payment_method', true) == 'bacs' ) && ('on-hold' == $order->get_status() || 'pending' == $order->get_status()) ) {
            $order->update_status('processing');
            $db = Factory::getDBO();
            $query = $db->getQuery(true);
            $query->update(Utility::getTableName('order').' AS wborder')
                ->set('wborder.open_source_order_status_id='.$query->quote($order->get_status()))
                ->where('wborder.open_source_order_id='.(int)$order_id)
            ;
            $db->setQuery($query)->execute();

        } else {
            return;
        }

    }
    public static function sync_information_order_to_plugin( $order_id, $posted_data, $order){
        global $woocommerce;
        $items = $woocommerce->cart->get_cart();
        $wordpress=Factory::getWordpress(0);
        if(!$wordpress->checkInstalled()) { return ;}

        foreach ($items as $item) {
            $db = Factory::getDBO();
            $query = $db->getQuery(true);
            $query->select('service.id')
                ->from(Utility::getTableName('service').' AS service')
                ->where('service.open_source_link_id='.(int)$item['product_id'])
                ;
            $service_id = $db->setQuery($query)->loadResult();
            if($service_id) {
                $data_cart = $item['data']->get_data();
                $modelBooking = Model::getInstance('booking');
                $data=array(
                    "employee_id"=>$item['employee_id'],
                    "number_person"=>$item['quantity'],
                    "first_name"=>$posted_data['billing_first_name'],
                    "last_name"=>$posted_data['billing_last_name'],
                    "email"=>$posted_data['billing_email'],
                    "phone"=>$posted_data['billing_phone'],
                    "address_1"=>$posted_data['billing_address_1'],
                    "address_2"=>$posted_data['billing_address_2'],
                    "city"=>$posted_data['billing_city'],
                    "calendar"=>$item['calendar'],
                    "create_date"=>$data_cart['date_created']->date,
                    "open_source_order_id"=>$order_id,
                    "open_source_payment_id"=>$posted_data['payment_method']

                );
                $order_sync = $modelBooking->book_service($data);
                $modelOrder = Model::getInstance('order');
                $order_appoitment = $modelOrder->getItem($order_sync->id);
                $order->update_meta_data( '_expert',  reset($order_appoitment->list_rate)->employee_fullname );
                $order->save();
            }
        }
    }
    public static function change_woocommerce_add_to_cart_redirect_url($url){
        $url = wc_get_cart_url();
        return $url;
    }
    public static function mp_sync_on_product_save( $post_id, $post, $update ) {
        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ; }

        $product = wc_get_product( $post_id );
        $db=Factory::getDBO();
        $query=$db->getQuery(true);
        $query->update(Utility::getTableName('service').' AS service')
            ->set('service.name='.$query->quote($product->get_name()))
            ->set('service.price='.(float)$product->get_price())
            ->where('service.open_source_link_id='.(int)$post_id)
            ;
        $db->setQuery($query)->execute();
    }

    public static function my_woocommerce_admin_order_item_headers() {
        global $woocommerce, $post;

        $order = new \WC_Order($post->ID);

        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ; }

        //to escape # from order id

        $order_id = trim(str_replace('#', '', $order->get_order_number()));
        $db = FactoryAlias::getDBO();
        $query = $db->getQuery(true);
        $query->select('wborder.id')
            ->from(Utility::getTableName('order'). ' AS wborder')
            ->where('wborder.open_source_order_id='.(int)$order_id)
        ;
        $order_id_wp = $db->setQuery($query)->loadResult();
        if($order_id_wp) {
            $column_name = array(
                "employee"=>"Employee",
                "duration"=>"Duration",
                "time"=>"Time"
            );
            foreach ($column_name as $item) {
                echo '<th>' . $item . '</th>';
            }
        }

    }
    public static function add_my_custom_product_data_fields() {
        global $woocommerce, $post;
        ?>
        <div id="my_custom_product_data" class="panel woocommerce_options_panel">

        </div>
        <?php
    }
    public static function add_my_custom_product_data_tab( $product_data_tabs ) {
        $product_data_tabs['my-custom-tab'] = array(
            'label' => __( 'My Custom Tab', 'my_text_domain' ),
            'target' => 'my_custom_product_data',
        );
        return $product_data_tabs;
    }

    public static function custom_product_list_column_content( $column, $product_id )
    {
        global $post;
        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ; }

        $db= FactoryAlias::getDBO();
        $query = $db->getQuery(true);
        $query->select('service.id')
            ->from(Utility::getTableName('service').' AS service')
            ->where('service.open_source_link_id='.(int)$product_id)
            ;
        $service_id = $db->setQuery($query)->loadResult();

        switch ( $column )
        {
            case 'delivery' :
                printf('<a href="'.FactoryAlias::getRootUrl().'/sellercenter/wb_service/?layout=form&id=%s'.'">'.__('Edit','wpbookingpro').'</a>',$service_id); // display the data
                break;
        }
    }
    /**
     * @param $_product
     * @param $item
     * @param null $item_id
     */
    public static function my_woocommerce_admin_order_item_values($_product, $item, $item_id = null) {
        global $woocommerce, $post;

        $order = new \WC_Order($post->ID);

        $wordpress=Factory::getWordpress(1);
        if(!$wordpress->checkInstalled()) { return ; }


        //to escape # from order id

        $order_id = trim(str_replace('#', '', $order->get_order_number()));
        $db = FactoryAlias::getDBO();
        $query = $db->getQuery(true);
        $query->select('wborder.id')
            ->from(Utility::getTableName('order'). ' AS wborder')
            ->where('wborder.open_source_order_id='.(int)$order_id)
        ;
        $order_id_wp = $db->setQuery($query)->loadResult();
        if(isset($order_id_wp)) {
            $modelOrder = Model::getInstance('order');
            $wp_order = $modelOrder->getItem($order_id_wp);
            $list_rate = $wp_order->list_rate;

            $values = array(
                "employee"=>$list_rate[0]->employee_fullname,
                "duration"=>$list_rate[0]->duration,
                "time"=>$list_rate[0]->list_time_detail
            );
            if($item['type']=="line_item")
                foreach ($values as $key=>$value) {
                    switch ($key) {
                        case $key:
                            echo '<td>'.$value.'</td>';
                            break;
                    }
                }
        }

    }

    /**
     * @param $columns
     * @return mixed
     */
    public static function custom_product_column($columns)
    {
        //add columns
        $columns['delivery'] = __( 'Delivery time','woocommerce'); // title
        return $columns;
    }

    /**
     *
     */
    public function run()
    {
        $cart=Cart::getInstance();
        //add_action( 'woocommerce_checkout_order_review', [$checkout,'woocommerce_order_review'], 10 );
        add_action( 'woocommerce_before_cart_contents', array($cart,'woocommerce_before_cart_contents'),  1, 1  );
        add_action( 'woocommerce_cart_contents', array($cart,'woocommerce_cart_contents'),  1, 1  );
        add_action( 'woocommerce_after_cart_contents', array($cart,'woocommerce_after_cart_contents'),  1, 1  );


        $checkout=CheckOut::getInstance();
        //add_action( 'woocommerce_checkout_order_review', array($this,$checkout,'woocommerce_order_review'], 10 );
        add_action( 'woocommerce_checkout_order_processed', array($checkout,'woocommerce_checkout_order_processed'),  10, 3   );




    }

    /**
     * @param $product_id
     * @return |null
     */
    public function get_product($product_id){
        return function_exists('wc_get_product')? wc_get_product($product_id):null;
    }

    /**
     * @param $args
     * @return array
     */
    public function get_products($args){
        return function_exists('wc_get_products')? wc_get_products($args):array();
    }
}