<?php

namespace auctionforge\inc\extensions;

use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\model\Auction;
use WP_Term;

class AuctionSlugTemplate
{
    public function init()
    {
        if (defined('AUCTIONFORGE_AUCTION_URL_ENABLED') && AUCTIONFORGE_AUCTION_URL_ENABLED === true) {
            add_filter('auctionforge_category_nicename_field', [$this, 'category_nicename_field'], 10, 5);
            add_filter('auctionforge_ml_prefix_field', [$this, 'category_ml_prefix_field'], 10, 4);
        }
    }

    /**
     * @param $slug string
     * @param $taxonomy string
     * @param $exclude_term_id int
     * @return bool
     */
    private function is_term_exists($slug, $taxonomy, $exclude_term_id = 0)
    {
        $terms = get_terms([
            'taxonomy' => $taxonomy,
            'slug' => $slug,
            'hide_empty' => false,
            'exclude' => [$exclude_term_id],
            'lang' => ''
        ]);

        return !empty($terms);
    }

    /**
     * @param $auctionSlug string
     * @param $auction \WP_Term
     * @param $instance Auction;
     * @param $v
     * @return mixed|string
     */
    public function category_nicename_field($auctionSlug, $auction, $instance, $v, $mlPrefix)
    {
        if (
            ($this->isTemplateMatch($auctionSlug) || !($auction instanceof WP_Term)) &&
            apply_filters('auctionforge_slug_template_enabled', false, $auctionSlug, $auction, $instance, $mlPrefix)
        ) {
            return $auctionSlug;
        }

        $base = $this->prefixBuild($mlPrefix);
        $auctionSlug = $this->templateBuild($instance, $base);

        if ($auction instanceof WP_Term) {
            $auctionSlug = $this->generateCheckTermSlug(
                $auctionSlug,
                $auction,
                $instance,
                $base
            );
        } else {
            $counter = 1;
            while ($this->is_term_exists($auctionSlug, 'auction_number')) {
                $suffix = $this->get_letter_index($counter++);
                $auctionSlug = "{$base}-{$suffix}";
            }
        }

        return $auctionSlug;
    }

    /**
     * @param $instance Auction
     * @param $slugAuction string
     * @return string
     */
    private function templateBuild($instance, $slugAuction) {
        $prefix = $instance->getNumber() ?: $instance->getId();
        return sanitize_title(sprintf("%s-%s", $prefix, $slugAuction));
    }

    /**
     * @param $checkSlug string
     * @param WP_Term $term
     * @param $instance Auction
     * @param $base string
     * @return string
     */
    function generateCheckTermSlug($checkSlug, $term, $instance, $base)
    {
        $original_slug = sanitize_title($checkSlug);

        if (!($term instanceof WP_Term)) {
            return $original_slug;
        }

        $base_slug = $this->templateBuild($instance, $base);
        $counter = 1;
        $proposed_slug = $original_slug;

        while ($this->is_term_exists($proposed_slug, $term->taxonomy, $term->term_id)) {
            $suffix = $this->get_letter_index($counter++);
            $proposed_slug = "{$base_slug}-{$suffix}";
        }

        return $proposed_slug;
    }

    /**
     * @param $prefix string
     * @param $auctionSlug string
     * @return mixed|string
     */
    public function category_ml_prefix_field($prefix, $auctionSlug, $auction, $instance)
    {
        if ($this->isTemplateMatch($auctionSlug)) {
            $taxonomy = 'auction_number';
            $term_id = $auction instanceof WP_Term ? $auction->term_id : 0;

            if ($this->is_term_exists($auctionSlug, $taxonomy, $term_id)) {
                $base = $this->templateBuild($instance, $this->prefixBuild($prefix));
                $counter = 1;

                //error_log("🚨 [AuctionSlug] Базовый slug занят: {$auctionSlug}. Начинаем подбор суффикса");

                while (true) {
                    $suffix = $this->get_letter_index($counter);
                    $proposedSlug = "{$base}-{$suffix}";

                    $exists = $this->is_term_exists($proposedSlug, $taxonomy, $term_id);

                    //error_log("🔍 [AuctionSlug] Проверка slug: {$proposedSlug} — " . ($exists ? "занят" : "свободен"));

                    if (!$exists) {
                        //error_log("✅ [AuctionSlug] Возвращён префикс: -{$suffix}");
                        return "-{$suffix}";
                    }

                    $counter++;
                }
            }

            //error_log("✅ [AuctionSlug] Slug {$auctionSlug} уникален, префикс не требуется");
            return '';
        }

        //var_dump("ℹ️ [AuctionSlug] Slug {$auctionSlug} не соответствует шаблону, возвращаем оригинальный префикс");
        return $prefix;
    }


    /**
     * @param $auctionSlug string
     * @return false|int
     */
    private function isTemplateMatch($auctionSlug)
    {
        $isTemplateMatch = (preg_match('/^[A-Za-z0-9]+-(' . $this->chunksPattern() . ')(?:-[A-Za-z]+)?$/u', $auctionSlug));
        return apply_filters('auctionforge_slug_template_matches', $isTemplateMatch, $auctionSlug);
    }

    private function chunksPattern()
    {
        return implode('|', [
            'auction', 'auktion', 'catalog', 'asta', 'leilão', 'аукцион', 'subasta'
        ]);
    }

    /**
     * @param $mlPrefix string
     * @return string
     */
    private function prefixBuild($mlPrefix)
    {
        if ($mlPrefix == '') {
            var_dump("before", $mlPrefix);
            $mlPrefix = SettingsHelper::getOption('lang', 'en');
            var_dump("after", $mlPrefix);
        }
        $mlPrefix = preg_replace('/^-/', '', $mlPrefix);
        $prefixes = [
            'en' => 'auction', 'de' => 'auktion', 'he' => 'catalog',
            'it' => 'asta', 'pt' => 'leilão', 'ru' => 'аукцион', 'es' => 'subasta'
        ];

        $prefixes = apply_filters('auctionforge_slug_template_prefixes', $prefixes,  $mlPrefix);

        return $prefixes[$mlPrefix] ?? 'auction';
    }

    /**
     * @param $number int
     * @return string
     */
    public function get_letter_index($number) {
        $result = '';
        while ($number > 0) {
            $number--;
            $remainder = $number % 26;
            $result = chr(65 + $remainder) . $result;
            $number = intval($number / 26);
        }
        return $result;
    }
}
(new AuctionSlugTemplate())->init();