<?php

namespace App\Helpers;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class LanguageHelper
{
    /**
     * اللغات المدعومة
     */
    const SUPPORTED_LANGUAGES = [
        'en', 'ar', 'fr', 'de', 'es', 'ru', 'zh-CN'
    ];

    /**
     * اللغة الافتراضية
     */
    const DEFAULT_LANGUAGE = 'en';

    /**
     * تحديد اللغة المناسبة للمستخدم
     *
     * @return string
     */
    public static function determineUserLanguage(): string
    {
        // إذا كان المستخدم مسجل الدخول
        if (Auth::check()) {
            $user = Auth::user();

            // تحقق من وجود اللغة في قاعدة البيانات وأنها مدعومة
            if (!empty($user->lang) && in_array($user->lang, self::SUPPORTED_LANGUAGES)) {
                return $user->lang;
            }

            // إذا لم تكن اللغة صحيحة، ارجع للإنجليزية
            return self::DEFAULT_LANGUAGE;
        }

        // للمستخدمين غير المسجلين، حدد اللغة من المتصفح
        return self::detectBrowserLanguage();
    }

    /**
     * تحديد لغة المتصفح
     *
     * @return string
     */
    public static function detectBrowserLanguage(): string
    {
        // تحقق من وجود Accept-Language header
        $acceptLanguage = request()->header('Accept-Language', '');

        if (empty($acceptLanguage)) {
            return self::DEFAULT_LANGUAGE;
        }

        // تحليل قائمة اللغات من المتصفح
        $languages = array_reduce(
            explode(',', $acceptLanguage),
            function ($result, $lang) {
                $parts = explode(';q=', $lang);
                $langCode = trim($parts[0]);
                $priority = isset($parts[1]) ? (float) $parts[1] : 1.0;

                // تحويل اللغات المركبة (مثل en-US إلى en)
                $normalizedLang = self::normalizeLangCode($langCode);

                if ($normalizedLang && in_array($normalizedLang, self::SUPPORTED_LANGUAGES)) {
                    $result[$normalizedLang] = $priority;
                }

                return $result;
            },
            []
        );

        if (empty($languages)) {
            return self::DEFAULT_LANGUAGE;
        }

        // ترتيب اللغات حسب الأولوية وإرجاع الأعلى
        arsort($languages);
        return array_key_first($languages);
    }

    /**
     * تطبيع رمز اللغة
     *
     * @param string $langCode
     * @return string|null
     */
    private static function normalizeLangCode(string $langCode): ?string
    {
        $langCode = strtolower(trim($langCode));

        // تعامل مع اللغات المركبة
        $langMap = [
            'ar' => 'ar',
            'ar-sa' => 'ar',
            'ar-eg' => 'ar',
            'ar-ae' => 'ar',
            'en' => 'en',
            'en-us' => 'en',
            'en-gb' => 'en',
            'fr' => 'fr',
            'fr-fr' => 'fr',
            'de' => 'de',
            'de-de' => 'de',
            'es' => 'es',
            'es-es' => 'es',
            'ru' => 'ru',
            'ru-ru' => 'ru',
            'zh' => 'zh-CN',
            'zh-cn' => 'zh-CN',
            'zh-hans' => 'zh-CN',
        ];

        return $langMap[$langCode] ?? null;
    }

    /**
     * تحديث لغة المستخدم في قاعدة البيانات
     *
     * @param string $langCode
     * @return bool
     */
    public static function updateUserLanguage(string $langCode): bool
    {
        if (!Auth::check() || !in_array($langCode, self::SUPPORTED_LANGUAGES)) {
            return false;
        }

        try {
            /** @var \App\Models\Z_Website\User $user */
            $user = Auth::user();
            $user->lang = $langCode;
            $user->save();
            return true;
        } catch (\Exception $e) {
            Log::error('Failed to update user language: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * الحصول على معلومات اللغة للـ JavaScript
     *
     * @return array
     */
    public static function getLanguageDataForJS(): array
    {
        $currentLang = self::determineUserLanguage();

        return [
            'currentLanguage' => $currentLang,
            'isAuthenticated' => Auth::check(),
            'userId' => Auth::check() ? Auth::id() : null,
            'supportedLanguages' => self::SUPPORTED_LANGUAGES,
            'defaultLanguage' => self::DEFAULT_LANGUAGE,
            'browserLanguage' => self::detectBrowserLanguage(),
        ];
    }

    /**
     * ترجمة النص باستخدام مفتاح الترجمة
     *
     * @param string $key
     * @param array $params
     * @return string
     */
    public static function translate(string $key, array $params = []): string
    {
        try {
            $currentLang = self::determineUserLanguage();
            $translations = self::loadTranslations($currentLang);

            // الحصول على النص المترجم باستخدام النقاط كفاصل
            $text = self::getNestedValue($translations, $key);

            // إذا لم يوجد النص، جرب الإنجليزية كاحتياطي
            if (empty($text) && $currentLang !== self::DEFAULT_LANGUAGE) {
                $englishTranslations = self::loadTranslations(self::DEFAULT_LANGUAGE);
                $text = self::getNestedValue($englishTranslations, $key);
            }

            // إذا لم يوجد النص، أرجع المفتاح
            if (empty($text)) {
                return $key;
            }

            // استبدال المتغيرات في النص
            if (!empty($params)) {
                foreach ($params as $param => $value) {
                    $text = str_replace('[' . $param . ']', $value, $text);
                }
            }

            return $text;

        } catch (\Exception $e) {
            Log::error('Translation error: ' . $e->getMessage(), [
                'key' => $key,
                'params' => $params
            ]);
            return $key;
        }
    }

    /**
     * تحميل ملف الترجمة للغة معينة
     *
     * @param string $lang
     * @return array
     */
    private static function loadTranslations(string $lang): array
    {
        static $cache = [];

        if (isset($cache[$lang])) {
            return $cache[$lang];
        }

        $filePath = public_path("assets/languages/{$lang}.json");

        if (!file_exists($filePath)) {
            return [];
        }

        $content = file_get_contents($filePath);
        $translations = json_decode($content, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::error("Invalid JSON in language file: {$lang}.json");
            return [];
        }

        $cache[$lang] = $translations ?? [];
        return $cache[$lang];
    }

    /**
     * الحصول على قيمة متداخلة من مصفوفة باستخدام النقاط
     *
     * @param array $array
     * @param string $key
     * @return string|null
     */
    private static function getNestedValue(array $array, string $key): ?string
    {
        $keys = explode('.', $key);
        $value = $array;

        foreach ($keys as $k) {
            if (!is_array($value) || !isset($value[$k])) {
                return null;
            }
            $value = $value[$k];
        }

        return is_string($value) ? $value : null;
    }

    /**
     * التحقق من صحة رمز اللغة
     *
     * @param string $langCode
     * @return bool
     */
    public static function isValidLanguage(string $langCode): bool
    {
        return in_array($langCode, self::SUPPORTED_LANGUAGES);
    }
}
