// Copyright 2013-2023, AFI.Inc. All rights reserved.

using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

using UnityEngine.SceneManagement;

// CharacterSelectUI는 CharacterSelectScene에서 캐릭터 선택 화면을 관리하는 클래스입니다.
public class CharacterSelectUI : MonoBehaviour {

    [SerializeField] private CharacterCreateUI characterCreateUI;

    [SerializeField] private GameObject characterObject;
    [SerializeField] private Transform characterObjectParent;

    [SerializeField] private TMP_Text titleText;
    const string _titleTextFormat = "캐릭터를 선택해주세요 ({0}/20)";
    
    [SerializeField] private Button createCharacterButton;
    [SerializeField] private Button deleteCharacterButton;
    [SerializeField] private Button logoutAccountButton;
    [SerializeField] private Button withdrawAccountButton;
    [SerializeField] private Button gameStartButton;

    [SerializeField] private TMP_Text statText;
    
    
    private List<GameObject> _gameObjectList = new List<GameObject>();

    private int selectedCharacterIndex = -1;

    void Start() {
        try {
            createCharacterButton.onClick.RemoveAllListeners();
            createCharacterButton.onClick.AddListener(characterCreateUI.OpenUI);
        
            deleteCharacterButton.onClick.RemoveAllListeners();
            deleteCharacterButton.onClick.AddListener(DeleteCharacter);
        
            logoutAccountButton.onClick.RemoveAllListeners();
            logoutAccountButton.onClick.AddListener(LogoutAccount);
        
            withdrawAccountButton.onClick.RemoveAllListeners();
            withdrawAccountButton.onClick.AddListener(WithdrawAccount);
        
            gameStartButton.onClick.RemoveAllListeners();
            gameStartButton.onClick.AddListener(GameStart);
        
            LoadingUI.Instance.OpenUI();
            // 캐릭터 미선택은 -1로 지정합니다.
            selectedCharacterIndex = -1;
        
            while (_gameObjectList.Count > 0) {
                Destroy(_gameObjectList[0]);
                _gameObjectList.RemoveAt(0);
            }
        
            _gameObjectList.Clear();
        
            LoadingUI.Instance.OpenUI();
            
            // 뒤끝 함수로 데이터 호출. 응답이 올때까지 loadingUI를 띄웁니다.
            // BackendManager에 profileList가 모두 차면 Reset 함수에 있는 데이터 정렬을 통해 화면에 표시합니다.
            BackendManager.Instance.GetCharacterList((success, message) => {
                LoadingUI.Instance.CloseUI();

                if (success == false) {
                    AlertUI.Instance.Alert("불러오기 오류", message);
                    return;
                }
            
                Reset();
            });
        } catch (Exception e) {
            Debug.LogError(e);
            AlertUI.Instance.Alert("오류", $"오류가 발생했습니다.\n{e.Message}");
        }
    }

    // 캐릭터 버튼 클릭
    public void CreateCharacter(string nickname, UserData userData) {

        LoadingUI.Instance.OpenUI();
            
        BackendManager.Instance.CreateCharacter(nickname, userData, ( success,  message) => {
            LoadingUI.Instance.CloseUI();
            if (success) {
                AlertUI.Instance.Alert("캐릭터 생성 완료", "캐릭터 생성에 성공했습니다.");
            } else {
                AlertUI.Instance.Alert("캐릭터 생성 실패", message);
            }
            Reset();
        });
    }

    // 현재 지정중인 캐릭터 선택
    public void SelectCharacter(int index) {
        selectedCharacterIndex = index;

        var characterProfile = _gameObjectList[index].GetComponent<CharacterProfileObject>();
        statText.text = characterProfile.profile.GetStats();
    }

    // 게임 시작 버튼
    public void GameStart() {
        LoadingUI.Instance.OpenUI();
        
        // 캐릭터 선택 함수 호출
        BackendManager.Instance.SelectCharacter(selectedCharacterIndex, ( success,  message) => {
            LoadingUI.Instance.CloseUI();

            if (success == false) {
                AlertUI.Instance.Alert("캐릭터 선택 실패", message);
                return;
            }
            
            // 게임정보 불러오기 함수 호출
            BackendManager.Instance.GetUserData((success2, message2) => {
                if (success2 == false) {
                    AlertUI.Instance.Alert("불러오기 오류", message2);
                    return;
                }
                
                // 아무런 에러가 없으면 바로 데이터가 이미 존재하는 것으로 판단하여 바로 게임 시작
                if (string.IsNullOrEmpty(message2)) {
                    SceneManager.LoadScene("InGameScene");
                } else {
                    // 결과는 성공인데 무언가 메세지가 있으면, 캐릭터 생성에는 성공했지만 데이터가 없는 것으로 판단되어 데이터 생성창으로 이동
                    AlertUI.Instance.Alert("불러오기 오류", "데이터가 존재하지 않습니다.", () => {
                        characterCreateUI.OpenUIByInsert(() => {
                            SceneManager.LoadScene("InGameScene");
                        });
                    });
                }
            });
        });
    }
    
    
    // 캐릭터 삭제
    private void DeleteCharacter() {
        LoadingUI.Instance.OpenUI();
            
        BackendManager.Instance.DeleteCharacter(selectedCharacterIndex, ( success,  message) => {
            LoadingUI.Instance.CloseUI();
            
            if (success) {
                Reset();

                AlertUI.Instance.Alert("캐릭터 삭제 성공", "캐릭터가 삭제되었습니다.");
            } else {
                AlertUI.Instance.Alert("캐릭터 삭제 실패", message);
            }

        });
    }

    // 계정 로그아웃
    private void LogoutAccount() {
        LoadingUI.Instance.OpenUI();

        BackendManager.Instance.LogoutAccount((success, message) => {
            LoadingUI.Instance.CloseUI();

            Reset();
            CloseUI();
            
            if (success) {
                AlertUI.Instance.Alert("로그아웃 성공", "로그아웃되었습니다.",() => SceneManager.LoadScene("LoginScene"));
            } else {
                AlertUI.Instance.Alert("로그아웃 실패", message);
            }
        });
    }
    
    // 계정 탈퇴
    private void WithdrawAccount() {
        LoadingUI.Instance.OpenUI();
        
        BackendManager.Instance.WithdrawAccount(( success,  message) => {
            LoadingUI.Instance.CloseUI();

            Reset();
            CloseUI();
            
            if (success) {
                AlertUI.Instance.Alert("회원 탈퇴 성공", "회원 탈퇴되었습니다.", () => SceneManager.LoadScene("LoginScene"));
            } else {
                AlertUI.Instance.Alert("회원 탈퇴 실패", message);
            }
        });
    }
    
    // UI 리셋
    private void Reset() {
        var profileList =  BackendManager.Instance.profileList;
        
        // BackendManager에 존재하는 profileList만큼 gameObject의 갯수를 맞춤(만약 서버에서 캐릭터가 삭제되었을 경우)
        // 기본적인 상황이라면 로직이 작동하지 않음.
        while (_gameObjectList.Count > profileList.Count) {
            Destroy(_gameObjectList[0]);
            _gameObjectList.RemoveAt(0);
        }

        // 캐릭터 프로필 오브젝트가 부족하면 생성
        for (int i  = _gameObjectList.Count; i <  profileList.Count; i++) {
            var obj = Instantiate(characterObject, transform, true);
            obj.transform.localScale = new Vector3(1, 1, 1);
            obj.transform.SetParent(characterObjectParent);
            _gameObjectList.Add(obj);
        }
        
        // 캐릭터 프로필 오브젝트에 프로필 정보를 넣어줌
        for (int i = 0; i <  BackendManager.Instance.profileList.Count; i++) {
            _gameObjectList[i].GetComponent<CharacterProfileObject>().SetProfile(this,  profileList[i],i);
        }
        
        
        titleText.text = string.Format(_titleTextFormat, profileList.Count);
        statText.text = "캐릭터를 선택하세요";
    }

    private void CloseUI() {
        gameObject.SetActive(false);
    }
}
