using UnityEngine;
using UnityEditor;
using System.IO;

public class TextureSizeTool
{
    public enum UpscaleResult
    {
        AlreadyMultipleOf4,
        Upscaled,
        Failed,
    }

    [MenuItem("FRVR/Upscale to Multiple of 4", false, 0)]
    static void UpscaleToMultipleOf4Menu()
    {
        Object[] selectedTextures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.Assets);

        if (selectedTextures.Length == 0)
        {
            EditorUtility.DisplayDialog("No Texture Selected",
                "Please select one or more textures in the Project window.", "OK");
            return;
        }

        int processedCount = 0;
        int skippedCount = 0;

        foreach (Texture2D selectedTexture in selectedTextures)
        {
            string path = AssetDatabase.GetAssetPath(selectedTexture);
            if (string.IsNullOrEmpty(path))
                continue;

            var result = UpscaleTextureToMultipleOf4(path);
            if (result == UpscaleResult.Upscaled) processedCount++;
            else if (result == UpscaleResult.AlreadyMultipleOf4) skippedCount++;
        }

        AssetDatabase.Refresh();

        string message = $"Processed {processedCount} texture(s)";
        if (skippedCount > 0)
        {
            message += $", skipped {skippedCount} (already multiple of 4)";
        }

        EditorUtility.DisplayDialog("Texture Upscaling Complete", message, "OK");
        Debug.Log(message);
    }

    [MenuItem("FRVR/Upscale to Multiple of 4", true)]
    static bool ValidateUpscaleToMultipleOf4Menu()
    {
        return Selection.GetFiltered(typeof(Texture2D), SelectionMode.Assets).Length > 0;
    }

    public static UpscaleResult UpscaleTextureToMultipleOf4(string path)
    {
        if (string.IsNullOrEmpty(path))
            return UpscaleResult.Failed;

        Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
        if (texture == null)
        {
            Debug.LogWarning($"Could not load texture at {path}");
            return UpscaleResult.Failed;
        }

        if (texture.width % 4 == 0 && texture.height % 4 == 0)
        {
            Debug.Log($"Skipped {path}: Already multiple of 4 ({texture.width}x{texture.height})");
            return UpscaleResult.AlreadyMultipleOf4;
        }

        int newWidth = ((texture.width + 3) / 4) * 4;
        int newHeight = ((texture.height + 3) / 4) * 4;

        Debug.Log($"Upscaling {path}: {texture.width}x{texture.height} -> {newWidth}x{newHeight}");

        TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
        if (importer == null)
        {
            Debug.LogWarning($"Could not get TextureImporter for {path}");
            return UpscaleResult.Failed;
        }

        bool wasReadable = importer.isReadable;

        if (!wasReadable)
        {
            importer.isReadable = true;
            importer.SaveAndReimport();
            AssetDatabase.Refresh();
        }

        texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
        if (texture == null)
        {
            Debug.LogWarning($"Could not load texture at {path}");
            return UpscaleResult.Failed;
        }

        RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight, 0, RenderTextureFormat.ARGB32);
        RenderTexture previous = RenderTexture.active;
        RenderTexture.active = rt;

        Graphics.Blit(texture, rt);

        Texture2D resizedTexture = new Texture2D(newWidth, newHeight, TextureFormat.RGBA32, false);
        resizedTexture.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
        resizedTexture.Apply();

        RenderTexture.active = previous;
        RenderTexture.ReleaseTemporary(rt);

        byte[] pngData = resizedTexture.EncodeToPNG();
        if (pngData == null || pngData.Length == 0)
        {
            Debug.LogError($"Failed to encode texture {path} to PNG");
            Object.DestroyImmediate(resizedTexture);
            return UpscaleResult.Failed;
        }

        File.WriteAllBytes(path, pngData);

        Object.DestroyImmediate(resizedTexture);

        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

        importer = AssetImporter.GetAtPath(path) as TextureImporter;
        if (importer != null && !wasReadable)
        {
            importer.isReadable = false;
            importer.SaveAndReimport();
        }

        return UpscaleResult.Upscaled;
    }
}
