using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;

public class FairyDialogueManager
{
    private ChatWindowController _chatWindow;
    private string _dialogueFileName;
    
    private GamePhase _currentGamePhase = GamePhase.Intro; // 현재 게임 단계
    
    private DialogueData _database;
    private Dictionary<string, DialogueStruct> _dialogueDict;
    private Dictionary<string, List<DialogueStruct>> _phaseDialogues;
    
    // 이미 보여준 게임플레이 대화 추적
    private HashSet<string> _shownGameplayDialogueIds;

    private string _fairyName = "냉장고 요정";
    
    public FairyDialogueManager(ChatWindowController chatWindow, string dialogueFileName = "dialogue.json")
    {
        _chatWindow = chatWindow;
        _dialogueFileName = dialogueFileName;
        _shownGameplayDialogueIds = new HashSet<string>();
        
        LoadDialogueData();
        OrganizeDialogues();
    }
    
    // 대화 데이터베이스 로드
    private void LoadDialogueData()
    {
        string filePath = "Dialogues/" + _dialogueFileName.Replace(".json", "");
        TextAsset jsonFile = Resources.Load<TextAsset>(filePath);
        
        if (jsonFile == null)
        {
            Debug.LogError($"경로 오류로 인한 대화 데이터 로딩 실패 : {filePath}");
            _database = new DialogueData { dialogues = new List<DialogueStruct>() };
            return;
        }
        
        try {
            _database = JsonUtility.FromJson<DialogueData>(jsonFile.text);
            
            _dialogueDict = new Dictionary<string, DialogueStruct>(); // 대화 사전 초기화
            foreach (DialogueStruct entry in _database.dialogues)
            {
                _dialogueDict[entry.id] = entry;
            }
        }
        catch (Exception e) {
            Debug.LogError($"JSON 파싱 오류: {e.Message}");
            _database = new DialogueData { dialogues = new List<DialogueStruct>() };
        }
    }
    
    // 대화를 단계별로 분류
    private void OrganizeDialogues()
    {
        _phaseDialogues = new Dictionary<string, List<DialogueStruct>>();
        
        foreach (DialogueStruct entry in _database.dialogues)
        {
            // 단계별 분류
            if (!_phaseDialogues.ContainsKey(entry.phase))
            {
                _phaseDialogues[entry.phase] = new List<DialogueStruct>();
            }
            _phaseDialogues[entry.phase].Add(entry);
        }
    }
    
    // 게임 단계 설정, GamePlay는 따로 실행
    public void SetGamePhase(GamePhase phase)
    {
        _currentGamePhase = phase;
        
        if (phase == GamePhase.Intro)
        {
            StartPhaseDialogue("intro");
        }
        else if (phase == GamePhase.End)
        {
            StartPhaseDialogue("end");
        }
    }
    
    // 단계별 시작 대화 찾기 및 시작
    private void StartPhaseDialogue(string phaseName)
    {
        if (!_phaseDialogues.ContainsKey(phaseName) || _phaseDialogues[phaseName].Count == 0)
        {
            Debug.LogWarning($"No dialogues found for phase: {phaseName}");
            return;
        }
        
        // 첫 대화 찾기 (요정이 먼저 말함)
        DialogueStruct startEntry = _phaseDialogues[phaseName]
            .FirstOrDefault(d => d.name == _fairyName && !string.IsNullOrEmpty(d.nextId));
        
        if (startEntry == null)
        {
            startEntry = _phaseDialogues[phaseName][0];
        }
        
        // 대화 시퀀스 시작
        StartDialogueSequence(startEntry.id);
    }
    
    // Gameplay일 때 랜덤 대화 출력
    public void ShowRandomGameplayDialogue()
    {
        if (_currentGamePhase != GamePhase.Gameplay) return;
        
        // 요정 대화 중 아직 보여주지 않은 것 찾기
        var availableDialogues = _phaseDialogues["gameplay"]
            .Where(d => d.name == _fairyName && !_shownGameplayDialogueIds.Contains(d.id))
            .ToList();
        
        // 모든 대화를 다 보여줬다면 다시 초기화
        if (availableDialogues.Count == 0)
        {
            _shownGameplayDialogueIds.Clear();
            availableDialogues = _phaseDialogues["gameplay"]
                .Where(d => d.name == _fairyName)
                .ToList();
        }
        
        // 랜덤 대화 선택
        if (availableDialogues.Count > 0)
        {
            int randomIndex = Random.Range(0, availableDialogues.Count);
            DialogueStruct randomDialogue = availableDialogues[randomIndex];
            
            // 보여준 대화 기록
            _shownGameplayDialogueIds.Add(randomDialogue.id);
            
            // 대화 시퀀스 시작
            StartDialogueSequence(randomDialogue.id);
        }
    }
    
    // 대화 ID로 대화 시작
    public void StartDialogueSequence(string startDialogueId)
    {
        if (!_dialogueDict.ContainsKey(startDialogueId)) return;
        
        DialogueStruct startEntry = _dialogueDict[startDialogueId]; // 시작 대화
        
        List<DialogueStruct> sequence = BuildDialogueSequence(startEntry); // 대화 시퀀스 구성
        
        // 대화창에 대화 시퀀스 전달
        _chatWindow.SetDialogueSequence(sequence);
        _chatWindow.ShowWindow();
    }
    
    // 연결된 대화 시퀀스 구성
    private List<DialogueStruct> BuildDialogueSequence(DialogueStruct startEntry)
    {
        List<DialogueStruct> sequence = new List<DialogueStruct>();
        HashSet<string> visitedIds = new HashSet<string>(); // 순환 참조 방지
        
        DialogueStruct currentEntry = startEntry;
        while (currentEntry != null && !visitedIds.Contains(currentEntry.id))
        {
            sequence.Add(currentEntry);
            visitedIds.Add(currentEntry.id);
            
            // 다음 대화가 없으면 종료
            if (string.IsNullOrEmpty(currentEntry.nextId) || 
                !_dialogueDict.ContainsKey(currentEntry.nextId))
            {
                break;
            }
            
            // 다음 대화로 이동
            currentEntry = _dialogueDict[currentEntry.nextId];
        }
        
        return sequence;
    }
    
    // 특정 대화 ID로 대화 시작 (세이브/로드 시 사용)
    public void StartDialogueById(string dialogueId)
    {
        if (_dialogueDict.ContainsKey(dialogueId))
        {
            StartDialogueSequence(dialogueId);
        }
        else
        {
            Debug.LogError($"Dialogue ID not found: {dialogueId}");
        }
    }
}