<?php

/**
 * Product swatches overrides (admin).
 *
 * @package B3WVS\VariationSwatches\Admin
 */
namespace B3WVS\VariationSwatches\Admin;

use B3WVS\VariationSwatches\Assets;
use B3WVS\VariationSwatches\Admin\ProductSwatches\GlobalTermUpdater;
use B3WVS\VariationSwatches\Admin\ProductSwatches\OverrideSanitizer;
use B3WVS\VariationSwatches\Admin\ProductSwatches\PanelRenderer;
defined( 'ABSPATH' ) || exit;
/**
 * Per-product swatch overrides coordinator.
 */
class ProductSwatches {
    /**
     * Instance of this class.
     *
     * @var ProductSwatches
     */
    private static $instance = null;

    /**
     * Meta key for product overrides.
     */
    const META_KEY = '_b3_wvs_overrides';

    /**
     * Panel renderer.
     *
     * @var PanelRenderer
     */
    private $panel_renderer;

    /**
     * Override sanitizer.
     *
     * @var OverrideSanitizer
     */
    private $sanitizer;

    /**
     * Global term updater.
     *
     * @var GlobalTermUpdater
     */
    private $global_updater;

    /**
     * Get instance of this class.
     *
     * @return ProductSwatches
     */
    public static function get_instance() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor.
     */
    private function __construct() {
        $this->panel_renderer = new PanelRenderer(self::META_KEY);
        $this->sanitizer = new OverrideSanitizer(self::META_KEY);
        $this->global_updater = new GlobalTermUpdater();
        add_filter( 'woocommerce_product_data_tabs', array($this, 'add_tab') );
        add_action( 'woocommerce_product_data_panels', array($this, 'render_panel') );
        add_action( 'woocommerce_admin_process_product_object', array($this, 'save') );
        add_action(
            'woocommerce_process_product_meta',
            array($this, 'save_by_post_id'),
            1000,
            1
        );
        add_action(
            'woocommerce_process_product_meta_variable',
            array($this, 'save_by_post_id'),
            1000,
            1
        );
        add_action(
            'save_post_product',
            array($this, 'maybe_flush_usage_stats_cache'),
            20,
            1
        );
        add_action(
            'trashed_post',
            array($this, 'maybe_flush_usage_stats_cache'),
            10,
            1
        );
        add_action(
            'untrashed_post',
            array($this, 'maybe_flush_usage_stats_cache'),
            10,
            1
        );
        add_action(
            'before_delete_post',
            array($this, 'maybe_flush_usage_stats_cache'),
            10,
            1
        );
        add_action( 'admin_enqueue_scripts', array($this, 'enqueue_assets') );
        add_action( 'wp_ajax_b3wvs_refresh_swatches_panel', array($this, 'ajax_refresh_swatches_panel') );
    }

    /**
     * Add product data tab.
     *
     * @param array $tabs Existing tabs.
     * @return array
     */
    public function add_tab( $tabs ) {
        $tabs['b3wvs_swatches'] = array(
            'label'    => __( 'Swatches', 'b3-swatches' ),
            'target'   => 'b3wvs_swatches_panel',
            'class'    => array('show_if_variable'),
            'priority' => 75,
        );
        return $tabs;
    }

    /**
     * Enqueue admin assets for the swatches panel.
     *
     * @param string $hook Current admin page hook.
     * @return void
     */
    public function enqueue_assets( $hook ) {
        if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
            return;
        }
        $screen = ( function_exists( 'get_current_screen' ) ? get_current_screen() : null );
        if ( !$screen || 'product' !== $screen->post_type ) {
            return;
        }
        wp_enqueue_style( 'wp-color-picker' );
        wp_enqueue_media();
        Assets::get_instance()->get_enqueuer()->enqueue_asset( 'admin-product-swatches', 'src/legacy/admin-product-swatches.js', array('jquery', 'wp-color-picker', 'jquery-ui-sortable') );
    }

    /**
     * Render the product data panel.
     *
     * @return void
     */
    public function render_panel() {
        $this->panel_renderer->render();
    }

    /**
     * Save product swatch overrides.
     *
     * @param \WC_Product $product Product object.
     * @return void
     */
    public function save( $product ) {
        if ( !$product || !method_exists( $product, 'get_id' ) ) {
            return;
        }
        $post_id = $product->get_id();
        $this->sanitizer->save( $post_id );
        $this->global_updater->save( $post_id );
        \b3wvs_flush_usage_stats_cache();
    }

    /**
     * Save overrides via post ID.
     *
     * @param int $post_id Product ID.
     * @return void
     */
    public function save_by_post_id( $post_id ) {
        $this->sanitizer->save( $post_id );
        $this->global_updater->save( $post_id );
        \b3wvs_flush_usage_stats_cache();
    }

    /**
     * Clear usage stats cache when any product lifecycle event can affect active swatch usage.
     *
     * @param int $post_id Product/post ID.
     * @return void
     */
    public function maybe_flush_usage_stats_cache( $post_id ) {
        $post_id = absint( $post_id );
        if ( !$post_id || 'product' !== get_post_type( $post_id ) || wp_is_post_revision( $post_id ) ) {
            return;
        }
        \b3wvs_flush_usage_stats_cache();
    }

    /**
     * AJAX: Refresh the swatches panel HTML after attributes are updated.
     *
     * @return void
     */
    public function ajax_refresh_swatches_panel() {
        check_ajax_referer( 'b3wvs_refresh_panel', 'nonce' );
        $post_id = ( isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0 );
        if ( !$post_id ) {
            wp_send_json_error( array(
                'message' => __( 'Invalid product ID.', 'b3-swatches' ),
            ), 400 );
        }
        if ( !current_user_can( 'edit_post', $post_id ) ) {
            wp_send_json_error( array(
                'message' => __( 'You do not have permission to edit this product.', 'b3-swatches' ),
            ), 403 );
        }
        $product = wc_get_product( $post_id );
        if ( !$product || !$product->is_type( 'variable' ) ) {
            wp_send_json_error( array(
                'message' => __( 'Product not found or is not a variable product.', 'b3-swatches' ),
            ), 404 );
        }
        wc_delete_product_transients( $post_id );
        clean_post_cache( $post_id );
        if ( function_exists( 'wp_cache_delete' ) ) {
            wp_cache_delete( 'product-' . $post_id, 'products' );
        }
        $product = wc_get_product( $post_id );
        ob_start();
        $this->panel_renderer->render_for_product( $product );
        $panel_html = ob_get_clean();
        wp_send_json_success( array(
            'html' => $panel_html,
        ) );
    }

}
