<?php

namespace App\Services;

use App\Models\Language;
use Illuminate\Contracts\Translation\Translator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View;

class LocalizationService
{
    public function __construct(private Translator $translator)
    {
    }

    public function activate(?string $requestedCode = null): ?Language
    {
        if (! Schema::hasTable('languages') || ! Schema::hasTable('language_translations')) {
            return null;
        }

        $availableLanguages = Language::query()
            ->where('is_active', true)
            ->orderByDesc('is_default')
            ->orderBy('name')
            ->get();

        $language = $requestedCode
            ? $availableLanguages->firstWhere('code', $requestedCode)
            : null;

        $language ??= $availableLanguages->firstWhere('is_default', true);
        $language ??= $availableLanguages->first();

        if (! $language) {
            return null;
        }

        $defaultLanguage = Language::query()
            ->where('is_active', true)
            ->where('is_default', true)
            ->first();

        if ($defaultLanguage) {
            $this->loadTranslations($defaultLanguage);

            if (method_exists($this->translator, 'setFallback')) {
                $this->translator->setFallback($defaultLanguage->code);
            }
        }

        if (! $defaultLanguage || $defaultLanguage->id !== $language->id) {
            $this->loadTranslations($language);
        }

        app()->setLocale($language->code);

        View::share('activeLanguage', $language);
        View::share('availableLanguages', $availableLanguages);

        return $language;
    }

    public function ui(string $key, string $fallback): string
    {
        $translated = $this->translator->get($key);

        return is_string($translated) && $translated !== $key
            ? $translated
            : $fallback;
    }

    public function catalog(): Collection
    {
        $english = trans('ui', [], 'en');
        $catalog = is_array($english) ? collect($english) : collect();

        if (Schema::hasTable('languages') && Schema::hasTable('language_translations')) {
            $defaultLanguage = Language::query()->where('is_default', true)->first();

            if ($defaultLanguage) {
                $defaultLanguage->translations()
                    ->pluck('value', 'key')
                    ->each(function (string $value, string $key) use ($catalog): void {
                        if (str_starts_with($key, 'ui.')) {
                            $catalog->put(substr($key, 3), $value);
                        }
                    });
            }
        }

        return $catalog->sortKeys();
    }

    private function loadTranslations(Language $language): void
    {
        $lines = $language->translations()
            ->pluck('value', 'key')
            ->filter(fn ($value): bool => filled($value))
            ->all();

        if ($lines !== []) {
            $this->translator->addLines($lines, $language->code);
        }
    }
}
