<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;

class SetLanguage
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // Decide requested language.
        // On community pages: prefer per-community session language, then community default,
        // then global language (cookie/session/user pref). This ensures each community
        // can have its own default until the user changes it intentionally.
        $visitingCommunity = 0;
        try {
            $visitingCommunity = (int) (function_exists('getVisitingCommunityId') ? getVisitingCommunityId() : 0);
        } catch (\Throwable $e) {
            $visitingCommunity = 0;
        }

        if ($visitingCommunity > 0) {
            $language = $this->getCommunityLanguage($visitingCommunity);
        } else {
            $language = $this->getLanguage();
        }
        
        // Set the application locale
        app()->setLocale($language);
        
        // Ensure session has the language value
        if (!Session::has('lang') || Session::get('lang') !== $language) {
            Session::put('lang', $language);
        }

        $response = $next($request);

        return $response;
    }

    private function getCommunityLanguage(int $communityId): string
    {
        $communityKey = 'lang_c_' . $communityId;

        // Requirement: before login, community language should be English only.
        // Default language (is_default) is applied after login only.
        if (!Auth::check()) {
            return 'en';
        }

        $language = null;
        try {
            $language = Session::get($communityKey);
        } catch (\Throwable $e) {
            $language = null;
        }

        // If session key is missing (e.g. host/session variations), fall back to cookie.
        if (!is_string($language) || $language === '') {
            try {
                $cookieLang = request()->cookie($communityKey);
                if (is_string($cookieLang) && $cookieLang !== '') {
                    $language = $cookieLang;
                    Session::put($communityKey, $language);
                }
            } catch (\Throwable $e) {
                // ignore
            }
        }

        if (!is_string($language) || $language === '') {
            try {
                $defaultVar = app('App\\Repositories\\CommunityLanguagesRepository')->getDefaultVarActive($communityId);
                if (is_string($defaultVar) && $defaultVar !== '') {
                    $language = $defaultVar;
                    Session::put($communityKey, $language);
                }
            } catch (\Throwable $e) {
                // ignore
            }
        }

        if (!is_string($language) || $language === '') {
            // If no community default is set, use English by default for that community.
            $language = 'en';
            Session::put($communityKey, $language);
        }

        $language = is_string($language) ? strtolower($language) : 'en';

        // Ensure the language is activated for the community.
        if ($language !== 'en') {
            try {
                $active = app('App\\Repositories\\CommunityLanguagesRepository')->findByVarActive($language, $communityId);
                if (! $active) {
                    $fallback = app('App\\Repositories\\CommunityLanguagesRepository')->getDefaultVarActive($communityId) ?: 'en';
                    $language = is_string($fallback) && $fallback !== '' ? strtolower($fallback) : 'en';
                    Session::put($communityKey, $language);
                }
            } catch (\Throwable $e) {
                $language = 'en';
                Session::put($communityKey, $language);
            }
        }

        return $language ?: 'en';
    }
    
    /**
     * Get the current language from various sources
     */
    private function getLanguage()
    {
        // Priority order: Cookie -> Session -> User Preference -> Default
        // NOTE: Do NOT use a global cache key for language selection; it leaks across users.

        // 0. Check explicit language cookie (useful across subdomains / session issues)
        try {
            $cookieLang = request()->cookie('lang');
            if (is_string($cookieLang) && $cookieLang !== '') {
                Session::put('lang', $cookieLang);
                return $cookieLang;
            }
        } catch (\Throwable $e) {
            // ignore
        }
        
        // 1. Check session
        if (Session::has('lang') && Session::get('lang')) {
            return Session::get('lang');
        }

        // 2. Check authenticated user preference
        if (Auth::check() && Auth::user()->lang) {
            $lang = Auth::user()->lang;
            Session::put('lang', $lang);
            return $lang;
        }
        
        // 3. Default to English
        $defaultLang = 'en';
        Session::put('lang', $defaultLang);
        return $defaultLang;
    }
}
