<?php

declare(strict_types=1);

namespace App\Services;

final class TagNormalizer
{
    /**
     * Normalize a raw tag string to a clean, ASCII-only slug.
     *
     * Steps:
     * 1. Trim + lowercase
     * 2. Transliterate Unicode → ASCII (iconv or Transliterator)
     * 3. Strip everything except [a-z0-9 -]
     * 4. Collapse whitespace, replace spaces with hyphens
     * 5. Strip leading/trailing hyphens
     * 6. Enforce max length
     */
    public function normalize(string $tag): string
    {
        $value = trim($tag);
        if ($value === '') {
            return '';
        }

        $value = mb_strtolower($value, 'UTF-8');

        // Transliterate to ASCII (e.g. é→e, ü→u, 日→nihon).
        // Try Transliterator first (intl extension), fall back to iconv.
        if (class_exists('\Transliterator')) {
            $trans = \Transliterator::create('Any-Latin; Latin-ASCII; Lower()');
            if ($trans !== null) {
                $value = (string) ($trans->transliterate($value) ?: $value);
            }
        } elseif (function_exists('iconv')) {
            $ascii = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
            if ($ascii !== false && $ascii !== '') {
                $value = $ascii;
            }
        }

        // Keep only ASCII letters, digits, spaces and hyphens.
        $value = (string) preg_replace('/[^a-z0-9\s\-]+/', '', $value);

        // Normalize whitespace.
        $value = (string) preg_replace('/\s+/', ' ', $value);
        $value = trim($value);

        // Spaces → hyphens, collapse repeats, strip edge hyphens.
        $value = str_replace(' ', '-', $value);
        $value = (string) preg_replace('/-+/', '-', $value);
        $value = trim($value, '-');

        $maxLength = (int) config('tags.max_length', 32);
        if ($maxLength > 0 && strlen($value) > $maxLength) {
            $value = substr($value, 0, $maxLength);
            $value = rtrim($value, '-');
        }

        return $value;
    }

    /**
     * Convert a normalized slug back to a human-readable display name.
     *
     * "blue-sky"          → "Blue Sky"
     * "sci-fi-landscape"  → "Sci Fi Landscape"
     * "3d"                → "3D"
     *
     * If the raw input is available, pass it instead of the slug — it gives
     * better casing (e.g. the AI sends "digital painting", no hyphens yet).
     */
    public function toDisplayName(string $slugOrRaw): string
    {
        // If raw input still has mixed case or spaces, title-case it directly.
        $clean = trim($slugOrRaw);
        if ($clean === '') {
            return '';
        }

        // Replace hyphens and underscores with spaces for word splitting.
        $spaced = str_replace(['-', '_'], ' ', $clean);

        // Title-case each word (mb_convert_case handles UTF-8 safely).
        return mb_convert_case($spaced, MB_CASE_TITLE, 'UTF-8');
    }
}
