<?php

namespace Soft_Tehnica\Freya_Sync_Service\Services;

use WP_Query;
use WP_Term;

defined('ABSPATH') || exit;

class CategoryHideService
{

    public function __construct()
    {
        $this->setup_hooks();
    }

    private function setup_hooks(): void
    {
        add_filter('get_terms_args', [$this, 'hide_categories'], 10, 2);
        add_action(
            'woocommerce_product_query',
            [$this, 'filter_products_in_hidden_categories']
        );
        add_filter('get_terms', [$this, 'add_disabled_label_to_terms'], 10, 3);
    }

    public function hide_categories(array $args, array $taxonomies): array
    {
        if (is_admin() || !in_array('product_cat', $taxonomies)) {
            return $args;
        }

        $hidden = $this->get_hidden_category_ids();

        if (empty($hidden)) {
            return $args;
        }

        $args['exclude'] = array_merge(
            $args['exclude'] ?? [],
            $hidden
        );

        return $args;
    }

    public function filter_products_in_hidden_categories(WP_Query $q): void
    {
        if (is_admin()) {
            return;
        }

        $hidden = $this->get_hidden_category_ids();

        if (empty($hidden)) {
            return;
        }

        $tax_query = (array)$q->get('tax_query');

        $tax_query[] = [
            'taxonomy' => 'product_cat',
            'field' => 'term_id',
            'terms' => $hidden,
            'operator' => 'NOT IN',
        ];

        $q->set('tax_query', $tax_query);
    }

    /**
     * @param WP_Term[]|int[] $terms
     * @param string[] $taxonomies
     */
    public function add_disabled_label_to_terms(
        array $terms,
        array $taxonomies,
        array $args
    ): array {
        if (!is_admin() || !in_array('product_cat', $taxonomies)) {
            return $terms;
        }

        foreach ($terms as $term) {
            if (is_int($term)) {
                $is_hidden = get_term_meta($term, '_freya_inactive', true);
            } else {
                $is_hidden = get_term_meta(
                    $term->term_id,
                    '_freya_inactive',
                    true
                );
            }

            if ($is_hidden === '1') {
                $term->name .= ' (dezactivată din Freya)';
            }
        }

        return $terms;
    }

    /**
     * @return int[]
     */
    private function get_hidden_category_ids(): array
    {
        global $wpdb;
        /* @var \wpdb $wpdb */

        return $wpdb->get_col(
            <<<SQL
                SELECT term_id FROM {$wpdb->termmeta}
                WHERE meta_key = '_freya_inactive'
                AND meta_value = 1
                SQL
        );
    }
}
