<?php

namespace Fab\Controller;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Fab\Interfaces\JIT_Interface;
use Fab\Metabox\FABMetaboxSetting;

/**
 * WooCommerce Apply Coupon Type
 *
 * @package    Fab
 * @subpackage Fab/Controller
 */
class WC_Apply_Coupon_Type extends WC_Group implements JIT_Interface {

    /**
     * Post Metas.
     *
     * @var array
     */
    public $post_metas = array(
        'woocommerce_apply_coupon'              => array(
            'meta_key' => 'fab_setting_woocommerce_apply_coupon',
        ),
        'woocommerce_apply_coupon_persuasively' => array(
            'meta_key' => 'fab_setting_woocommerce_apply_coupon_persuasively',
        ),
    );

    /**
     * Constructor.
     */
    public function __construct() {
        parent::__construct();
        $this->type       = 'apply_coupon';
        $this->dependency = FAB_WOOCOMMERCE_PLUGIN_FILE;
    }

    /**
     * Get labels type.
     *
     * @return array
     */
    public function get_labels_type() {
        return array(
            'name' => __( 'Apply Coupon', 'floating-awesome-button' ),
        );
    }

    /**
     * AJAX handler to search for WooCommerce coupons based on a search term.
     *
     * This function listens for AJAX requests made to the `wp_ajax_fab_search_coupons` hook.
     * It sanitizes and processes the search term, queries WooCommerce coupons, and returns
     * the results as a JSON response. The results include the coupon ID and title.
     *
     * @return void Outputs a JSON response containing an array of coupons.
     */
    public function ajax_search_coupons() {
        // Get the search term from the request.
        $search_term = isset( $_GET['q'] ) ? sanitize_text_field( wp_unslash( $_GET['q'] ) ) : '';

        // Query WooCommerce coupons.
        $args = array(
            'post_type'      => 'shop_coupon',
            'posts_per_page' => 10, // Limit the number of results.
            's'              => $search_term, // Search term.
            'post_status'    => 'publish', // Only published coupons.
        );

        $query = new \WP_Query( $args );

        // Prepare the results.
        $coupons = array();

        if ( $query->have_posts() ) {
            while ( $query->have_posts() ) {
                $query->the_post();

                $coupon_title = get_the_title();
                $coupon_title = html_entity_decode( $coupon_title, ENT_QUOTES, 'UTF-8' );

                $coupons[] = array(
                    'id'        => get_the_ID(),
                    'text'      => $coupon_title,
                    'post_type' => 'shop_coupon',
                );
            }
        }

        wp_reset_postdata();

        // Return the coupons as a JSON response.
        wp_send_json( $coupons );
    }

    /**
     * Automatically applies a coupon from the URL parameter.
     *
     * This function checks if a coupon code is passed via the URL parameter `fab_coupon_code`.
     * If a valid coupon code is found and the coupon is not already applied to the cart,
     * it applies the coupon to the WooCommerce cart.
     *
     * @return void
     */
    public function apply_coupon_from_url() {
        if ( isset( $_GET['fab_coupon_code'] ) && ! empty( $_GET['fab_coupon_code'] ) ) {
            // Check if coupon is valid.
            $coupon_code = sanitize_text_field( wp_unslash( $_GET['fab_coupon_code'] ) );
            $coupon      = new \WC_Coupon( $coupon_code );
            if ( WC()->cart->has_discount( $coupon_code ) || ! $coupon || ! $coupon->is_valid() ) {
                wp_safe_redirect( remove_query_arg( 'fab_coupon_code' ) );
                exit;
            }

            // Search FAB item by coupon ID.
            $fab = \Fab\Helper\WooCommerce\Coupon::getInstance()->search_fab_by_coupon_id( $coupon->get_id() );
            if ( ! $fab ) {
                wp_safe_redirect( remove_query_arg( 'fab_coupon_code' ) );
                exit;
            }

            // If FAB is displayed, meaning location rule is valid then applied the coupon.
            if ( $fab->isToBeDisplayed() ) {
                WC()->cart->add_discount( $coupon_code );
            }

            // Remove the coupon code from the URL.
            wp_safe_redirect( remove_query_arg( 'fab_coupon_code' ) );
            exit;
        }
    }

    /**
     * Add convert coupon to FAB action to FAB post type row actions
     *
     * @param array   $actions Array of row action links.
     * @param WP_Post $post   The post object.
     * @return array
     */
    public function add_fab_convert_coupon_action( $actions, $post ) {
        if ( 'shop_coupon' === $post->post_type ) {
            $actions['fab_convert_coupon'] = sprintf(
                '<a href="%s">%s</a>',
                wp_nonce_url(
                    admin_url( 'admin.php?action=fab_convert_coupon&coupon_id=' . $post->ID ),
                    'fab_convert_coupon_' . $post->ID
                ),
                __( 'Turn into FAB', 'floating-awesome-button' )
            );
        }
        return $actions;
    }

    /**
     * Handle the conversion of coupon to FAB
     *
     * @return void
     */
    public function convert_coupon_to_fab() {
        // Check if post ID is provided.
        $coupon_id = isset( $_GET['coupon_id'] ) ? intval( $_GET['coupon_id'] ) : 0;

        // Verify nonce.
        if ( isset( $_GET['_wpnonce'] ) && ! wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'fab_convert_coupon_' . $coupon_id ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            wp_die( esc_html__( 'Security check failed', 'floating-awesome-button' ) );
        }

        // Add new fab.
        $result = \Fab\Helper\FAB_Template::getInstance()->add_new_fab(
            (object) array(
                'id'        => 'woocommerce-apply-coupon',
                'coupon_id' => $coupon_id,
            )
        );

        // Check if there's an error.
        if ( is_wp_error( $result ) ) {
            wp_die( esc_html( $result->get_error_message() ) );
        }

        // Redirect to FAB edit page.
        wp_safe_redirect( admin_url( 'post.php?post=' . $result . '&action=edit' ) );
        exit;
    }

    /**
     * Add WooCommerce coupon integration.
     *
     * @return void
     */
    public function add_wc_coupon_integration() {
        $screen = get_current_screen();

        // Early return if not on coupon edit page.
        if ( ! $screen || ( 'shop_coupon' !== $screen->post_type ) ) {
            return;
        }

        // Enqueue script.
        \FAB()->Helper->wp_enqueue_script_typescript( 'fab-integration-wc-coupon', 'assets/ts/integration/wc-coupon.ts', array(), FAB_VERSION, true );
        wp_localize_script(
            'fab-integration-wc-coupon',
            'FAB_COUPON',
            array(
                'coupon' => array(
                    'id'          => get_the_ID(),
                    'convert_url' => wp_nonce_url(
                        admin_url( 'admin.php?action=fab_convert_coupon&coupon_id=' . get_the_ID() ),
                        'fab_convert_coupon_' . get_the_ID()
                    ),
                    'explore_url' => admin_url( 'edit.php?post_type=fab&page=floating-awesome-button-templates&search=coupon' ),
                ),
                'label'  => array(
                    'turn_into_fab' => __( 'Turn into FAB', 'floating-awesome-button' ),
                    'add_new_fab'   => __( 'Add New FAB Coupon', 'floating-awesome-button' ),
                ),
            )
        );
    }

    /*
    |--------------------------------------------------------------------------
    | Fulfill implemented interface contracts
    |--------------------------------------------------------------------------
     */

    /**
     * JIT Method.
     *
     * @return void
     */
    public static function jit() {
        /**
         * |--------------------------------------------------------------------------
         * | WOOCOMMERCE HOOKS
         * | - Prevent error if woocommerce plugin is not active.
         * |--------------------------------------------------------------------------
         */
        if ( ! FAB_WOOCOMMERCE_PLUGIN_ACTIVE ) {
            return;
        }

        // Add fab setting types.
        add_filter( 'fab_setting_types', array( __CLASS__, 'jit_add_fab_setting_types' ), 10, 1 );

        // @backend - Ajax search coupons
        add_action( 'wp_ajax_fab_search_coupons', array( __CLASS__, 'jit_ajax_search_coupons' ) );

        // @backend - Apply coupon from URL
        add_action( 'template_redirect', array( __CLASS__, 'jit_apply_coupon_from_url' ) );

        /**
         * |--------------------------------------------------------------------------
         * | INTEGRATION
         * | - Early return if WooCommerce integration is not enabled.
         * |--------------------------------------------------------------------------
         */
        if ( \Fab\Plugin\Helper::getInstance()->check_plugin_integration( FAB_WOOCOMMERCE_PLUGIN_FILE ) !== 'enabled' ) {
            return;
        }

        // Add convert coupon to coupon row action.
        add_filter( 'post_row_actions', array( __CLASS__, 'jit_add_fab_convert_coupon_action' ), 10, 2 );
        add_action( 'admin_action_fab_convert_coupon', array( __CLASS__, 'jit_convert_coupon_to_fab' ) );

        // Add convert coupon page-title-action on index & edit coupon page.
        add_action( 'admin_enqueue_scripts', array( __CLASS__, 'jit_add_wc_coupon_integration' ) );
    }
}
