<?php
/**
 * WooCommerce product tags (product_tag) — list and CRUD for ZERTI inventory.
 */

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

function zerti_product_tag_taxonomy(): string
{
    return 'product_tag';
}

function zerti_product_tags_available(): bool
{
    return taxonomy_exists(zerti_product_tag_taxonomy());
}

function zerti_product_tags_capability(): string
{
    return 'manage_product_terms';
}

function zerti_user_can_manage_product_tags(): bool
{
    if (current_user_can(zerti_product_tags_capability())) {
        return true;
    }

    return current_user_can('edit_products');
}

/**
 * @return array<string, mixed>|null
 */
function zerti_product_tag_to_item(WP_Term $term): ?array
{
    if ($term->taxonomy !== zerti_product_tag_taxonomy()) {
        return null;
    }

    return [
        'id' => (int) $term->term_id,
        'name' => $term->name,
        'slug' => $term->slug,
        'parent' => 0,
        'description' => $term->description,
        'count' => (int) $term->count,
        'order' => 0,
        'thumbnail_id' => 0,
        'thumbnail_url' => '',
        'display_type' => 'default',
    ];
}

/**
 * @return list<array<string, mixed>>
 */
function zerti_product_tags_flat_list(): array
{
    if (!zerti_product_tags_available()) {
        return [];
    }

    $terms = get_terms([
        'taxonomy' => zerti_product_tag_taxonomy(),
        'hide_empty' => false,
        'orderby' => 'name',
        'order' => 'ASC',
    ]);

    if (!is_array($terms) || is_wp_error($terms)) {
        return [];
    }

    $items = [];
    foreach ($terms as $term) {
        if (!$term instanceof WP_Term) {
            continue;
        }
        $row = zerti_product_tag_to_item($term);
        if ($row !== null) {
            $items[] = $row;
        }
    }

    usort(
        $items,
        static function (array $a, array $b): int {
            return strcasecmp((string) ($a['name'] ?? ''), (string) ($b['name'] ?? ''));
        }
    );

    return $items;
}

/**
 * Search product tags by name (product editor autocomplete).
 *
 * @return list<array{id:int,name:string,slug:string}>
 */
function zerti_product_tags_search_for_picker(string $term, int $limit = 20): array
{
    if (!zerti_product_tags_available()) {
        return [];
    }

    $term = trim($term);
    if ($term === '') {
        return [];
    }

    $limit = max(1, min(50, $limit));
    $terms = get_terms([
        'taxonomy' => zerti_product_tag_taxonomy(),
        'hide_empty' => false,
        'number' => $limit,
        'search' => $term,
        'orderby' => 'name',
        'order' => 'ASC',
    ]);

    if (!is_array($terms) || is_wp_error($terms)) {
        return [];
    }

    $items = [];
    foreach ($terms as $tag_term) {
        if (!$tag_term instanceof WP_Term) {
            continue;
        }
        $row = zerti_product_tag_to_item($tag_term);
        if ($row === null) {
            continue;
        }
        $items[] = [
            'id' => (int) $row['id'],
            'name' => (string) $row['name'],
            'slug' => (string) $row['slug'],
        ];
    }

    return $items;
}

/**
 * @param list<array<string, mixed>> $flat
 * @return list<array<string, mixed>>
 */
function zerti_product_tags_build_tree(array $flat): array
{
    $out = [];
    foreach ($flat as $row) {
        $node = $row;
        $node['children'] = [];
        $out[] = $node;
    }

    return $out;
}

/**
 * @return list<array{id:int,label:string,depth:int}>
 */
function zerti_product_tag_parent_options(int $exclude_term_id = 0): array
{
    unset($exclude_term_id);

    return [
        [
            'id' => 0,
            'label' => __('— No parent —', 'zerti'),
            'depth' => 0,
        ],
    ];
}

function zerti_product_tag_validate_parent(int $term_id, int $parent_id): bool
{
    unset($term_id);

    return $parent_id === 0;
}

/**
 * @param array<string, mixed> $source
 * @return array{id:int,name:string,slug:string,parent:int,description:string,display_type:string,thumbnail_id:int,order:int}
 */
function zerti_product_tag_payload_from_array(array $source): array
{
    $id = isset($source['id']) ? absint(wp_unslash((string) $source['id'])) : 0;
    $name = isset($source['name']) ? sanitize_text_field(wp_unslash((string) $source['name'])) : '';
    $slug = isset($source['slug']) ? sanitize_title(wp_unslash((string) $source['slug'])) : '';
    $description = isset($source['description']) ? wp_kses_post(wp_unslash((string) $source['description'])) : '';

    return [
        'id' => $id,
        'name' => $name,
        'slug' => $slug,
        'parent' => 0,
        'description' => $description,
        'display_type' => 'default',
        'thumbnail_id' => 0,
        'order' => 0,
    ];
}

/**
 * @return array{id:int,name:string,slug:string,parent:int,description:string,display_type:string,thumbnail_id:int,order:int}
 */
/**
 * @param array{id:int,name:string,slug:string,parent:int,description:string,display_type:string,thumbnail_id:int,order:int} $payload
 * @return array{ok:bool,item?:array<string,mixed>,message?:string,code?:string}
 */
function zerti_product_tag_save(array $payload): array
{
    if (!zerti_product_tags_available()) {
        return ['ok' => false, 'message' => __('Taxonomy missing', 'zerti'), 'code' => 'taxonomy_missing'];
    }

    $name = trim($payload['name'] ?? '');
    if ($name === '') {
        return ['ok' => false, 'message' => __('Name is required', 'zerti'), 'code' => 'name_required'];
    }

    $id = (int) ($payload['id'] ?? 0);
    $slug = trim((string) ($payload['slug'] ?? ''));
    if ($slug === '') {
        $slug = sanitize_title($name);
    }

    $args = [
        'description' => (string) ($payload['description'] ?? ''),
        'slug' => $slug,
    ];

    if ($id > 0) {
        $existing = get_term($id, zerti_product_tag_taxonomy());
        if (!$existing instanceof WP_Term || is_wp_error($existing)) {
            return ['ok' => false, 'message' => __('Not found', 'zerti'), 'code' => 'not_found'];
        }

        $result = wp_update_term($id, zerti_product_tag_taxonomy(), array_merge($args, ['name' => $name]));
    } else {
        $result = wp_insert_term($name, zerti_product_tag_taxonomy(), $args);
    }

    if (is_wp_error($result)) {
        return [
            'ok' => false,
            'message' => $result->get_error_message(),
            'code' => (string) $result->get_error_code(),
        ];
    }

    $term_id = $id > 0 ? $id : (int) ($result['term_id'] ?? 0);
    if ($term_id < 1) {
        return ['ok' => false, 'message' => __('Save failed', 'zerti'), 'code' => 'save_failed'];
    }

    $term = get_term($term_id, zerti_product_tag_taxonomy());
    if (!$term instanceof WP_Term || is_wp_error($term)) {
        return ['ok' => false, 'message' => __('Save failed', 'zerti'), 'code' => 'save_failed'];
    }

    $item = zerti_product_tag_to_item($term);

    return $item !== null
        ? ['ok' => true, 'item' => $item]
        : ['ok' => false, 'message' => __('Save failed', 'zerti'), 'code' => 'save_failed'];
}

/**
 * @return array{ok:bool,message?:string,code?:string}
 */
function zerti_product_tag_delete(int $term_id): array
{
    if ($term_id < 1 || !zerti_product_tags_available()) {
        return ['ok' => false, 'message' => __('Not found', 'zerti'), 'code' => 'not_found'];
    }

    $term = get_term($term_id, zerti_product_tag_taxonomy());
    if (!$term instanceof WP_Term || is_wp_error($term)) {
        return ['ok' => false, 'message' => __('Not found', 'zerti'), 'code' => 'not_found'];
    }

    $result = wp_delete_term($term_id, zerti_product_tag_taxonomy());
    if (is_wp_error($result)) {
        return [
            'ok' => false,
            'message' => $result->get_error_message(),
            'code' => (string) $result->get_error_code(),
        ];
    }
    if ($result === false) {
        return ['ok' => false, 'message' => __('Delete failed', 'zerti'), 'code' => 'delete_failed'];
    }

    return ['ok' => true];
}

function zerti_product_tag_error_message(string $code, string $fallback = ''): string
{
    $map = [
        'name_required' => __('Tag name is required.', 'zerti'),
        'not_found' => __('Tag not found.', 'zerti'),
        'taxonomy_missing' => __('WooCommerce product tag is not available.', 'zerti'),
        'delete_failed' => __('Could not delete tag.', 'zerti'),
        'save_failed' => __('Could not save tag.', 'zerti'),
        'term_exists' => __('Duplicate tag name or slug.', 'zerti'),
    ];

    if (isset($map[$code])) {
        return $map[$code];
    }

    return $fallback !== '' ? $fallback : __('An error occurred.', 'zerti');
}
