using System.Net;
using adas_core.Authentication.Attributes;
using adas_core.Domain.Enums;
using adas_core.module.ProxyDevices.Services;
using Microsoft.AspNetCore.Mvc;

namespace adas_core.Controllers;

[Route("proxy-devices")]
[ApiController]
public class ProxyDeviceController(IProxyDeviceService proxyDeviceService) : ControllerBase
{
    [HttpGet("{deviceId}")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> GetStreamById(string deviceId)
    {
        var response = await proxyDeviceService.Process(deviceId);
        if (!response.IsSuccessStatusCode) return new StatusCodeResult((int)response.StatusCode);
        var stream = await response.Content.ReadAsStreamAsync();
        if (response.Content.Headers.ContentLength > 0) Response.ContentLength = response.Content.Headers.ContentLength;
        return new FileStreamResult(stream,
            response.Content.Headers.ContentType?.ToString() ?? "multipart/x-mixed-replace"); // Set MIME type as needed
    }

    [HttpGet("{deviceId}/content")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task<IActionResult> GetContentById(string deviceId)
    {
        var response = await proxyDeviceService.Process(deviceId);
        var content = await response.Content.ReadAsStreamAsync();
        if (response.Content.Headers.ContentLength > 0) Response.ContentLength = response.Content.Headers.ContentLength;
        if (response.Content.Headers.ContentType != null)
            Response.ContentType = response.Content.Headers.ContentType?.ToString() ?? "";
        return Ok(content);
    }

    [HttpGet("{deviceId}/mjpeg-stream")]
    [AuthorizeRoles(PermissionEnum.RolesType.AuthSome)]
    public async Task GetAsMpegStreamById(string deviceId)
    {
        try
        {                       

            using var cts = CancellationTokenSource.CreateLinkedTokenSource(HttpContext.RequestAborted);
            //cts.CancelAfter(TimeSpan.FromMinutes(5));

            var response = await proxyDeviceService.Stream(deviceId);

            if (!response.IsSuccessStatusCode)
            {
                Response.StatusCode = (int)response.StatusCode;
                return;
            }

            if (response.Content.Headers.ContentType != null)
                Response.ContentType = response.Content.Headers.ContentType?.ToString() ??
                                       "multipart/x-mixed-replace;boundary=my-boundary";
            await using var stream = await response.Content.ReadAsStreamAsync(cts.Token);
            // Buffer for reading the stream
            var buffer = new byte[4096];
            int bytesRead;


            while (!cts.Token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, cts.Token)) > 0)
            {
                await Response.Body.WriteAsync(buffer.AsMemory(0, bytesRead), cts.Token);
                await Response.Body.FlushAsync(cts.Token);
            }
        }
        catch (HttpRequestException e)
        {
            Response.StatusCode = (int)(e.StatusCode ?? HttpStatusCode.NotFound);
        }
    }
}