<?php

namespace App\Helpers;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;

class TextDataHelper
{
    /**
     * Cache duration in minutes (24 hours)
     */
    protected static $cacheDuration = 1440;

    /**
     * Get localized name from textdata files
     *
     * @param string $nameStrId The NameStrID128 from database
     * @return string|null
     */
    public static function getItemName($nameStrId)
    {
        if (empty($nameStrId)) {
            return null;
        }

        // Get cached data or load from file
        $textData = self::getTextData();
        
        return $textData[$nameStrId] ?? null;
    }

    /**
     * Get localized description from textdata files
     *
     * @param string $descStrId The DescStrID128 from database
     * @return string|null
     */
    public static function getItemDescription($descStrId)
    {
        if (empty($descStrId)) {
            return null;
        }

        // Get cached data or load from file
        $textData = self::getTextData();
        
        return $textData[$descStrId] ?? null;
    }

    /**
     * Get all textdata entries (cached)
     *
     * @return array
     */
    protected static function getTextData()
    {
        $cacheKey = 'textdata_combined';
        
        return Cache::remember($cacheKey, self::$cacheDuration, function () {
            $allTextData = [];
            
            // Load both files
            $equipData = self::loadTextDataFile('textdata_equip&skill.txt');
            $objectData = self::loadTextDataFile('textdata_object.txt');
            
            // Combine both arrays
            $allTextData = array_merge($equipData, $objectData);
            
            Log::info('Loaded TextData: ' . count($allTextData) . ' total entries');
            
            return $allTextData;
        });
    }

    /**
     * Load and parse a textdata file
     * Format: 1\tSTRING_ID\tText
     *
     * @param string $fileName
     * @return array
     */
    protected static function loadTextDataFile($fileName)
    {
        $filePath = public_path("assets/textdata/{$fileName}");
        
        if (!File::exists($filePath)) {
            Log::warning("TextData file not found: {$filePath}");
            return [];
        }

        try {
            $content = File::get($filePath);
            $lines = explode("\n", $content);
            $textData = [];

            foreach ($lines as $lineNumber => $line) {
                $line = trim($line);
                
                // Skip empty lines and comments
                if (empty($line) || str_starts_with($line, '//')) {
                    continue;
                }

                // Parse line using fixed format: 1\tSTRING_ID\tText
                $parts = explode("\t", $line);
                
                if (count($parts) >= 3) {
                    $stringId = trim($parts[1]);
                    $text = trim($parts[2]);
                    
                    // Clean text to avoid encoding issues
                    $text = self::cleanText($text);
                    
                    if (!empty($stringId) && !empty($text)) {
                        $textData[$stringId] = $text;
                    }
                }
            }

            Log::info("Loaded {$fileName}: " . count($textData) . " entries");
            return $textData;

        } catch (\Exception $e) {
            Log::error("Error loading TextData file {$fileName}: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Clear all textdata cache
     *
     * @return void
     */
    public static function clearCache()
    {
        Cache::forget('textdata_combined');
        Log::info('TextData cache cleared');
    }

    /**
     * Clean text to avoid encoding issues
     */
    private static function cleanText(string $text): string
    {
        // Remove or replace invalid UTF-8 characters
        $text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
        
        // Remove control characters except tab and newline
        $text = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $text);
        
        // If text is still problematic, use a safe placeholder
        if (!mb_check_encoding($text, 'UTF-8')) {
            return 'Item';
        }
        
        // Return cleaned text or fallback
        return !empty($text) ? $text : 'Item';
    }

    /**
     * Preload textdata into cache
     *
     * @return array Summary of loaded data
     */
    public static function preloadCache()
    {
        self::clearCache();
        $data = self::getTextData();
        
        return [
            'total_entries' => count($data),
            'cached_at' => now()->toDateTimeString()
        ];
    }

    /**
     * Search for entries containing keyword
     *
     * @param string $keyword
     * @param int $limit
     * @return array
     */
    public static function searchEntries($keyword, $limit = 50)
    {
        $textData = self::getTextData();
        $results = [];
        $count = 0;

        foreach ($textData as $stringId => $text) {
            if ($count >= $limit) break;
            
            if (stripos($text, $keyword) !== false || stripos($stringId, $keyword) !== false) {
                $results[] = [
                    'string_id' => $stringId,
                    'text' => $text
                ];
                $count++;
            }
        }

        return $results;
    }

    /**
     * Get statistics about loaded textdata
     *
     * @return array
     */
    public static function getStats()
    {
        $textData = self::getTextData();
        
        $stats = [
            'total_entries' => count($textData),
            'item_entries' => 0,
            'skill_entries' => 0,
            'mob_entries' => 0,
            'npc_entries' => 0,
            'other_entries' => 0
        ];

        foreach (array_keys($textData) as $stringId) {
            if (str_contains($stringId, 'SN_ITEM_')) {
                $stats['item_entries']++;
            } elseif (str_contains($stringId, 'SN_SKILL_')) {
                $stats['skill_entries']++;
            } elseif (str_contains($stringId, 'SN_MOB_')) {
                $stats['mob_entries']++;
            } elseif (str_contains($stringId, 'SN_NPC_')) {
                $stats['npc_entries']++;
            } else {
                $stats['other_entries']++;
            }
        }

        return $stats;
    }
}
