<?php
declare(strict_types=1);

namespace App\Support;

final class LocaleContext
{
    /**
     * @param array<int, string> $supportedLocales
     */
    public function __construct(
        private readonly array $supportedLocales,
        private readonly string $defaultLocale,
        private readonly ?string $explicitLocale = null,
        private readonly ?string $cookieLocale = null,
        private readonly ?string $preferredLocale = null,
        private readonly ?string $browserLocale = null,
        private readonly array $directions = [],
    ) {
    }

    public function uiLocale(): string
    {
        foreach ([
            $this->explicitLocale,
            $this->cookieLocale,
            $this->preferredLocale,
            $this->browserLocale,
            $this->defaultLocale,
        ] as $candidate) {
            $normalized = $this->normalize($candidate);

            if ($normalized !== null) {
                return $normalized;
            }
        }

        return $this->supportedLocales[0] ?? $this->defaultLocale;
    }

    public function direction(): string
    {
        return $this->directionForLocale($this->uiLocale());
    }

    public function contentDirection(?string $contentLocale): string
    {
        $normalized = $this->normalize($contentLocale);

        if ($normalized === null) {
            return 'auto';
        }

        return $this->directionForLocale($normalized);
    }

    /**
     * @return array{lang: string, dir: string}
     */
    public function htmlAttributes(): array
    {
        return [
            'lang' => $this->uiLocale(),
            'dir' => $this->direction(),
        ];
    }

    private function normalize(?string $locale): ?string
    {
        if ($locale === null) {
            return null;
        }

        $locale = strtolower(str_replace('_', '-', trim($locale)));

        if ($locale === '') {
            return null;
        }

        foreach ($this->supportedLocales as $supportedLocale) {
            $supportedLocale = strtolower(str_replace('_', '-', trim((string) $supportedLocale)));
            if ($locale === $supportedLocale) {
                return $supportedLocale;
            }
        }

        return null;
    }

    private function directionForLocale(string $locale): string
    {
        $normalized = strtolower(trim($locale));
        $configured = strtolower((string) ($this->directions[$normalized] ?? $this->directions[$locale] ?? ''));

        if (in_array($configured, ['rtl', 'ltr'], true)) {
            return $configured;
        }

        $base = explode('-', str_replace('_', '-', $normalized))[0];
        return in_array($base, ['ar', 'fa', 'he', 'ur', 'ps', 'sd', 'ug', 'yi', 'dv'], true) ? 'rtl' : 'ltr';
    }
}
