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

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

// CharacterCreateUI는 캐릭터 생성을 담당하는 UI입니다.
public class CharacterCreateUI : MonoBehaviour {
    [SerializeField] private CharacterSelectUI characterSelectUI;
    [SerializeField] private Image characterImage;
    
    [SerializeField] private TMP_InputField nicknameInputField;
    [SerializeField] private Button[] shapeButtons;
    [SerializeField] private TMP_Text shapeText;
    [SerializeField] private Button[] colorButtons;
    [SerializeField] private Image colorImage;
    [SerializeField] private Button[] jobButtons;
    [SerializeField] private TMP_Text jobText;
    
    [SerializeField] private Button createButton;
    [SerializeField] private Button backButton;

    private int currentShape = 0;
    private int currentColor = 0;
    private int currentJob = 0;
    
    List<string> shapeList;
    List<string> colorList;
    List<string> jobList;

    // 캐릭터 생성 UI를 활성화하는 함수
    public void OpenUI() {
        Reset();
        gameObject.SetActive(true);
    }
    
    // 캐릭터 생성 UI와 동일하지만 게임정보만 생성하는 UI를 생성하는 함수
    public void OpenUIByInsert(Action afterInsert) {
        OpenUI();
        
        nicknameInputField.interactable = false;
        nicknameInputField.text = Backend.UserNickName;
        createButton.onClick.RemoveAllListeners();
        createButton.onClick.AddListener(() => {
            UserData userData = new UserData();
            userData.color = colorList[currentColor];
            userData.shape = shapeList[currentShape];
            userData.jobClass = jobList[currentJob];
            
            LoadingUI.Instance.OpenUI();
            BackendManager.Instance.InsertData(userData, ( success,  message) => {
                LoadingUI.Instance.CloseUI();

                if (success) {
                    AlertUI.Instance.Alert("데이터 생성 성공", "데이터 생성이 완료되었습니다.\n게임을 시작합니다.", afterInsert);
                    // 방법 1: 데이터 생성이 완료된 이후, 다시 캐릭터 선택으로 가서 데이터를 불러오는 방법
                    // 방법 2: 데이터 생성 후, 바로 캐싱된 데이터를 사용하는 방법
                    // 방법 1은 함수 호출이 한번 더 이루어지므로, 방법 2로 선택. 다만 안전성은 방법 1이 우위.
                    BackendManager.Instance.currentUserData = userData;
                } else {
                    AlertUI.Instance.Alert("데이터 생성 실패", message);
                }
            });
        });
    }
    
    private void Reset() {
        
        // 기본 커스텀 마이징 리스트
        shapeList = new List<string>() {"circle", "square", "triangle"};
        colorList = new List<string>() {"Red", "Green", "Blue"};
        jobList = new List<string>() {"Warrior", "Magician", "Archer"};
        
        // 현재 선택한 커스텀 마이징 종류
        currentShape = 0;
        currentColor = 0;
        currentJob = 0;

        // 닉네임 입력 필드 초기화
        // OpenUIByInsert일 경우, 닉네임이 false가 되기 때문에 초기화 필요
        nicknameInputField.interactable = true;
        nicknameInputField.text = string.Empty;
        
        // 버튼 모두 초기화
        shapeButtons[0].onClick.RemoveAllListeners();
        shapeButtons[0].onClick.AddListener(() => SelectShape(false));
        shapeButtons[1].onClick.RemoveAllListeners();
        shapeButtons[1].onClick.AddListener(() => SelectShape(true));
        
        colorButtons[0].onClick.RemoveAllListeners();
        colorButtons[0].onClick.AddListener(() => SelectColor(false));
        colorButtons[1].onClick.RemoveAllListeners();
        colorButtons[1].onClick.AddListener(() => SelectColor(true));
        
        jobButtons[0].onClick.RemoveAllListeners();
        jobButtons[0].onClick.AddListener(() => SelectJob(false));
        jobButtons[1].onClick.RemoveAllListeners();
        jobButtons[1].onClick.AddListener(() => SelectJob(true));

        // 생성 버튼 클릭시 커스텀마이징한 UserData 생성
        createButton.onClick.RemoveAllListeners();
        createButton.onClick.AddListener(() => {
            UserData userData = new UserData();
            userData.color = colorList[currentColor];
            userData.shape = shapeList[currentShape];
            userData.jobClass = jobList[currentJob];
            
            // 게임오브젝트 리스트 관리를 SelectUI에서 진행하므로, 해당 스크립트에서 캐릭터만들고 캐싱으로 오브젝트 추가
            characterSelectUI.CreateCharacter(nicknameInputField.text, userData);
            CloseUI();
            
        });
        
        backButton.onClick.RemoveAllListeners();
        backButton.onClick.AddListener(CloseUI);
        
        
        // 해당 버튼을 클릭한 결과로 UI 기본값 초기화
        shapeButtons[0].onClick.Invoke();
        colorButtons[0].onClick.Invoke();
        jobButtons[0].onClick.Invoke();
    }
    
    public void CloseUI() {
        gameObject.SetActive(false);
    }

    // 모양을 변경하는 함수
    private void SelectShape(bool isNext) {
        if (isNext) {
            currentShape++;

            if (shapeList.Count <= currentShape) {
                currentShape = 0;
            }
        } else {
            currentShape--;
            
            if (currentShape < 0) {
                currentShape = shapeList.Count - 1;
            }
        }
        
        shapeText.text = shapeList[currentShape];
        characterImage.sprite = SpriteManager.GetImage(shapeList[currentShape]);
    }
    
    // 색상을 변경하는 함수
    private void SelectColor(bool isNext) {
        if (isNext) {
            currentColor++;

            if (colorList.Count <= currentColor) {
                currentColor = 0;
            }
        } else {
            currentColor--;
            
            if (currentColor < 0) {
                currentColor = colorList.Count - 1;
            }
        }

        switch (colorList[currentColor]) {
            case "Red":
                colorImage.color = Color.red;
                break;
            case "Green":
                colorImage.color = Color.green;
                break;
            case "Blue":
                colorImage.color = Color.blue;
                break;
            default:
                colorImage.color = Color.white;
                Debug.LogError("해당 컬러는 존재하지 않습니다 : " + colorList[currentColor]);
                break;
        }

        characterImage.color = colorImage.color;
    }
    
    // 직업을 변경하는 함수
    private void SelectJob(bool isNext) {
        if (isNext) {
            currentJob++;

            if (jobList.Count <= currentJob) {
                currentJob = 0;
            }
        } else {
            currentJob--;
            
            if (currentJob < 0) {
                currentJob = jobList.Count - 1;
            }
        }
        
        jobText.text = jobList[currentJob];
    }
}
