using UnityEngine;
using UnityEditor;
using System.IO;

public class IconGenerator : EditorWindow
{
    public Camera renderCamera;
    public GameObject[] prefabs;
    public string savePath = "Assets/_Project/Art/Icons/MetaPart/Bedroom";
    public int imageSize = 2000;
    public float padding = 1.2f;
    public float minRadius = 0.3f;
    
    public Vector3 cameraAngle = new Vector3(30f, 135f, 0f); 

    private Vector2 scrollPos;

    [MenuItem("Tools/Icon Generator")]
    public static void ShowWindow()
    {
        GetWindow<IconGenerator>("Icon Generator").minSize = new Vector2(300, 550);
    }

    void OnGUI()
    {
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

        GUILayout.Label("Settings", EditorStyles.boldLabel);
        
        renderCamera = (Camera)EditorGUILayout.ObjectField("Render Camera", renderCamera, typeof(Camera), true);
        savePath = EditorGUILayout.TextField("Save Path", savePath);
        imageSize = EditorGUILayout.IntField("Image Size", imageSize);
        padding = EditorGUILayout.Slider("Padding (Space around)", padding, 1f, 3f); 
        minRadius = EditorGUILayout.Slider("Min Radius", minRadius, 0.1f, 5f);
        
        GUILayout.Space(5);
        cameraAngle = EditorGUILayout.Vector3Field("Camera Angle", cameraAngle);
        GUILayout.Space(10);

        ScriptableObject target = this;
        SerializedObject so = new SerializedObject(target);
        SerializedProperty prefabsProperty = so.FindProperty("prefabs");
        
        EditorGUILayout.PropertyField(prefabsProperty, true);
        so.ApplyModifiedProperties();

        EditorGUILayout.EndScrollView();

        GUILayout.Space(5);
        if (GUILayout.Button("Generate Icons", GUILayout.Height(40)))
        {
            if (renderCamera == null || prefabs == null || prefabs.Length == 0)
            {
                Debug.LogWarning("Please assign a camera and at least one prefab!");
                return;
            }
            Generate();
        }
        GUILayout.Space(5);
    }

    void Generate()
    {
        if (!Directory.Exists(savePath))
        {
            Directory.CreateDirectory(savePath);
        }

        Vector3 originalCamPos = renderCamera.transform.position;
        Quaternion originalCamRot = renderCamera.transform.rotation; // Запоминаем оригинальный поворот
        float originalOrthoSize = renderCamera.orthographicSize;

        RenderTexture rt = new RenderTexture(imageSize, imageSize, 24);
        renderCamera.targetTexture = rt;
        Texture2D screenShot = new Texture2D(imageSize, imageSize, TextureFormat.ARGB32, false);

        foreach (var prefab in prefabs)
        {
            if (prefab == null) continue;

            GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
            instance.transform.position = Vector3.zero; 

            Bounds bounds = CalculateBounds(instance);

            Vector3 offset = new Vector3(-bounds.center.x, -bounds.min.y, -bounds.center.z);
            instance.transform.position += offset;

            bounds = CalculateBounds(instance);
            
            renderCamera.transform.rotation = Quaternion.Euler(cameraAngle);

            FrameCamera(renderCamera, bounds);

            renderCamera.Render();
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, imageSize, imageSize), 0, 0);
            screenShot.Apply();

            string fullPath = Path.Combine(savePath, prefab.name + ".png");
            byte[] bytes = screenShot.EncodeToPNG();
            File.WriteAllBytes(fullPath, bytes);

            DestroyImmediate(instance);
        }
        
        renderCamera.transform.position = originalCamPos;
        renderCamera.transform.rotation = originalCamRot; 
        renderCamera.orthographicSize = originalOrthoSize;
        renderCamera.targetTexture = null;
        RenderTexture.active = null;
        DestroyImmediate(rt);
        
        AssetDatabase.Refresh();
        Debug.Log($"Successfully generated {prefabs.Length} icons in {savePath}");
    }

    Bounds CalculateBounds(GameObject obj)
    {
        Renderer[] renderers = obj.GetComponentsInChildren<Renderer>();
        if (renderers.Length == 0) return new Bounds(obj.transform.position, Vector3.zero);

        Bounds bounds = renderers[0].bounds;
        foreach (Renderer r in renderers)
        {
            bounds.Encapsulate(r.bounds);
        }
        return bounds;
    }

    void FrameCamera(Camera cam, Bounds bounds)
    {
        float radius = Mathf.Max(bounds.extents.magnitude, minRadius) * padding;

        if (cam.orthographic)
        {
            cam.orthographicSize = radius;
            cam.transform.position = bounds.center - cam.transform.forward * 10f;
        }
        else
        {
            float fov = cam.fieldOfView * 0.5f * Mathf.Deg2Rad;
            float distance = radius / Mathf.Sin(fov);
            cam.transform.position = bounds.center - cam.transform.forward * distance;
        }
    }
}