<?php

if (!defined('ABSPATH')) { exit; }

class AIEO_Exchanger_Term_Resolver {

    
    public static function resolve_terms(array $entries, $taxonomy, $mode) {
        if (!taxonomy_exists($taxonomy)) {
            return array('term_ids' => array(), 'created' => 0, 'errors' => array());
        }
        $created = 0;
        $errors  = array();
        $term_ids = array();

        
        
        $sorted = self::sort_with_parents_first($entries);

        
        $resolved = array(); 

        foreach ($sorted as $entry) {
            $slug = (string) ($entry['slug'] ?? '');
            $name = (string) ($entry['name'] ?? '');
            if ($slug === '' && $name === '') { continue; }

            $tid = self::find_term_id($slug, $name, $taxonomy);

            if ($tid <= 0) {
                if ($mode === 'create_link_only') {
                    
                    continue;
                }
                if ($mode === 'update_only') {
                    continue;
                }
                $args = array();
                if (!empty($entry['parent_slug']) && isset($resolved[(string) $entry['parent_slug']])) {
                    $args['parent'] = (int) $resolved[(string) $entry['parent_slug']];
                }
                if (!empty($entry['description'])) {
                    $args['description'] = (string) $entry['description'];
                }
                if ($slug !== '') { $args['slug'] = $slug; }

                $insert = wp_insert_term($name !== '' ? $name : $slug, $taxonomy, $args);
                if (is_wp_error($insert)) {
                    
                    if ($insert->get_error_code() === 'term_exists') {
                        $existing = $insert->get_error_data();
                        $tid = is_array($existing) ? (int) ($existing['term_id'] ?? 0) : (int) $existing;
                    } else {
                        $errors[] = array('slug' => $slug, 'taxonomy' => $taxonomy, 'error' => $insert->get_error_message());
                        continue;
                    }
                } else {
                    $tid = (int) $insert['term_id'];
                    $created++;
                }
            }

            
            if ($tid > 0 && $mode !== 'create_link_only' && $mode !== 'create_no_term_meta') {
                self::apply_term_meta($tid, $entry, $mode);
            }

            if ($tid > 0) {
                $term_ids[] = $tid;
                if ($slug !== '') { $resolved[$slug] = $tid; }
            }
        }

        return array(
            'term_ids' => array_values(array_unique(array_map('intval', $term_ids))),
            'created'  => $created,
            'errors'   => $errors,
        );
    }

    
    private static function sort_with_parents_first(array $entries) {
        $by_slug = array();
        foreach ($entries as $e) {
            $slug = (string) ($e['slug'] ?? '');
            if ($slug !== '') { $by_slug[$slug] = $e; }
        }
        $out = array();
        $seen = array();
        $emit = function ($entry) use (&$out, &$seen, &$emit, &$by_slug) {
            $slug = (string) ($entry['slug'] ?? '');
            if ($slug !== '' && isset($seen[$slug])) { return; }
            $parent = (string) ($entry['parent_slug'] ?? '');
            if ($parent !== '' && isset($by_slug[$parent]) && empty($seen[$parent])) {
                $emit($by_slug[$parent]);
            }
            $out[] = $entry;
            if ($slug !== '') { $seen[$slug] = true; }
        };
        foreach ($entries as $e) { $emit($e); }
        return $out;
    }

    
    public static function find_term_id($slug, $name, $taxonomy) {
        if ($slug !== '') {
            $t = get_term_by('slug', $slug, $taxonomy);
            if ($t && !is_wp_error($t)) { return (int) $t->term_id; }
        }
        if ($name !== '') {
            $t = get_term_by('name', $name, $taxonomy);
            if ($t && !is_wp_error($t)) { return (int) $t->term_id; }
        }
        return 0;
    }

    
    private static function apply_term_meta($term_id, array $entry, $mode) {
        
        $image_keys = array(
            'thumbnail'  => 'thumbnail_id',
            'brand_logo' => 'brand_logo',
        );
        foreach ($image_keys as $json_key => $meta_key) {
            if (empty($entry[$json_key]['src'])) { continue; }
            $src = (string) $entry[$json_key]['src'];
            $existing = (int) get_term_meta($term_id, $meta_key, true);

            if ($existing > 0 && $mode === 'update_only') {
                continue; 
            }
            if ($existing > 0 && $mode !== 'overwrite') {
                continue; 
            }
            $aid = AIEO_Exchanger_Image_Resolver::resolve($src, $term_id, $meta_key);
            if ($aid > 0) {
                update_term_meta($term_id, $meta_key, $aid);
            }
        }

        
        if (!empty($entry['extra_term_meta']) && is_array($entry['extra_term_meta'])) {
            foreach ($entry['extra_term_meta'] as $k => $v) {
                if (!is_string($k)) { continue; }
                $existing = get_term_meta($term_id, $k, true);
                if ($existing !== '' && $mode === 'update_only')   { continue; }
                if ($existing !== '' && $mode !== 'overwrite')     { continue; }
                update_term_meta($term_id, $k, is_scalar($v) ? (string) $v : $v);
            }
        }

        
        if (!empty($entry['swatch']) && is_array($entry['swatch'])) {
            self::apply_swatch_meta($term_id, $entry['swatch'], $mode);
        }
    }

    
    private static function apply_swatch_meta($term_id, array $swatch, $mode) {
        $type = (string) ($swatch['type'] ?? '');
        if ($type === 'image') {
            $existing = (int) get_term_meta($term_id, 'product_attribute_image', true);
            if ($existing > 0 && $mode === 'update_only')   { return; }
            if ($existing > 0 && $mode !== 'overwrite')     { return; }
            $src = (string) ($swatch['src'] ?? '');
            if ($src === '') { return; }
            $aid = AIEO_Exchanger_Image_Resolver::resolve($src, $term_id, 'product_attribute_image');
            if ($aid > 0) {
                update_term_meta($term_id, 'product_attribute_image', $aid);
                update_term_meta($term_id, 'product_attribute_color_type', '');
            }
            return;
        }

        
        
        $writeable = ($mode === 'overwrite' || $mode === 'create_with_term_meta');
        if (!$writeable && get_term_meta($term_id, 'product_attribute_color_type', true) !== '') {
            return;
        }

        if ($type === 'color') {
            update_term_meta($term_id, 'product_attribute_color_type', 'background');
            update_term_meta($term_id, 'product_attribute_color',      (string) ($swatch['value'] ?? ''));
        } elseif ($type === 'gradient') {
            update_term_meta($term_id, 'product_attribute_color_type',                  'gradient');
            update_term_meta($term_id, 'product_attribute_color_gradient_color_1',      (string) ($swatch['from'] ?? ''));
            update_term_meta($term_id, 'product_attribute_color_gradient_color_2',      (string) ($swatch['to']   ?? ''));
            update_term_meta($term_id, 'product_attribute_color_gradient_direction',    (string) ($swatch['direction'] ?? 'to right'));
        } elseif ($type === 'multiple') {
            update_term_meta($term_id, 'product_attribute_color_type', 'multiple');
            $colors = (array) ($swatch['colors'] ?? array());
            for ($i = 1; $i <= 4; $i++) {
                update_term_meta($term_id, 'product_attribute_color_multiple_color_' . $i, (string) ($colors[$i - 1] ?? ''));
            }
            update_term_meta($term_id, 'product_attribute_color_multiple_direction', (string) ($swatch['direction'] ?? 'to right'));
        }
    }
}
