using System.Threading;
using Cysharp.Threading.Tasks;
using Darkmatter.Core.Contracts.Services.Camera;
using Darkmatter.Core.Contracts.Services.Capture;
using UnityEngine;
using CameraType = Darkmatter.Core.Enums.Services.Camera.CameraType;

namespace Darkmatter.Services.Capture
{
    public class CaptureService : ICaptureService
    {
        private readonly ICameraService _cameraService;

        public CaptureService(ICameraService cameraService)
        {
            _cameraService = cameraService;
        }

        public async UniTask<Sprite> CapturePngAsync(GameObject captureObject, float captureSize,
            CancellationToken cancellationToken = default)
        {
            var captureCamera = _cameraService.GetCamera(CameraType.CaptureCamera);

            await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);
            
            int size = Mathf.RoundToInt(captureSize);
            var renderTexture = RenderTexture.GetTemporary(size, size, 24);
            var previousTarget = captureCamera.targetTexture;
            var previousActive = RenderTexture.active;

            try
            {
                captureCamera.targetTexture = renderTexture;
                
                captureCamera.Render();

                RenderTexture.active = renderTexture;

                var texture = new Texture2D(size, size, TextureFormat.RGBA32, false);
                texture.ReadPixels(new Rect(0, 0, size, size), 0, 0);
                texture.Apply();

                return Sprite.Create(texture, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f));
            }
            finally
            {
                captureCamera.targetTexture = previousTarget;
                RenderTexture.active = previousActive;
                RenderTexture.ReleaseTemporary(renderTexture);
            }
        }
    }
}