using Azure.Storage.Blobs.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TEAMModelOS.Models;
using TEAMModelOS.Models.Request;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.PngQuant;

namespace TEAMModelOS.Controllers.Core
{
    [Route("Core")]
    [ApiController]
    public class CoreController : ControllerBase
    {
        private readonly AzureStorageFactory _azureStorage;
        private readonly DingDing _dingDing;
        private readonly Option _option;

        public CoreController(AzureStorageFactory azureStorage , DingDing dingDing, IOptionsSnapshot<Option> option)
        {
            _azureStorage = azureStorage;
            _dingDing = dingDing;
            _option = option?.Value;
        }

        [HttpPost("system-info")]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        public  IActionResult  SystemInfo(JsonElement request) {

            //var v1 = Assembly.GetEntryAssembly().GetName().Version;
            //var v2 = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
            var version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
            //Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " +

            //                  $"{Assembly.GetEntryAssembly().GetName().Version}");

            //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version:" +
            //                  $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");

            //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +

            //                  $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion}");
            return Ok(new { version });
        }
        /// <summary>
        /// 等待P1V3，啟動Dcoker，支持EMF GDI+
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("convert-emf")]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        public async Task<IActionResult> ConvertEmf(ImageQuangRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.base64)) return BadRequest();
                byte[] obase64data = Convert.FromBase64String(request.base64);
                using var obase64ms = new MemoryStream(obase64data);
                var (isimg, type, dupe) = Utils.ImageValidateByStream(obase64ms);
                if (isimg && type.Equals("emf"))
                {
                    var pngimagebase64 = Utils.ConvertEMFtoPNG(obase64ms);
                    return Ok(pngimagebase64);
                }
                else
                {
                    return BadRequest("非EMF圖片格式");
                }
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"Core，{_option.Location}，convert-emf()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }

        /// <summary>
        /// PNG JPF 圖片輕量化
        /// </summary>
        /// <param name="request">支持html base64標籤解析</param>
        /// <returns></returns>
        [HttpPost("image-quant")]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        public async Task<IActionResult> ImageQuang(List<ImageQuangRequest> request)
        {
            if (request.Count < 1) return BadRequest();
            Regex rex = new Regex(@"data:(?<key1>image.+?);base64,(?<key2>.+)");

            List<object> respons = new List<object>();
            var quantizer = new PngQuantizer();
            foreach (var item in request)
            {
                //正則處理，移除空白
                string trim = Regex.Replace(item.base64, @"\s", "");
                Match match = rex.Match(trim);
                string otype = match.Groups["key1"].Value;
                string obase64 = match.Groups["key2"].Value;
                byte[] obase64data = Convert.FromBase64String(obase64);
                using var obase64ms = new MemoryStream(obase64data);
                //驗證圖片格式及位深，判斷是否要處理量化演算
                var (isimg, type, dupe) = Utils.ImageValidateByStream(obase64ms);
                if (isimg && (type.Equals("png") || type.Equals("jpg")) && dupe > 8)
                {
                    string img = string.Empty;
                    using var quantized = quantizer.QuantizeImage(obase64ms, item.width, item.height); //JPEG，PNG輕量化
                    if (quantized != null)
                    {
                        //檢查是否需要保存原圖到blob
                        if (!string.IsNullOrWhiteSpace(item.blob))
                        {
                            img = $"{Guid.NewGuid():N}.{type}"; //命名新圖片名稱
                            string Container = item.blob.Substring(0, item.blob.IndexOf("/")); //取得容器名稱
                            string blobpath = $"{item.blob[(item.blob.Trim('/').IndexOf("/") + 1)..]}/{img}"; //處理路徑，避免多餘的字符
                            await _azureStorage.GetBlobContainerClient(Container).GetBlobClient(blobpath).UploadAsync(obase64ms, new BlobHttpHeaders { ContentType = otype });
                        }
                        using var nbase64ms = new MemoryStream();
                        quantized.Save(nbase64ms, ImageFormat.Png); //保存為PNG格式
                        byte[] data = nbase64ms.ToArray();
                        string base64 = $"data:image/png;base64,{Convert.ToBase64String(data)}"; //創建新的img src base64
                        respons.Add(new { base64 = base64, blob = img });

                        // TODO 下面註解，無法解決保存時，真正改變Format32bppArgb為Format8bppIndexed，需要再研究
                        //ImageCodecInfo imageCodecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(info => info.MimeType == "image/png");
                        //var parameters = new EncoderParameters(1);
                        //parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
                        //quantized.Save(nbase64ms, imageCodecInfo, parameters); //保存為PNG格式
                    }
                    else
                    {
                        respons.Add(new { base64 = item.base64, blob = "" }); //異常的圖片，原Base64返回
                    }
                }
                else
                {
                    respons.Add(new { base64 = item.base64, blob = "" }); //不符合的圖片，原Base64返回
                }
            }
            return Ok(respons);

        }
    }
}
