<?php
/**
 * Wholesale Suite Integration.
 *
 * @since   1.2.0
 * @package SAAI
 */

namespace SAAI\Integrations;

use SAAI\Abstracts\Abstract_Class;
use SAAI\Helpers\Helper;
use SAAI\REST\Chat\Chat_Post_Types;

defined( 'ABSPATH' ) || exit;

/**
 * Wholesale Suite Integration class.
 *
 * Integrates with WooCommerce Wholesale Prices plugin to include
 * wholesale pricing data in AI memory uploads for products.
 *
 * @since 1.2.0
 */
class Wholesale_Suite extends Abstract_Class {

    /**
     * Run the integration.
     *
     * @since 1.2.0
     * @return void
     */
    public function run() {
        if ( ! self::is_wwp_active() ) {
            return;
        }

        add_filter( 'saai_prepare_post_data_metadata', array( $this, 'add_wholesale_prices_to_metadata' ), 10, 3 );
        add_filter( 'saai_product_pricing_data', array( $this, 'add_wholesale_prices_to_pricing_data' ), 10, 2 );
    }

    /**
     * Check if WooCommerce Wholesale Prices plugin is active.
     *
     * @since 1.2.0
     * @return bool True if Wholesale Prices is active, false otherwise.
     */
    public static function is_wwp_active() {
        if ( class_exists( 'WooCommerceWholeSalePrices' ) || class_exists( 'WWP_Wholesale_Prices' ) ) {
            return true;
        }

        // Fallback to plugin check.
        if ( ! function_exists( 'is_plugin_active' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        if ( function_exists( 'is_plugin_active' ) ) {
            return is_plugin_active( 'woocommerce-wholesale-prices/woocommerce-wholesale-prices.bootstrap.php' );
        }

        return false;
    }

    /**
     * Add wholesale prices to product metadata for AI memory upload.
     *
     * Hooks into the saai_prepare_post_data_metadata filter to inject
     * wholesale price meta values into the metadata array.
     *
     * Since returning non-empty metadata from this filter skips the default
     * meta_keys processing, this method also includes user-configured meta_keys.
     *
     * @since 1.2.0
     *
     * @param array  $metadata  The metadata array.
     * @param int    $post_id   The post ID.
     * @param string $post_type The post type.
     * @return array Modified metadata with wholesale prices.
     */
    public function add_wholesale_prices_to_metadata( $metadata, $post_id, $post_type ) {
        if ( 'product' !== $post_type ) {
            return $metadata;
        }

        // Check if wholesale data inclusion is enabled in settings.
        $settings               = get_option( Chat_Post_Types::OPTION_KEY, array() );
        $include_wholesale_data = isset( $settings['product']['include_wholesale_data'] )
            ? $settings['product']['include_wholesale_data']
            : false;

        if ( ! $include_wholesale_data ) {
            return $metadata;
        }

        // Include user-configured meta_keys first since returning non-empty
        // metadata from this filter skips the default meta_keys processing.
        $meta_keys = isset( $settings['product']['meta_keys'] ) ? $settings['product']['meta_keys'] : array();
        if ( ! empty( $meta_keys ) ) {
            foreach ( $meta_keys as $meta_key ) {
                if ( ! isset( $metadata[ $meta_key ] ) ) {
                    $metadata[ $meta_key ] = Helper::get_post_meta( $post_id, $meta_key, true );
                }
            }
        }

        $wholesale_roles = $this->get_wholesale_roles();

        if ( empty( $wholesale_roles ) ) {
            return $metadata;
        }

        $product = wc_get_product( $post_id );

        if ( ! $product ) {
            return $metadata;
        }

        // Check if any wholesale role has a price set for this product.
        // Only store a boolean availability flag — actual prices are served
        // via the chat tool endpoint with role-based filtering.
        $has_wholesale_price = false;

        foreach ( $wholesale_roles as $role_key => $role_data ) {
            $meta_key = $role_key . '_wholesale_price';
            $price    = Helper::get_post_meta( $post_id, $meta_key, true );

            if ( '' !== $price && false !== $price ) {
                $has_wholesale_price = true;
                break;
            }
        }

        // For variable products, check variations if parent has no wholesale price.
        // A parent-level check is sufficient for the "available" flag since we only
        // need to know if wholesale pricing exists anywhere on this product.
        if ( ! $has_wholesale_price && $product->is_type( 'variable' ) ) {
            foreach ( $product->get_children() as $variation_id ) {
                foreach ( $wholesale_roles as $role_key => $role_data ) {
                    $meta_key        = $role_key . '_wholesale_price';
                    $variation_price = Helper::get_post_meta( $variation_id, $meta_key, true );

                    if ( '' !== $variation_price && false !== $variation_price ) {
                        $has_wholesale_price = true;
                        break 2;
                    }
                }
            }
        }

        $metadata['wholesale_price_available'] = $has_wholesale_price ? 'Yes' : 'No';

        return $metadata;
    }

    /**
     * Add wholesale prices to product pricing data for the chat tool endpoint.
     *
     * @since 1.2.0
     *
     * @param array       $price_data The product pricing data.
     * @param \WC_Product $product    The product object.
     * @return array Modified pricing data with wholesale prices.
     */
    public function add_wholesale_prices_to_pricing_data( $price_data, $product ) {
        // Check if wholesale data inclusion is enabled in settings.
        $settings               = get_option( Chat_Post_Types::OPTION_KEY, array() );
        $include_wholesale_data = isset( $settings['product']['include_wholesale_data'] )
            ? $settings['product']['include_wholesale_data']
            : false;

        if ( ! $include_wholesale_data ) {
            return $price_data;
        }

        $wholesale_roles = $this->get_wholesale_roles();

        if ( empty( $wholesale_roles ) ) {
            return $price_data;
        }

        // Filter wholesale roles by the current user's role.
        // Admins and shop managers see all wholesale prices.
        if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'manage_woocommerce' ) ) {
            $user_wholesale_role = $this->get_current_user_wholesale_role();

            // Non-wholesale users see no wholesale prices.
            if ( empty( $user_wholesale_role ) || ! isset( $wholesale_roles[ $user_wholesale_role ] ) ) {
                return $price_data;
            }

            // Narrow to only the user's wholesale role.
            $wholesale_roles = array( $user_wholesale_role => $wholesale_roles[ $user_wholesale_role ] );
        }

        $wholesale_prices = array();

        foreach ( $wholesale_roles as $role_key => $role_data ) {
            $role_name = isset( $role_data['roleName'] ) ? $role_data['roleName'] : $role_key;
            $price     = $this->get_product_wholesale_price( $product, $role_key );

            if ( '' !== $price && false !== $price ) {
                $wholesale_prices[] = array(
                    'role'     => $role_name,
                    'role_key' => $role_key,
                    'price'    => $price,
                );
            }
        }

        if ( ! empty( $wholesale_prices ) ) {
            $price_data['wholesale_prices'] = $wholesale_prices;
        }

        return $price_data;
    }

    /**
     * Get all registered wholesale roles.
     *
     * Uses WWP_Wholesale_Roles if available, otherwise falls back
     * to scanning wp_roles for roles containing "wholesale".
     *
     * @since 1.2.0
     * @return array Associative array of wholesale roles.
     */
    protected function get_wholesale_roles() {
        // Try WWP_Wholesale_Roles class first.
        if ( class_exists( 'WWP_Wholesale_Roles' ) ) {
            $wwp_roles = \WWP_Wholesale_Roles::getInstance();

            if ( method_exists( $wwp_roles, 'getAllRegisteredWholesaleRoles' ) ) {
                return $wwp_roles->getAllRegisteredWholesaleRoles();
            }
        }

        // Fallback: scan wp_roles for roles containing "wholesale".
        global $wp_roles;

        if ( ! isset( $wp_roles ) ) {
            $wp_roles = wp_roles(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
        }

        $wholesale_roles = array();

        foreach ( $wp_roles->roles as $role_key => $role_data ) {
            if ( false !== strpos( strtolower( $role_key ), 'wholesale' ) ) {
                $wholesale_roles[ $role_key ] = array(
                    'roleName' => $role_data['name'],
                );
            }
        }

        return $wholesale_roles;
    }

    /**
     * Get the current user's wholesale role key.
     *
     * @since 1.2.0
     * @return string The wholesale role key, or empty string if the user has no wholesale role.
     */
    protected function get_current_user_wholesale_role() {
        $user = wp_get_current_user();

        if ( ! $user->exists() ) {
            return '';
        }

        // Use WWP_Wholesale_Roles if available.
        if ( class_exists( 'WWP_Wholesale_Roles' ) ) {
            $wwp_roles = \WWP_Wholesale_Roles::getInstance();

            if ( ! $wwp_roles instanceof \WWP_Wholesale_Roles ) {
                return '';
            }

            $user_wholesale = $wwp_roles->getUserWholesaleRole( $user );

            if ( ! empty( $user_wholesale ) ) {
                return $user_wholesale[0];
            }

            return '';
        }

        // Fallback when WWP class is absent: scan user roles for any containing "wholesale".
        // The returned slug must exactly match a key in get_wholesale_roles() for the
        // isset() check in add_wholesale_prices_to_pricing_data() to pass.
        foreach ( $user->roles as $role ) {
            if ( false !== strpos( strtolower( $role ), 'wholesale' ) ) {
                return $role;
            }
        }

        return '';
    }

    /**
     * Get the wholesale price for a product and role.
     *
     * For simple products, reads the meta key directly.
     * For variable products, also aggregates variation wholesale prices.
     *
     * @since 1.2.0
     *
     * @param \WC_Product $product  The product object.
     * @param string      $role_key The wholesale role key.
     * @return string|array|false The wholesale price, array of variation prices, or false if not set.
     */
    protected function get_product_wholesale_price( $product, $role_key ) {
        $meta_key = $role_key . '_wholesale_price';
        $price    = Helper::get_post_meta( $product->get_id(), $meta_key, true );

        // For variable products, also check variations.
        if ( $product->is_type( 'variable' ) ) {
            $variation_prices = array();
            $variations       = $product->get_children();

            foreach ( $variations as $variation_id ) {
                $variation_price = Helper::get_post_meta( $variation_id, $meta_key, true );

                if ( '' !== $variation_price && false !== $variation_price ) {
                    $variation = wc_get_product( $variation_id );

                    if ( $variation ) {
                        $variation_prices[] = array(
                            'variation_id' => $variation_id,
                            'name'         => $variation->get_name(),
                            'price'        => $variation_price,
                        );
                    }
                }
            }

            if ( ! empty( $variation_prices ) ) {
                return $variation_prices;
            }
        }

        if ( '' === $price || false === $price ) {
            return false;
        }

        return $price;
    }
}
