<?php

namespace MintyPHP\Http;

use MintyPHP\I18n;

/**
 * Handles locale detection and URL manipulation for multi-language support.
 */
class LocaleResolver
{
    private array $availableLocales;
    private string $defaultLocale;
    private string $basePath;

    public function __construct(?array $availableLocales = null, ?string $defaultLocale = null)
    {
        $this->defaultLocale = $defaultLocale ?? I18n::$defaultLocale;
        $this->availableLocales = $availableLocales ?? (defined('APP_LOCALES') ? APP_LOCALES : [$this->defaultLocale]);
        $this->basePath = trim(parse_url(\MintyPHP\Router::getBaseUrl(), PHP_URL_PATH) ?: '/', '/');
    }

    /**
     * Parse a request URI and extract locale information.
     *
     * @return array{
     *     locale: string,
     *     pathWithoutLocale: string,
     *     query: string,
     *     hadLocaleInUrl: bool,
     *     hadInvalidLocale: bool
     * }
     */
    public function parseUri(string $uri): array
    {
        $path = parse_url($uri, PHP_URL_PATH) ?: '';
        $query = parse_url($uri, PHP_URL_QUERY) ?: '';

        $relativePath = Request::stripBasePath($path);
        $segments = $relativePath === '' ? [] : explode('/', $relativePath);

        $localeCandidate = $segments[0] ?? '';
        $hadLocaleInUrl = false;
        $hadInvalidLocale = false;
        $locale = '';

        if ($localeCandidate !== '' && in_array($localeCandidate, $this->availableLocales, true)) {
            $locale = array_shift($segments);
            $hadLocaleInUrl = true;
        } elseif ($localeCandidate !== '' && $this->looksLikeLocale($localeCandidate)) {
            array_shift($segments);
            $hadInvalidLocale = true;
        }

        return [
            'locale' => $locale,
            'pathWithoutLocale' => implode('/', $segments),
            'query' => $query,
            'hadLocaleInUrl' => $hadLocaleInUrl,
            'hadInvalidLocale' => $hadInvalidLocale,
        ];
    }

    /**
     * Resolve the effective locale from multiple sources (priority order):
     * 1. URL segment (explicit)
     * 2. User session preference
     * 3. Cookie preference
     * 4. Default locale
     */
    public function resolveLocale(string $urlLocale, ?string $userLocale = null, ?string $cookieLocale = null): string
    {
        if ($urlLocale !== '' && $this->isValidLocale($urlLocale)) {
            return $urlLocale;
        }

        if ($userLocale !== null && $userLocale !== '' && $this->isValidLocale($userLocale)) {
            return $userLocale;
        }

        if ($cookieLocale !== null && $cookieLocale !== '' && $this->isValidLocale($cookieLocale)) {
            return $cookieLocale;
        }

        return $this->defaultLocale;
    }

    /**
     * Build a new REQUEST_URI without the locale segment.
     */
    public function buildUriWithoutLocale(string $pathWithoutLocale, string $query): string
    {
        $newPath = $this->basePath !== '' ? '/' . $this->basePath : '';

        if ($pathWithoutLocale !== '') {
            $newPath .= '/' . $pathWithoutLocale;
        } elseif ($newPath === '') {
            $newPath = '/';
        }

        return $newPath . ($query !== '' ? '?' . $query : '');
    }

    /**
     * Check if a locale string is valid (exists in available locales).
     */
    public function isValidLocale(string $locale): bool
    {
        return in_array($locale, $this->availableLocales, true);
    }

    private function looksLikeLocale(string $candidate): bool
    {
        return preg_match('/^[a-z]{2}(?:-[a-z]{2})?$/i', $candidate) === 1;
    }
}
