<?php

namespace App\Helpers;

use App\Models\Language;

/**
 * Language Helper
 * 
 * Provides utility methods for handling language-related operations
 * across the insurance platform. This helper manages language detection,
 * translation support, and language-specific formatting.
 */
class LanguageHelper
{
    /**
     * Get the current language code from the request
     * 
     * Priority:
     * 1. Accept-Language header
     * 2. Session language
     * 3. Default language (English)
     * 
     * @return string Language code (en, zh, fa, etc.)
     */
    public static function getCurrentLanguage(): string
    {
        // Check Accept-Language header first
        if (request()->hasHeader('Accept-Language')) {
            $headerLang = request()->header('Accept-Language');
            $langCode = self::extractLanguageCode($headerLang);
            
            if ($langCode && self::isLanguageSupported($langCode)) {
                return $langCode;
            }
        }
        
        // Check session language if available
        if (session()->has('locale')) {
            $sessionLang = session('locale');
            if (self::isLanguageSupported($sessionLang)) {
                return $sessionLang;
            }
        }
        
        // Return default language (English)
        return 'en';
    }
    
    /**
     * Extract language code from Accept-Language header
     * 
     * Handles formats like:
     * - "en"
     * - "en-US"
     * - "zh-CN"
     * - "fa-IR"
     * - "en,zh;q=0.9,fa;q=0.8"
     * 
     * @param string $acceptLanguage Accept-Language header value
     * @return string|null Extracted language code
     */
    private static function extractLanguageCode(string $acceptLanguage): ?string
    {
        // Split by comma to get language preferences
        $languages = explode(',', $acceptLanguage);
        
        foreach ($languages as $lang) {
            // Remove quality weight if present (e.g., ;q=0.8)
            $lang = trim(explode(';', $lang)[0]);
            
            // Extract language code (e.g., "en" from "en-US")
            if (strpos($lang, '-') !== false) {
                $lang = explode('-', $lang)[0];
            }
            
            // Validate it's a valid language code
            if (preg_match('/^[a-z]{2,3}$/i', $lang)) {
                return strtolower($lang);
            }
        }
        
        return null;
    }
    
    /**
     * Check if a language code is supported by the application
     * 
     * @param string $languageCode Language code to check
     * @return bool True if supported, false otherwise
     */
    public static function isLanguageSupported(string $languageCode): bool
    {
        $supportedLanguages = ['en', 'zh', 'fa'];
        return in_array(strtolower($languageCode), $supportedLanguages);
    }
    
    /**
     * Get the language ID from database based on language code
     * 
     * @param string|null $languageCode Language code (optional, uses current if not provided)
     * @return int Language ID from database
     */
    public static function getLanguageId(?string $languageCode = null): int
    {
        $code = $languageCode ?? self::getCurrentLanguage();
        
        $language = Language::where('code', $code)
            ->where('is_active', true)
            ->first();
        
        // Fallback to English if language not found
        if (!$language) {
            $language = Language::where('code', 'en')
                ->where('is_active', true)
                ->first();
        }
        
        return $language ? $language->id : 1; // Default to ID 1 if no languages exist
    }
    
    /**
     * Check if current language is Chinese
     * 
     * @return bool True if current language is Chinese
     */
    public static function isChinese(): bool
    {
        return self::getCurrentLanguage() === 'zh';
    }
    
    /**
     * Check if current language is Persian/Farsi
     * 
     * @return bool True if current language is Persian
     */
    public static function isPersian(): bool
    {
        return self::getCurrentLanguage() === 'fa';
    }
    
    /**
     * Check if current language is English
     * 
     * @return bool True if current language is English
     */
    public static function isEnglish(): bool
    {
        return self::getCurrentLanguage() === 'en';
    }
    
    /**
     * Get the text direction for current language
     * 
     * @return string 'ltr' for left-to-right, 'rtl' for right-to-left
     */
    public static function getTextDirection(): string
    {
        return self::isPersian() ? 'rtl' : 'ltr';
    }
    
    /**
     * Get language name in its own language
     * 
     * @param string|null $languageCode Language code (optional)
     * @return string Language name
     */
    public static function getLanguageName(?string $languageCode = null): string
    {
        $code = $languageCode ?? self::getCurrentLanguage();
        
        return match($code) {
            'en' => 'English',
            'zh' => '中文',
            'fa' => 'فارسی',
            default => 'English',
        };
    }
    
    /**
     * Get all supported languages with their details
     * 
     * @return array Array of supported languages
     */
    public static function getSupportedLanguages(): array
    {
        return [
            [
                'code' => 'en',
                'name' => 'English',
                'native_name' => 'English',
                'direction' => 'ltr',
                'flag' => '🇺🇸',
            ],
            [
                'code' => 'zh',
                'name' => 'Chinese',
                'native_name' => '中文',
                'direction' => 'ltr',
                'flag' => '🇨🇳',
            ],
            [
                'code' => 'fa',
                'name' => 'Persian',
                'native_name' => 'فارسی',
                'direction' => 'rtl',
                'flag' => '🇮🇷',
            ],
        ];
    }
    
    /**
     * Translate a status code to current language
     * 
     * @param string $status Status code (pending, approved, etc.)
     * @return string Translated status
     */
    public static function translateStatus(string $status): string
    {
        $language = self::getCurrentLanguage();
        
        $translations = [
            'en' => [
                'pending' => 'Pending',
                'under_review' => 'Under Review',
                'approved' => 'Approved',
                'rejected' => 'Rejected',
                'completed' => 'Completed',
            ],
            'zh' => [
                'pending' => '待处理',
                'under_review' => '审核中',
                'approved' => '已批准',
                'rejected' => '已拒绝',
                'completed' => '已完成',
            ],
            'fa' => [
                'pending' => 'در انتظار',
                'under_review' => 'در حال بررسی',
                'approved' => 'تایید شده',
                'rejected' => 'رد شده',
                'completed' => 'تکمیل شده',
            ],
        ];
        
        return $translations[$language][$status] ?? ucfirst(str_replace('_', ' ', $status));
    }
    
    /**
     * Translate insurance type to current language
     * 
     * @param bool $isEntry True for entry insurance, false for exit
     * @return string Translated insurance type
     */
    public static function translateInsuranceType(bool $isEntry): string
    {
        $language = self::getCurrentLanguage();
        
        $translations = [
            'en' => [
                'entry' => 'Entry to Canada',
                'exit' => 'Exit from Canada',
            ],
            'zh' => [
                'entry' => '进入加拿大',
                'exit' => '离开加拿大',
            ],
            'fa' => [
                'entry' => 'ورود به کانادا',
                'exit' => 'خروج از کانادا',
            ],
        ];
        
        $type = $isEntry ? 'entry' : 'exit';
        return $translations[$language][$type] ?? ($isEntry ? 'Entry' : 'Exit');
    }
    
    /**
     * Format a date according to current language preferences
     * 
     * @param \Carbon\Carbon|string $date Date to format
     * @param string $format Format type (short, medium, long, full)
     * @return string Formatted date
     */
    public static function formatDate($date, string $format = 'medium'): string
    {
        if (!$date) {
            return '';
        }
        
        if (is_string($date)) {
            $date = \Carbon\Carbon::parse($date);
        }
        
        $language = self::getCurrentLanguage();
        
        // Different date formats for different languages
        $formats = [
            'en' => [
                'short' => 'm/d/Y',
                'medium' => 'M d, Y',
                'long' => 'F d, Y',
                'full' => 'l, F d, Y',
            ],
            'zh' => [
                'short' => 'Y/m/d',
                'medium' => 'Y年m月d日',
                'long' => 'Y年m月d日',
                'full' => 'Y年m月d日 l',
            ],
            'fa' => [
                'short' => 'Y/m/d',
                'medium' => 'Y/m/d',
                'long' => 'Y/m/d',
                'full' => 'l Y/m/d',
            ],
        ];
        
        $formatPattern = $formats[$language][$format] ?? $formats['en'][$format];
        return $date->format($formatPattern);
    }
    
    /**
     * Format a date with time according to current language
     * 
     * @param \Carbon\Carbon|string $dateTime DateTime to format
     * @return string Formatted date and time
     */
    public static function formatDateTime($dateTime): string
    {
        if (!$dateTime) {
            return '';
        }
        
        if (is_string($dateTime)) {
            $dateTime = \Carbon\Carbon::parse($dateTime);
        }
        
        $language = self::getCurrentLanguage();
        
        $formats = [
            'en' => 'M d, Y H:i',
            'zh' => 'Y年m月d日 H:i',
            'fa' => 'Y/m/d H:i',
        ];
        
        $formatPattern = $formats[$language] ?? $formats['en'];
        return $dateTime->format($formatPattern);
    }
    
    /**
     * Format currency amount according to language
     * 
     * @param float $amount Amount to format
     * @param string $currency Currency code (CAD, USD, etc.)
     * @return string Formatted currency
     */
    public static function formatCurrency(float $amount, string $currency = 'CAD'): string
    {
        $language = self::getCurrentLanguage();
        
        $symbols = [
            'CAD' => '$',
            'USD' => '$',
            'EUR' => '€',
            'GBP' => '£',
        ];
        
        $symbol = $symbols[$currency] ?? '$';
        
        // Different formatting for different languages
        return match($language) {
            'zh' => $symbol . number_format($amount, 2),
            'fa' => number_format($amount, 2) . ' ' . $symbol,
            default => $symbol . number_format($amount, 2),
        };
    }
    
    /**
     * Set the application language for the current session
     * 
     * @param string $languageCode Language code to set
     * @return bool True if language was set successfully
     */
    public static function setLanguage(string $languageCode): bool
    {
        if (!self::isLanguageSupported($languageCode)) {
            return false;
        }
        
        session(['locale' => $languageCode]);
        app()->setLocale($languageCode);
        
        return true;
    }
    
    /**
     * Get translation for common insurance terms
     * 
     * @param string $term Term to translate
     * @return string Translated term
     */
    public static function translateTerm(string $term): string
    {
        $language = self::getCurrentLanguage();
        
        $terms = [
            'insurance_cover' => [
                'en' => 'Insurance Coverage',
                'zh' => '保险覆盖',
                'fa' => 'پوشش بیمه',
            ],
            'premium' => [
                'en' => 'Premium',
                'zh' => '保费',
                'fa' => 'حق بیمه',
            ],
            'deductible' => [
                'en' => 'Deductible',
                'zh' => '免赔额',
                'fa' => 'کسر فرانشیز',
            ],
            'coverage' => [
                'en' => 'Coverage',
                'zh' => '覆盖范围',
                'fa' => 'پوشش',
            ],
            'policy' => [
                'en' => 'Policy',
                'zh' => '保单',
                'fa' => 'پلیسی',
            ],
            'beneficiary' => [
                'en' => 'Beneficiary',
                'zh' => '受益人',
                'fa' => 'ذینفع',
            ],
        ];
        
        return $terms[$term][$language] ?? $term;
    }
    
    /**
     * Get the appropriate greeting based on time of day and language
     * 
     * @return string Greeting in current language
     */
    public static function getGreeting(): string
    {
        $hour = now()->hour;
        $language = self::getCurrentLanguage();
        
        if ($hour < 12) {
            return match($language) {
                'zh' => '早上好',
                'fa' => 'صبح بخیر',
                default => 'Good morning',
            };
        } elseif ($hour < 18) {
            return match($language) {
                'zh' => '下午好',
                'fa' => 'عصر بخیر',
                default => 'Good afternoon',
            };
        } else {
            return match($language) {
                'zh' => '晚上好',
                'fa' => 'شب بخیر',
                default => 'Good evening',
            };
        }
    }
}