<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Language;
use App\Models\LanguagePhrase;
use App\Services\LanguageService;
use App\Services\TranslationScanner;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Laracasts\Flash\Flash;

class AdminLanguageController extends Controller
{

    protected $data = [];
    protected $langService = [];

    public function __construct(LanguageService $languageService)
    {
        $this->langService = $languageService;

        $this->data['title'] = 'Languages';
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function index()
    {
        $this->data['languages'] = $this->langService->getAllLanguages();

        return view('admin.language.index', $this->data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $this->data['title'] = 'Add new Language';

        return view('admin.language.create', $this->data);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @return void
     * @throws \Exception
     */
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'locale' => 'required|unique:languages,locale'
        ]);

        $lang = $this->langService->create($request->all());
        
        // Auto-populate new language with phrases from default language
        $this->populateNewLanguage($lang);

        Flash::success('Language created successfully and phrases populated from default language. You can now translate them.');

        return redirect()->route('ch-admin.language.edit', [$lang->id]);
    }
    
    /**
     * Populate a newly created language with phrases from the default language
     * 
     * @param Language $language
     */
    private function populateNewLanguage($language)
    {
        // Get default language
        $defaultLanguage = Language::where('default', 1)->first();
        
        if (!$defaultLanguage) {
            return; // No default language, can't populate
        }
        
        // Get active theme namespace
        $activeNamespace = setting('site_theme', 'default');
        
        // Replicate phrases from default language to new language
        $languageService = new LanguageService($defaultLanguage, new LanguagePhrase());
        $languageService->replicatePhrases($language->id, $activeNamespace);
    }

    /**
     * Display the specified resource.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }


    /**
     * Display the specified resource.
     *
     * @param int $id
     * @return void
     * @throws \Exception
     */
    public function phrases($id, $active_group = 'general')
    {
        $this->data['language'] = $this->langService->find($id);

        $this->data['title'] = 'Edit Phrases for ' . $this->data['language']->name;

        $this->data['active_group'] = $active_group;

        // Get active theme namespace
        $activeNamespace = setting('site_theme', 'default');
        
        // Get phrases filtered by active theme
        $phrases = $this->langService->getPhrasesByLang($id, $activeNamespace);

        $this->data['phrases'] = $phrases->where('group', $active_group);

        $groups = $phrases->groupBy('group')->keys()->mapWithKeys(function ($row) {
            if ($row == '*') {
                return [$row => 'General'];
            }

            return [$row => ucfirst(str_replace('_', ' ', $row))];
        })->toArray();

        unset($groups['general']);
        $this->data['groups'] = ['general' => 'General'] + $groups;
        
        // Add active theme info to view
        $this->data['active_namespace'] = $activeNamespace;

        return view('admin.language.phrases', $this->data);
    }


    public function phrasesUpdate(Request $request, $lang_id, $group)
    {
        try {
            // Get active theme namespace
            $activeNamespace = function_exists('setting') ? setting('site_theme', 'default') : 'default';
            
            $languageService = new LanguageService(Language::find($lang_id), new LanguagePhrase());
            $languageService->updateTranslations($group, $request->input('phrases'), $activeNamespace);
        } catch (\Exception $exception) {
            Flash::error('Error: ' . $exception->getMessage());

            return redirect()->back();
        }

        Flash::success('Phrases updated successfully.');

        return redirect()->back();
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function edit($id)
    {
        $this->data['title'] = 'Edit Language';

        $this->data['language'] = $this->langService->find($id);

        return view('admin.language.edit', $this->data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $id
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function update(Request $request, $id)
    {
        $request->validate([
            'name' => 'required_without_all:enabled,default',
            'locale' => 'required_without_all:enabled,default|unique:languages,locale,' . $id,
        ]);

        $this->langService->update($request->all(), $id);;

        Flash::success('Language updated successfully.');

        if ($request->has('enabled') || $request->has('default')) {
            return redirect()->route('ch-admin.language.index');
        } else {
            return redirect()->route('ch-admin.language.edit', [$id]);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return void
     * @throws \Exception
     */
    public function destroy($id)
    {
        $this->langService->delete($id);

        Flash::success('Language deleted successfully.');

        return redirect()->route('ch-admin.language.index');
    }

    public function sync(): RedirectResponse
    {
        $scanner = app()->make(TranslationScanner::class);

        $missingData = $scanner->getMissingTranslationsFromDB();
        $allMatches = $scanner->findTranslations();

        $languages = Language::all();

        foreach ($languages as $language) {
            // LanguageService extends LanguageRepository, so pass Language and LanguagePhrase models
            $languageService = new LanguageService($language, new LanguagePhrase());
            
            // Add missing translations (preserves existing user customizations)
            if (count($missingData)) {
                foreach ($missingData as $namespace => $groups) {
                    foreach ($groups as $group => $phrases) {
                        $languageService->updateTranslations($group, $phrases, $namespace);
                    }
                }
            }

            // Delete translations that no longer exist in files
            $keysToDelete = $scanner->getMissingTranslationsToDelete();
            foreach ($keysToDelete as $namespace => $groups) {
                foreach ($groups as $group => $phrases) {
                    $languageService->deletePhrasesByGroupKey($group, array_keys($phrases), $namespace);
                }
            }

            // NOTE: We do NOT overwrite existing translations here
            // This preserves user customizations made in the admin panel
            // If you need to reset a translation to its file value, delete it first, then sync
        }

        Flash::success('Phrases Synced successfully. New phrases added, removed phrases deleted, existing customizations preserved.');

        return redirect()->back();
    }

    /**
     * Reset active theme's translations to default values from files
     * Deletes all customizations for the active theme and re-syncs from files
     * 
     * @param int|null $lang_id If provided, resets only this language. Otherwise resets all languages.
     */
    public function resetToDefault($lang_id = null): RedirectResponse
    {
        // Get active theme namespace
        $activeNamespace = setting('site_theme', 'default');
        
        $deletedCount = 0;
        
        if ($lang_id) {
            // Reset specific language only
            $language = Language::findOrFail($lang_id);
            $deleted = $language->phrases()
                ->where('namespace', $activeNamespace)
                ->delete();
            
            $deletedCount = $deleted;
            Flash::success("Reset complete! {$deletedCount} phrases deleted for '{$language->name}' in theme '{$activeNamespace}'. Re-syncing from files...");
        } else {
            // Reset all languages
            $languages = Language::all();
            
            foreach ($languages as $language) {
                // Delete all phrases for active theme namespace
                $deleted = $language->phrases()
                    ->where('namespace', $activeNamespace)
                    ->delete();
                
                $deletedCount += $deleted;
            }
            
            Flash::success("Reset complete! {$deletedCount} phrases deleted for ALL LANGUAGES in theme '{$activeNamespace}'. Re-syncing from files...");
        }
        
        // Re-sync to add translations from files
        return $this->sync();
    }
    
    /**
     * Get count of phrases that will be deleted on reset
     * Used for confirmation dialogs
     * 
     * @param int|null $lang_id Optional language ID
     * @return \Illuminate\Http\JsonResponse
     */
    public function getResetPhraseCount($lang_id = null)
    {
        $activeNamespace = setting('site_theme', 'default');
        
        if ($lang_id) {
            // Count for specific language
            $language = Language::findOrFail($lang_id);
            $count = $language->phrases()
                ->where('namespace', $activeNamespace)
                ->count();
                
            return response()->json([
                'count' => $count,
                'language' => $language->name,
                'namespace' => $activeNamespace
            ]);
        } else {
            // Count for all languages
            $totalCount = 0;
            $languages = Language::all();
            $languageCounts = [];
            
            foreach ($languages as $language) {
                $count = $language->phrases()
                    ->where('namespace', $activeNamespace)
                    ->count();
                
                if ($count > 0) {
                    $languageCounts[] = "{$language->name}: {$count}";
                }
                $totalCount += $count;
            }
            
            return response()->json([
                'count' => $totalCount,
                'breakdown' => $languageCounts,
                'namespace' => $activeNamespace
            ]);
        }
    }
}
