using UnityEngine;
using UVC.Log;

namespace UVC.Extension
{
    /// <summary>
    /// RenderTexture 확장 메서드를 제공하는 클래스입니다.
    /// </summary>
    public static class RenderTextureEx
    {
        /// <summary>
        /// RenderTexture를 Texture2D로 변환합니다.
        /// </summary>
        /// <param name="renderTexture">변환할 RenderTexture 객체</param>
        /// <returns>변환된 Texture2D 객체</returns>
        /// <example>
        /// 사용 예시:
        /// <code>
        /// // RenderTexture 생성
        /// RenderTexture renderTexture = new RenderTexture(256, 256, 24);
        /// 
        /// // 카메라에서 renderTexture에 렌더링
        /// Camera.main.targetTexture = renderTexture;
        /// Camera.main.Render();
        /// 
        /// // RenderTexture를 Texture2D로 변환
        /// Texture2D texture2D = renderTexture.ToTexture2D();
        /// 
        /// // 사용 후 정리
        /// Camera.main.targetTexture = null;
        /// Camera.main.ResetAspect();
        /// </code>
        /// </example>
        public static Texture2D ToTexture2D(this RenderTexture renderTexture)
        {
            Texture2D texture2D = new Texture2D(renderTexture.width, renderTexture.height);
            RenderTexture.active = renderTexture;
            texture2D.ReadPixels(new UnityEngine.Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
            texture2D.Apply();
            return texture2D;
        }

        /// <summary>
        /// RenderTexture를 바이트 배열로 변환합니다.
        /// </summary>
        /// <param name="renderTexture">변환할 RenderTexture 객체</param>
        /// <param name="format">이미지 형식 (기본값: PNG)</param>
        /// <returns>바이트 배열</returns>
        /// <example>
        /// 사용 예시:
        /// <code>
        /// RenderTexture rt = new RenderTexture(256, 256, 24);
        /// byte[] bytes = rt.ToBytes();
        /// File.WriteAllBytes("screenshot.png", bytes);
        /// </code>
        /// </example>
        public static byte[] ToBytes(this RenderTexture renderTexture, TextureFormat format = TextureFormat.RGBA32)
        {
            Texture2D texture2D = renderTexture.ToTexture2D();
            byte[] bytes = texture2D.EncodeToPNG();
            Object.Destroy(texture2D);
            return bytes;
        }

        /// <summary>
        /// RenderTexture를 지정된 경로에 PNG 파일로 저장합니다.
        /// </summary>
        /// <param name="renderTexture">저장할 RenderTexture 객체</param>
        /// <param name="filePath">저장할 파일 경로</param>
        /// <returns>성공 여부</returns>
        /// <example>
        /// 사용 예시:
        /// <code>
        /// RenderTexture rt = new RenderTexture(256, 256, 24);
        /// Camera.main.targetTexture = rt;
        /// Camera.main.Render();
        /// bool success = rt.SaveToPNG("Assets/Screenshots/screenshot.png");
        /// Camera.main.targetTexture = null;
        /// </code>
        /// </example>
        public static bool SaveToPNG(this RenderTexture renderTexture, string filePath)
        {
            try
            {
                byte[] bytes = renderTexture.ToBytes();
                System.IO.File.WriteAllBytes(filePath, bytes);
                return true;
            }
            catch (System.Exception e)
            {
                ULog.Error($"RenderTexture를 PNG로 저장하는 데 실패했습니다: {e.Message}", e);
                return false;
            }
        }

        /// <summary>
        /// RenderTexture의 크기를 조정합니다.
        /// </summary>
        /// <param name="renderTexture">원본 RenderTexture</param>
        /// <param name="width">새 너비</param>
        /// <param name="height">새 높이</param>
        /// <returns>크기가 조정된 새로운 RenderTexture</returns>
        /// <example>
        /// 사용 예시:
        /// <code>
        /// RenderTexture originalRT = new RenderTexture(1024, 1024, 24);
        /// RenderTexture resizedRT = originalRT.Resize(512, 512);
        /// // 사용 후 정리
        /// resizedRT.Release();
        /// originalRT.Release();
        /// </code>
        /// </example>
        public static RenderTexture Resize(this RenderTexture renderTexture, int width, int height)
        {
            RenderTexture resized = new RenderTexture(width, height, renderTexture.depth);
            Graphics.Blit(renderTexture, resized);
            return resized;
        }
    }
}
