<?php

/**
 * Global term updater - Handles saving global attribute swatch data from product edit screen.
 *
 * @package B3WVS\VariationSwatches\Admin\ProductSwatches
 */
namespace B3WVS\VariationSwatches\Admin\ProductSwatches;

use B3WVS\VariationSwatches\Admin\TermMeta\Sanitizer as TermMetaSanitizer;
defined( 'ABSPATH' ) || exit;
/**
 * GlobalTermUpdater Class
 *
 * Persists global attribute swatch data (term meta) when edited from the product swatches panel.
 */
class GlobalTermUpdater {
    /**
     * Save global term settings via post ID.
     *
     * @param int $post_id Product ID.
     */
    public function save( $post_id ) {
        $post_id = absint( $post_id );
        if ( !$post_id ) {
            return;
        }
        if ( !$this->verify_nonce() ) {
            return;
        }
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Sanitized field-by-field below, nonce verified above.
        $raw = ( isset( $_POST['b3wvs_global_terms'] ) ? wp_unslash( $_POST['b3wvs_global_terms'] ) : array() );
        if ( !is_array( $raw ) ) {
            return;
        }
        foreach ( $raw as $attribute_name => $options ) {
            if ( !is_array( $options ) ) {
                continue;
            }
            $attribute_key = sanitize_text_field( (string) $attribute_name );
            if ( !taxonomy_exists( $attribute_key ) ) {
                continue;
            }
            foreach ( $options as $slug => $data ) {
                if ( !is_array( $data ) ) {
                    continue;
                }
                $slug_key = sanitize_text_field( (string) $slug );
                $term = get_term_by( 'slug', $slug_key, $attribute_key );
                if ( !$term || is_wp_error( $term ) ) {
                    continue;
                }
                if ( !current_user_can( 'edit_term', $term->term_id ) ) {
                    continue;
                }
                $sanitized = $this->sanitize_global_entry( $data );
                $this->apply_term_meta( $term->term_id, $sanitized );
            }
        }
    }

    /**
     * Verify the nonce for saving.
     *
     * @return bool
     */
    private function verify_nonce() {
        if ( !isset( $_POST['b3wvs_product_swatches_nonce'] ) ) {
            return false;
        }
        return wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['b3wvs_product_swatches_nonce'] ) ), 'b3wvs_save_product_swatches' );
    }

    /**
     * Sanitize a global term entry.
     *
     * @param array $data Raw data for one option.
     * @return array Sanitized data.
     */
    private function sanitize_global_entry( $data ) {
        $type = ( isset( $data['type'] ) ? sanitize_text_field( (string) $data['type'] ) : '' );
        if ( !in_array( $type, TermMetaSanitizer::ALLOWED_TYPES, true ) ) {
            $resolved_type = '';
            $type = $resolved_type;
        }
        $payload = array(
            'type'  => $type,
            'color' => ( isset( $data['color'] ) ? sanitize_text_field( (string) $data['color'] ) : '' ),
            'label' => ( isset( $data['label'] ) ? sanitize_text_field( (string) $data['label'] ) : '' ),
        );
        return $payload;
    }

    /**
     * Apply sanitized data to term meta.
     *
     * @param int   $term_id  Term ID.
     * @param array $payload  Sanitized payload.
     */
    private function apply_term_meta( $term_id, $payload ) {
        $type = ( isset( $payload['type'] ) ? $payload['type'] : '' );
        $label = ( isset( $payload['label'] ) ? sanitize_text_field( (string) $payload['label'] ) : '' );
        if ( '' === trim( $label ) ) {
            delete_term_meta( $term_id, 'b3_wvs_label' );
        } else {
            update_term_meta( $term_id, 'b3_wvs_label', $label );
        }
        update_term_meta( $term_id, 'b3_wvs_type', $type );
        if ( '' === $type ) {
            $this->clear_shared_meta( $term_id );
            return;
        }
        switch ( $type ) {
            case 'color':
            case 'button':
                $this->save_color_data( $term_id, $payload );
                break;
            default:
                $this->clear_shared_meta( $term_id );
                break;
        }
    }

    /**
     * Clear all term meta values for a term.
     *
     * @param int $term_id Term ID.
     */
    private function clear_shared_meta( $term_id ) {
        delete_term_meta( $term_id, 'b3_wvs_color' );
    }

    /**
     * Save color/button data.
     *
     * @param int   $term_id Term ID.
     * @param array $payload Sanitized payload.
     */
    private function save_color_data( $term_id, $payload ) {
        $color = ( isset( $payload['color'] ) ? $payload['color'] : '' );
        if ( '' === trim( $color ) ) {
            delete_term_meta( $term_id, 'b3_wvs_color' );
        } else {
            update_term_meta( $term_id, 'b3_wvs_color', $color );
        }
    }

}
