<?php
/**
 * AJAX — WooCommerce product brands (inventory › brands).
 */

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

function zerti_ajax_product_brands_guard(): void
{
    check_ajax_referer('zerti_product_brands', 'nonce');

    if (!zerti_user_can_access_admin() || !zerti_user_can_manage_product_brands()) {
        wp_send_json_error(['message' => 'forbidden'], 403);
    }

    if (!zerti_product_brands_available()) {
        wp_send_json_error(['message' => 'taxonomy_missing'], 400);
    }
}

/**
 * @param array<string, mixed> $source
 * @return array{term:string}
 */
function zerti_ajax_product_brands_search_input_from_array(array $source): array
{
    $term = isset($source['term']) ? sanitize_text_field(wp_unslash((string) $source['term'])) : '';

    return [
        'term' => $term,
    ];
}

/**
 * @return array{term:string}
 */
/**
 * @param array<string, mixed> $source
 * @return array{search:string}
 */
function zerti_ajax_product_brands_list_input_from_array(array $source): array
{
    $search = isset($source['search']) ? sanitize_text_field(wp_unslash((string) $source['search'])) : '';

    return [
        'search' => $search,
    ];
}

/**
 * @return array{search:string}
 */
/**
 * @param array<string, mixed> $source
 * @return array{id:int}
 */
function zerti_ajax_product_brand_delete_input_from_array(array $source): array
{
    $id = isset($source['id']) ? absint(wp_unslash((string) $source['id'])) : 0;

    return [
        'id' => $id,
    ];
}

/**
 * @return array{id:int}
 */
function zerti_ajax_product_brands_search(): void
{
    check_ajax_referer('zerti_product_brands', 'nonce');

    if (!zerti_user_can_access_admin() || !current_user_can('edit_products')) {
        wp_send_json_error(['message' => 'forbidden'], 403);
    }

    if (!zerti_product_brands_available()) {
        wp_send_json_error(['message' => 'taxonomy_missing'], 400);
    }

    $post = zerti_unslash_post_array();
    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified via check_ajax_referer() above.
    $input = zerti_ajax_product_brands_search_input_from_array($post);
    $term = $input['term'];

    wp_send_json_success([
        'brands' => zerti_product_brands_search_for_picker($term),
    ]);
}

function zerti_ajax_product_brands_list(): void
{
    zerti_ajax_product_brands_guard();

    $post = zerti_unslash_post_array();
    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified in zerti_ajax_product_brands_guard().
    $input = zerti_ajax_product_brands_list_input_from_array($post);
    $search = $input['search'];
    $flat = zerti_product_brands_flat_list();

    if ($search !== '') {
        $matched = zerti_product_brands_filter_flat_by_search($flat, $search);
        if ($matched === []) {
            $flat = [];
        } else {
            $match_ids = [];
            foreach ($matched as $row) {
                $match_ids[(int) ($row['id'] ?? 0)] = true;
            }
            $by_id = [];
            foreach ($flat as $row) {
                $by_id[(int) $row['id']] = $row;
            }
            $keep = $match_ids;
            foreach (array_keys($match_ids) as $mid) {
                $parent = (int) ($by_id[$mid]['parent'] ?? 0);
                while ($parent > 0 && !isset($keep[$parent])) {
                    $keep[$parent] = true;
                    $parent = (int) ($by_id[$parent]['parent'] ?? 0);
                }
            }
            $flat = array_values(array_filter(
                $flat,
                static function (array $row) use ($keep): bool {
                    return isset($keep[(int) ($row['id'] ?? 0)]);
                }
            ));
        }
    }

    wp_send_json_success([
        'flat' => $flat,
        'tree' => zerti_product_brands_build_tree($flat),
        'parent_options' => zerti_product_brand_parent_options(),
        'total' => count($flat),
    ]);
}

function zerti_ajax_product_brand_save(): void
{
    zerti_ajax_product_brands_guard();

    $post = zerti_unslash_post_array();
    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified in zerti_ajax_product_brands_guard().
    $payload = zerti_product_brand_payload_from_array($post);
    $result = zerti_product_brand_save($payload);

    if (empty($result['ok'])) {
        $code = isset($result['code']) ? (string) $result['code'] : 'save_failed';
        $msg = zerti_product_brand_error_message(
            $code,
            isset($result['message']) ? (string) $result['message'] : ''
        );
        wp_send_json_error(['message' => $msg, 'code' => $code], 400);
    }

    wp_send_json_success([
        'item' => $result['item'] ?? null,
        'flat' => zerti_product_brands_flat_list(),
        'tree' => zerti_product_brands_build_tree(zerti_product_brands_flat_list()),
        'parent_options' => zerti_product_brand_parent_options((int) ($result['item']['id'] ?? 0)),
    ]);
}

function zerti_ajax_product_brand_delete(): void
{
    zerti_ajax_product_brands_guard();

    $post = zerti_unslash_post_array();
    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- verified in zerti_ajax_product_brands_guard().
    $input = zerti_ajax_product_brand_delete_input_from_array($post);
    $id = $input['id'];
    $result = zerti_product_brand_delete($id);

    if (empty($result['ok'])) {
        $code = isset($result['code']) ? (string) $result['code'] : 'delete_failed';
        $msg = zerti_product_brand_error_message(
            $code,
            isset($result['message']) ? (string) $result['message'] : ''
        );
        wp_send_json_error(['message' => $msg, 'code' => $code], 400);
    }

    wp_send_json_success([
        'flat' => zerti_product_brands_flat_list(),
        'tree' => zerti_product_brands_build_tree(zerti_product_brands_flat_list()),
        'parent_options' => zerti_product_brand_parent_options(),
    ]);
}

