using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;

namespace AvatarRefinery.Editor.Core
{
    /// <summary>
    /// 階層・コンポーネント・レンダラー参照の指紋(SHA1)。
    /// 「診断/修正の前後でアバターが変わっていないこと」を機械的に検証するために使う(テスト・将来の自動修正のロールバック検証)。
    /// </summary>
    public static class HierarchyFingerprint
    {
        public static string Compute(GameObject root)
        {
            var sb = new StringBuilder();
            foreach (var t in root.GetComponentsInChildren<Transform>(true))
            {
                sb.Append(Path(t, root.transform)).Append('|').Append(t.localPosition).Append(t.localRotation).Append(t.localScale).Append('|');
                foreach (var c in t.GetComponents<Component>())
                {
                    if (c == null) { sb.Append("<Missing>;"); continue; }
                    sb.Append(c.GetType().FullName).Append(';');
                    if (c is Renderer rd)
                    {
                        foreach (var m in rd.sharedMaterials) sb.Append(m ? m.name : "null").Append(',');
                        sb.Append(rd.probeAnchor ? rd.probeAnchor.name : "noanchor").Append(',');
                        if (rd is SkinnedMeshRenderer smr)
                            sb.Append(smr.sharedMesh ? smr.sharedMesh.name + ":" + smr.sharedMesh.blendShapeCount + ":" + smr.sharedMesh.triangles.Length : "nomesh")
                              .Append(':').Append(smr.localBounds);
                    }
                }
                sb.Append('\n');
            }
            using (var sha = SHA1.Create())
                return BitConverter.ToString(sha.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString()))).Replace("-", "");
        }

        private static string Path(Transform t, Transform root)
        {
            var parts = new List<string>();
            while (t != null && t != root) { parts.Add(t.name); t = t.parent; }
            parts.Reverse(); return string.Join("/", parts);
        }
    }
}
