using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MediaBrowser.Common.Configuration;

namespace Jellyfin.Plugin.MediaBarEnhanced.Api
{
    /// <summary>
    /// Controller for handling custom overlay image uploads and retrieval.
    /// </summary>
    [ApiController]
    [Route("MediaBarEnhanced")]
    public class OverlayImageController : ControllerBase
    {
        private readonly IApplicationPaths _applicationPaths;
        private readonly string _imageDirectory;
        private readonly string _imagePath;

        public OverlayImageController(IApplicationPaths applicationPaths)
        {
            _applicationPaths = applicationPaths;
            
            // We use the plugin's data folder to store the image
            _imageDirectory = MediaBarEnhancedPlugin.Instance?.DataFolderPath ?? Path.Combine(applicationPaths.DataPath, "plugins", "MediaBarEnhanced");
            
            // We'll just overwrite this single file each time
            _imagePath = Path.Combine(_imageDirectory, "custom_overlay_image.dat");
        }

        /// <summary>
        /// Uploads a new custom overlay image.
        /// </summary>
        [HttpPost("OverlayImage")]
        [Consumes("multipart/form-data")]
        public async Task<IActionResult> UploadImage([FromForm] IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest("No file uploaded.");
            }

            try
            {
                if (!Directory.Exists(_imageDirectory))
                {
                    Directory.CreateDirectory(_imageDirectory);
                }

                // Delete is not strictly necessary and can cause locking issues if someone is currently reading it.
                // FileMode.Create will truncate the file if it exists, effectively overwriting it.
                // We use FileShare.None to ensure we have exclusive write access, but handle potential IOExceptions gracefully.
                using (var stream = new FileStream(_imagePath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    await file.CopyToAsync(stream).ConfigureAwait(false);
                }

                // Return the GET URL that the frontend can use
                var getUrl = "/MediaBarEnhanced/OverlayImage?t=" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                return Ok(new { url = getUrl });
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Internal server error: {ex.Message}");
            }
        }

        /// <summary>
        /// Retrieves the custom overlay image.
        /// </summary>
        [HttpGet("OverlayImage")]
        public IActionResult GetImage()
        {
            if (!System.IO.File.Exists(_imagePath))
            {
                return NotFound();
            }

            // Read the file and return as a generic octet stream. 
            // We use FileShare.ReadWrite so that if someone is currently overwriting the file (uploading), we don't block them,
            // and we also don't get blocked by other readers.
            var stream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            
            // "image/*" works reliably as browsers will sniff the exact image mime type (jpeg, png, webp).
            return File(stream, "image/*");
        }
    }
}
