<?php

if ( !defined( 'ABSPATH' ) ) {

    exit;
}

if ( !class_exists( 'Pricely_Pipeline_Coupons' ) ) {

    require_once 'pipeline-coupons-internal.php';
    require_once 'pipeline-coupons-auto-add.php';
    require_once 'pipeline-coupons-discounts.php';
    require_once 'pipeline-coupons-data.php';

    class Pricely_Pipeline_Coupons {

        private static $instance;
        private $pipeline_coupons_auto_add;
        private $pipeline_coupons_data;
        private $coupons;
        private $coupon_type;
        private $coupon_type_label;

        public static function get_instance(): self {

            if ( !self::$instance ) {

                self::$instance = new self();
            }

            return self::$instance;
        }

        public function __construct() {

            $this->pipeline_coupons_auto_add = Pricely_Pipeline_Coupons_Auto_Add::get_instance();
            $this->pipeline_coupons_data = Pricely_Pipeline_Coupons_Data::get_instance();

            $this->coupons = false;

            $this->coupon_type = 'pricely_coupon';
            $this->coupon_type_label = esc_html__( 'Dynamic Pricing &amp; Discounts+', 'pricely-dynamic-pricing-cart-discounts' );

            add_filter( 'woocommerce_coupon_discount_types', array( $this, 'get_coupon_types' ), 99999 );
            add_filter( 'woocommerce_product_coupon_types', array( $this, 'get_product_coupon_types' ), 99999 );
            add_filter( 'woocommerce_coupon_get_discount_type', array( $this, 'get_discount_type' ), 99999, 2 );
            add_filter( 'woocommerce_coupon_sort', array( $this, 'get_coupon_sort' ), 99999, 2 );
            add_filter( 'woocommerce_coupons_enabled', array( $this, 'get_coupons_enabled' ), 99999 );
            add_filter( 'woocommerce_cart_totals_coupon_label', array( $this, 'get_coupon_label' ), 99999, 2 );
            add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'get_coupon_total_html' ), 99999, 3 );
        }

        public function process_coupons_auto_add( $cart ) {

            $this->pipeline_coupons_auto_add->process_coupons_auto_add( $cart );
        }

        public function get_totals( $coupon_code ) {

            return $this->pipeline_coupons_data->get_coupon_totals( $coupon_code );
        }

        public function get_coupon_types( $coupon_types ) {

            $coupon_types[ $this->coupon_type ] = $this->coupon_type_label;

            return $coupon_types;
        }

        public function get_discount_type( $discount_type, $coupon ) {

            if ( !$coupon ) {

                return $discount_type;
            }

            if ( 'fixed_cart' !== $discount_type ) {

                return $discount_type;
            }

            $coupons_data = $this->get_coupons();

            if ( !is_array( $coupons_data ) ) {

                return $discount_type;
            }

            $coupon_codes = array_keys( $coupons_data );

            $coupon_code = $coupon->get_code();

            if ( !in_array( $coupon_code, $coupon_codes ) ) {

                return $discount_type;
            }

            return $this->coupon_type;
        }

        public function get_product_coupon_types( $coupon_types ) {

            $coupon_types[] = $this->coupon_type;

            return $coupon_types;
        }

        public function get_coupon_sort( $sort, $coupon ) {

            $discount_type = '';

            if ( method_exists( $coupon, 'get_discount_type' ) ) {

                $discount_type = $coupon->get_discount_type();
            }

            if ( 'pricely_coupon' == $discount_type ) {

                return 0;
            }

            $sort++;

            return $sort;
        }

        public function get_coupons_enabled( $coupons_enabled ) {

            if ( $this->is_coupons_active() ) {

                return true;
            }

            return $coupons_enabled;
        }

        public function get_coupon_label( $coupon_label, $coupon_obj ) {

            if ( !method_exists( $coupon_obj, 'get_code' ) ) {

                return $coupon_label;
            }

            $coupon_code = $coupon_obj->get_code();

            $coupon = $this->get_coupon_by_code( $coupon_code );

            if ( !$coupon ) {

                return $coupon_label;
            }

            $label = apply_filters( 'pricely_get-pipeline-coupon-label', $coupon[ 'label' ], $coupon, $coupon_code );

            if ( empty( $label ) ) {

                return $coupon_label;
            }

            $tooltip = apply_filters( 'pricely_get-pipeline-coupon-tooltip', $coupon[ 'tooltip' ], $coupon, $coupon_code );

            if ( empty( $tooltip ) ) {

                return $label;
            }

            return '<span title="' . wc_sanitize_tooltip( $tooltip ) . '">' . esc_html( $label ) . '</span>';
        }

        public function get_coupon_total_html( $coupon_html, $coupon_obj, $discount_amount_html ) {

            if ( !method_exists( $coupon_obj, 'get_code' ) ) {

                return $coupon_html;
            }

            $coupon_code = $coupon_obj->get_code();

            $coupon = $this->get_coupon_by_code( $coupon_code );

            if ( !$coupon ) {

                return $coupon_html;
            }

            return $discount_amount_html;
        }

        public function get_coupon_by_code( $coupon_code ) {

            $coupons = $this->get_coupons();

            if ( !isset( $coupons[ $coupon_code ] ) ) {

                return false;
            }

            return $coupons[ $coupon_code ];
        }

        public function get_coupons() {

            if ( false !== $this->coupons ) {

                return $this->coupons;
            }

            $this->coupons = $this->get_cart_discount_coupons( array() );

            return $this->coupons;
        }

        private function is_coupons_active() {

            return (count( $this->get_coupons() ) > 0);
        }

        private function get_cart_discount_coupons( $coupons ) {

            $cart_discounts = Pricely_Pipeline_Cart_Discounts::get_instance()->get_data();

            if ( !$cart_discounts ) {

                return $coupons;
            }

            if ( !isset( $cart_discounts[ 'coupons' ] ) ) {

                return $coupons;
            }

            foreach ( $cart_discounts[ 'coupons' ] as $coupon_data ) {

                $coupon_code = $coupon_data[ 'coupon_code' ];

                if ( !isset( $coupons[ $coupon_code ][ 'coupon_id' ] ) ) {

                    $coupons[ $coupon_code ][ 'coupon_id' ] = $coupon_data[ 'id' ];
                }

                $coupons[ $coupon_code ][ 'label' ] = $coupon_data[ 'label' ];
                $coupons[ $coupon_code ][ 'tooltip' ] = $coupon_data[ 'tooltip' ];
                $coupons[ $coupon_code ][ 'individual_use' ] = $coupon_data[ 'individual_use' ];
                $coupons[ $coupon_code ][ 'auto_add' ] = $coupon_data[ 'auto_add' ];
                $coupons[ $coupon_code ][ 'allow_removal' ] = $coupon_data[ 'allow_removal' ];
                $coupons[ $coupon_code ][ 'discount_ids' ] = $coupon_data[ 'discount_ids' ];
            }

            return $coupons;
        }

    }

    Pricely_Pipeline_Coupons::get_instance();
}

