using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using XGame.Editor.Asset;
using XGame.Framework;
using XGame.Framework.ObjectCollection;

namespace XGame.Editor
{
    public abstract class CodeGenerator
    {
        /// <summary>
        /// 项目名字，用于确认命名空间
        /// </summary>
        protected string productName;
        /// <summary>
        /// 脚本的根目录
        /// </summary>
        protected string codesRootPath;

        protected void InitPath(string codesFolder)
        {
            var xgConfig = XGameConfig.Load();
            productName = xgConfig.productName;
            var assemblyPath = AssetDatabase.GUIDToAssetPath(xgConfig.launchAssemblyGUID);
            codesRootPath = Path.Combine(Path.GetDirectoryName(assemblyPath), codesFolder);
        }
        protected bool VerifyPrefab(GameObject go)
        {
            var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(go);
            if (string.IsNullOrEmpty(prefabPath))
                prefabPath = PrefabStageUtility.GetCurrentPrefabStage()?.assetPath;
            if (string.IsNullOrEmpty(prefabPath))
            {
                EditorUtility.DisplayDialog("Warning", $"请将该GameObject拖拽为预制体。", "确定");
                return false;
            }
            var guid = AssetDatabase.AssetPathToGUID(prefabPath);
            string addressableName = AddressableHelper.GUIDToName(guid);
            if (string.IsNullOrEmpty(addressableName))
            {
                EditorUtility.DisplayDialog("Warning", $"请点击Build/CollectAddressableAssets，以收集预制的Addressable信息。", "确定");
                return false;
            }
            return true;
        }
        /// <summary>
        /// 通用的代码生成
        /// </summary>
        /// <param name="keyName"></param>
        /// <param name="componentName"></param>
        /// <param name="codeFileName"></param>
        /// <param name="templateFileName"></param>
        /// <param name="customReplace"></param>
        /// <returns></returns>
        protected bool GenCommonCode(string keyName, string componentName, string codeFileName, string templateFileName, Func<string, string> customReplace = null)
        {
            var codePath = $"{codesRootPath}/{keyName}/{codeFileName}.cs";
            if (File.Exists(codePath))
            {
                EditorUtility.DisplayDialog("代码生成错误", $"存在同名脚本:{codePath}", "确认");
                return false;
            }
            var dirPath = $"{codesRootPath}/{keyName}";
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            var guids = AssetDatabase.FindAssets(templateFileName);
            var templatePath = AssetDatabase.GUIDToAssetPath(guids[0]);
            var codeText = AssetDatabase.LoadAssetAtPath<TextAsset>(templatePath).text;
            codeText = codeText.Replace("<#ProductName>", productName);
            codeText = codeText.Replace("<#KeyName>", keyName);
            codeText = codeText.Replace("<#ComponentName>", componentName);
            if (customReplace != null)
            {
                codeText = customReplace(codeText);
            }
            File.WriteAllText(codePath, codeText, Encoding.UTF8);
            Debug.Log($"生成代码 Path:{codePath}");
            return true;
        }

        protected bool GenViewModelCode(ObjectCollector collector, string keyName, string componentName, string vmFileName, string vmTemplateName, Func<string, string> customReplace = null)
        {
            var goType = typeof(GameObject).Name;
            var trType = typeof(Transform).Name;
            var propertyDefineSb = new StringBuilder();
            var propertyAssignSb = new StringBuilder();
            if (collector.keys.Count > 0)
            {
                for (int i = 0; i < collector.keys.Count; i++)
                {
                    var key = collector.keys[i];
                    var type = collector.bindTypes[i];
                    var propertyName = ToTitleCase(key);
                    propertyDefineSb.AppendLine($"        public {type} {propertyName} {{ get; private set; }}");
                    if (type == goType)
                    {
                        propertyAssignSb.AppendLine($"            {propertyName} = collector.GetGameObject(\"{key}\");");
                    }
                    else if (type == trType)
                    {
                        propertyAssignSb.AppendLine($"            {propertyName} = collector.GetGameObject(\"{key}\").transform;");
                    }
                    else
                    {
                        propertyAssignSb.AppendLine($"            {propertyName} = collector.GetComponent<{type}>(\"{key}\");");
                    }
                }
            }
            return GenCommonCode(keyName, componentName, vmFileName, vmTemplateName, codeText =>
            {
                codeText = codeText.Replace("<#PropertyDefineArea>", propertyDefineSb.ToString());
                codeText = codeText.Replace("<#PropertyAssignArea>", propertyAssignSb.ToString());
                if (customReplace != null)
                {
                    codeText = customReplace(codeText);
                }
                return codeText;
            });
        }
        /// <summary>
        /// 字符串首字母转大写
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        protected string ToTitleCase(string val)
        {
            //return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(val);
            if (string.IsNullOrEmpty(val))
            {
                return val;
            }
            return char.ToUpper(val[0]) + val.Substring(1);
        }
    }
}

