using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class TextureImportSettingsWindow : EditorWindow
{
    private Vector2 scrollPosition;
    private List<TextureInfo> textures = new List<TextureInfo>();
    private bool scanned;
    private bool showOnlyNeedsFix = true;

    private class TextureInfo
    {
        public string path;
        public int width;
        public int height;
        public int newWidth;
        public int newHeight;
        public bool needsFix;
    }

    [MenuItem("FRVR/Texture Import Settings")]
    public static void ShowWindow()
    {
        GetWindow<TextureImportSettingsWindow>("Texture Import Settings");
    }

    private void OnGUI()
    {
        EditorGUILayout.Space(5);

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Scan All Textures", GUILayout.Height(30)))
        {
            ScanTextures();
        }

        int fixCount = 0;
        foreach (var tex in textures)
        {
            if (tex.needsFix) fixCount++;
        }

        EditorGUI.BeginDisabledGroup(fixCount == 0);
        if (GUILayout.Button($"Fix All ({fixCount})", GUILayout.Height(30)))
        {
            FixAll();
        }
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space(5);
        showOnlyNeedsFix = EditorGUILayout.ToggleLeft("Show only needs fix", showOnlyNeedsFix);

        if (!scanned)
        {
            EditorGUILayout.HelpBox("Click 'Scan All Textures' to find all textures in the project.", MessageType.Info);
            return;
        }

        EditorGUILayout.Space(5);
        EditorGUILayout.LabelField($"Found {textures.Count} textures, {fixCount} need fixing", EditorStyles.boldLabel);

        EditorGUILayout.HelpBox(
            "Target: texture dimensions should be a multiple of 4.\n\n" +
            "Non-multiples of 4 prevent block-compression formats (DXT/ETC2/ASTC) from being used, " +
            "forcing uncompressed fallback and inflating build size.\n\n" +
            "Fix upscales to the next multiple of 4 using Graphics.Blit.",
            MessageType.Info);
        EditorGUILayout.Space(5);

        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

        foreach (var tex in textures)
        {
            if (showOnlyNeedsFix && !tex.needsFix) continue;
            DrawTextureEntry(tex);
        }

        EditorGUILayout.EndScrollView();
    }

    private void DrawTextureEntry(TextureInfo tex)
    {
        var style = new GUIStyle(EditorStyles.helpBox);
        {
            var bgTex = new Texture2D(1, 1);
            bgTex.SetPixel(0, 0, tex.needsFix
                ? new Color(0.8f, 0.2f, 0.2f, 0.15f)
                : new Color(0.2f, 0.8f, 0.2f, 0.15f));
            bgTex.Apply();
            style.normal.background = bgTex;
        }

        EditorGUILayout.BeginVertical(style);

        // Header row
        EditorGUILayout.BeginHorizontal();
        string statusIcon = tex.needsFix ? "X" : "OK";
        EditorGUILayout.LabelField($"[{statusIcon}] {tex.path}", EditorStyles.boldLabel);

        if (GUILayout.Button("Select", GUILayout.Width(60)))
        {
            var obj = AssetDatabase.LoadAssetAtPath<Texture2D>(tex.path);
            if (obj != null)
            {
                Selection.activeObject = obj;
                EditorGUIUtility.PingObject(obj);
            }
        }

        if (tex.needsFix)
        {
            if (GUILayout.Button("Fix", GUILayout.Width(50)))
            {
                TextureSizeTool.UpscaleTextureToMultipleOf4(tex.path);
                AssetDatabase.Refresh();
                ScanTextures();
                GUIUtility.ExitGUI();
            }
        }
        EditorGUILayout.EndHorizontal();

        // Dimensions
        EditorGUI.indentLevel++;
        string dimensions = $"{tex.width} x {tex.height}";
        string value = tex.needsFix
            ? $"{dimensions}  ->  {tex.newWidth} x {tex.newHeight}  [NEEDS FIX]"
            : $"{dimensions}  [OK]";
        EditorGUILayout.LabelField("Dimensions", value);
        EditorGUI.indentLevel--;

        EditorGUILayout.EndVertical();
        EditorGUILayout.Space(2);
    }

    private void ScanTextures()
    {
        textures.Clear();
        string[] guids = AssetDatabase.FindAssets("t:Texture2D", new[] { "Assets" });

        foreach (string guid in guids)
        {
            string path = AssetDatabase.GUIDToAssetPath(guid);
            var importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer == null) continue;

            var loaded = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
            if (loaded == null) continue;

            var info = new TextureInfo
            {
                path = path,
                width = loaded.width,
                height = loaded.height,
            };
            info.newWidth = ((info.width + 3) / 4) * 4;
            info.newHeight = ((info.height + 3) / 4) * 4;
            info.needsFix = (info.width % 4 != 0) || (info.height % 4 != 0);

            textures.Add(info);
        }

        // Sort: items needing fix first, then alphabetically
        textures.Sort((a, b) =>
        {
            if (a.needsFix != b.needsFix)
                return a.needsFix ? -1 : 1;
            return string.Compare(a.path, b.path);
        });

        scanned = true;
    }

    private void FixAll()
    {
        int count = 0;
        foreach (var tex in textures)
        {
            if (!tex.needsFix) continue;
            var result = TextureSizeTool.UpscaleTextureToMultipleOf4(tex.path);
            if (result == TextureSizeTool.UpscaleResult.Upscaled) count++;
        }

        AssetDatabase.Refresh();

        EditorUtility.DisplayDialog("Texture Import Settings",
            $"Fixed {count} texture(s).\n\nAll textures now have dimensions that are multiples of 4.", "OK");

        ScanTextures();
    }
}
