﻿using System.IO;
using UnityEditor;
using UnityEngine;

namespace RKOKO.Config.Free.Editor
{
    public class PreferencesWindow : EditorWindow
    {
        private const string HEADER_PATH = "Assets/RKOKOConfigTableToolFree/Editor/Textures/header.png";

        private Texture2D _headerTexture;
        private Vector2 _scroll;

        [MenuItem("RKOKO Config Free/Preferences", true)]
        public static bool OpenValidate()
        {
            return ToolEditor.IsInstall();
        }

        [MenuItem("RKOKO Config Free/Preferences", priority = 201)]
        public static void Open()
        {
            var win = GetWindow<PreferencesWindow>();
            win.titleContent = new GUIContent(EditorLocalize.Get(1001));
            win.minSize = new Vector2(420, 560);
            win.Show();
        }

        private void OnEnable()
        {
            LoadTextures();
        }

        private void LoadTextures()
        {
            _headerTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(HEADER_PATH);
        }

        private void OnGUI()
        {
            if (_headerTexture == null)
            {
                LoadTextures();
            }

            var area = new Rect(0, 0, position.width, position.height);
            var center = area.center;
            area.width -= 16;
            area.height -= 16;
            area.center = center;
            var headerHeight = DrawHeader(area);
            area.y += headerHeight;
            area.height -= headerHeight;
            var topLinksArea = area;
            topLinksArea.height = 28;
            DrawTopLinks(topLinksArea);
            area.y += topLinksArea.height;
            area.height -= topLinksArea.height;
            GUILayout.BeginArea(area);
            _scroll = GUILayout.BeginScrollView(_scroll);
            GUILayout.Label(EditorLocalize.Get(1002));
            Preferences.Default.JsonLoadMode =
                (JsonLoadMode)EditorGUILayout.EnumPopup(Preferences.Default.JsonLoadMode);
            if (Preferences.Default.JsonLoadMode == JsonLoadMode.Custom)
            {
                GUILayout.Label(EditorLocalize.Get(1003));
                Preferences.Default.CustomJsonExportPath =
                    EditorGUILayout.TextField(Preferences.Default.CustomJsonExportPath, GUILayout.Height(44));
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button(EditorLocalize.Get(1018)))
                {
                    Preferences.Default.CustomJsonExportPath =
                        ToolEditor.ToUnityPath(Path.GetDirectoryName(Paths.RESOURCES_JSON_FILE_PATH));
                }

                if (GUILayout.Button(EditorLocalize.Get(1004)))
                {
                    var path = EditorUtility.OpenFolderPanel(EditorLocalize.Get(1016), Application.dataPath, "");
                    if (IsPathInsideAssets(path))
                    {
                        Preferences.Default.CustomJsonExportPath = ToolEditor.ToUnityPath(path);
                    }
                    else
                    {
                        if (path.Length > 0)
                        {
                            ToolEditor.ShowMessageBox(EditorLocalize.Get(1014));
                        }
                    }
                }

                GUILayout.EndHorizontal();
            }

            GUILayout.Space(16);
            GUILayout.Label(EditorLocalize.Get(1005));
            Preferences.Default.CSharpExportMode =
                (CSharpExportMode)EditorGUILayout.EnumPopup(Preferences.Default.CSharpExportMode);
            if (Preferences.Default.CSharpExportMode == CSharpExportMode.Custom)
            {
                Preferences.Default.CustomCsharpExportPath =
                    EditorGUILayout.TextField(Preferences.Default.CustomCsharpExportPath, GUILayout.Height(44));
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button(EditorLocalize.Get(1018)))
                {
                    Preferences.Default.CustomCsharpExportPath = Paths.DEFAULT_CSHARP_EXPORT_PATH;
                }

                if (GUILayout.Button(EditorLocalize.Get(1004)))
                {
                    var path = EditorUtility.OpenFolderPanel(EditorLocalize.Get(1013), Application.dataPath, "");
                    if (IsPathInsideAssets(path))
                    {
                        Preferences.Default.CustomCsharpExportPath = ToolEditor.ToUnityPath(path);
                    }
                    else
                    {
                        if (path.Length > 0)
                        {
                            ToolEditor.ShowMessageBox(EditorLocalize.Get(1014));
                        }
                    }
                }

                GUILayout.EndHorizontal();
            }

            GUILayout.Space(16);
            Preferences.Default.EncryptJson =
                GUILayout.Toggle(Preferences.Default.EncryptJson, EditorLocalize.Get(1028));
            if (Preferences.Default.EncryptJson)
            {
                GUILayout.Label(EditorLocalize.Get(1030));
                Preferences.Default.JsonEncryptKey =
                    EditorGUILayout.TextField(Preferences.Default.JsonEncryptKey);
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button(EditorLocalize.Get(1029)))
                {
                    Preferences.Default.JsonEncryptKey = RkokoAesUtility.GenerateRandomKey();
                }

                GUILayout.EndHorizontal();
            }

            GUILayout.Space(16);
            Preferences.Default.BackUp =
                GUILayout.Toggle(Preferences.Default.BackUp, EditorLocalize.Get(1033));
            if (Preferences.Default.BackUp)
            {
                GUILayout.Label(EditorLocalize.GetFormat(1034, Paths.BACK_UP_FOLDER, Env.MAX_BACK_UP_COUNT.ToString()));
            }

            GUILayout.Space(16);
            GUILayout.Label(EditorLocalize.Get(1011));
            if (GUILayout.Button(EditorLocalize.GetDisplayName(), "popup"))
            {
                var current = EditorLocalize.GetLanguageType();
                var menu = new GenericMenu();
                foreach (var pair in EditorLocalize.DisplayNames)
                {
                    var languageType = pair.Key;
                    var display = pair.Value;
                    var selected = current == languageType;
                    menu.AddItem(new GUIContent(display), selected,
                        () =>
                        {
                            EditorLocalize.ChangeLanguage(languageType);
                            titleContent = new GUIContent(EditorLocalize.Get(1001));
                        });
                }

                menu.ShowAsContext();
            }

            GUILayout.Space(16);
            if (GUILayout.Button(EditorLocalize.Get(1006), GUILayout.Height(32)))
            {
                SaveAndApply();
            }

            GUILayout.EndScrollView();
            GUILayout.EndArea();
        }

        private float DrawHeader(Rect area)
        {
            const float headerAreaHeight = 100;
            const float topPadding = 0f;
            const float maxHeaderWidth = 430f;
            const float maxDrawHeight = 86;
            if (_headerTexture == null)
            {
                return 0;
            }

            float textureWidth = _headerTexture.width;
            float textureHeight = _headerTexture.height;
            if (textureWidth <= 0f || textureHeight <= 0f)
            {
                return 0f;
            }

            float availableWidth = Mathf.Max(100f, area.width - 24f);
            float drawWidth = Mathf.Min(availableWidth, maxHeaderWidth);
            float drawHeight = drawWidth * textureHeight / textureWidth;
            if (drawHeight > maxDrawHeight)
            {
                drawHeight = maxDrawHeight;
                drawWidth = drawHeight * textureWidth / textureHeight;
            }

            float x = Mathf.Round(area.x + (area.width - drawWidth) * 0.5f);
            float y = Mathf.Round(area.y + topPadding);
            var rect = new Rect(
                x,
                y,
                Mathf.Round(drawWidth),
                Mathf.Round(drawHeight)
            );
            var bgArea = area;
            bgArea.height = rect.height;
            EditorGUI.DrawRect(bgArea, new Color(1f, 1f, 1f, 1f));
            GUI.DrawTexture(rect, _headerTexture, ScaleMode.ScaleToFit, true);
            return headerAreaHeight;
        }


        private void DrawTopLinks(Rect area)
        {
            GUILayout.BeginArea(area);
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(EditorLocalize.Get(1060)))
            {
                ToolEditor.OpenDocumentation();
            }

            GUILayout.EndHorizontal();
            GUILayout.EndArea();
        }

        public bool IsPathInsideAssets(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return false;
            }

            var unityPath = ToolEditor.ToUnityPath(path);
            return unityPath == "Assets" || unityPath.StartsWith("Assets/");
        }

        private void SaveAndApply()
        {
            if (Preferences.Default.JsonLoadMode == JsonLoadMode.Custom)
            {
                if (IsPathInsideAssets(Preferences.Default.CustomJsonExportPath))
                {
                    Preferences.Default.CustomJsonExportPath =
                        ToolEditor.ToUnityPath(Preferences.Default.CustomJsonExportPath);
                }
                else
                {
                    ToolEditor.ShowMessageBox(EditorLocalize.Get(1017));
                    return;
                }
            }

            if (Preferences.Default.CSharpExportMode == CSharpExportMode.Custom)
            {
                if (IsPathInsideAssets(Preferences.Default.CustomCsharpExportPath))
                {
                    Preferences.Default.CustomCsharpExportPath =
                        ToolEditor.ToUnityPath(Preferences.Default.CustomCsharpExportPath);
                }
                else
                {
                    ToolEditor.ShowMessageBox(EditorLocalize.Get(1015));
                    return;
                }
            }

            EditorUtility.SetDirty(Preferences.Default);
            AssetDatabase.SaveAssets();
            Debug.Log(
                $"<color=#2FBF71>✅<b>[RKOKO CONFIG FREE] {EditorLocalize.Get(1019)}</b></color>");
        }
    }
}