using CrazyStudio.Core.Common.AliyunExt.Oss.Tools;
using CrazyStudio.Core.Common.Eitities;
using CrazyStudio.Core.Common.Tools;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Concurrent;
using System.Text.Json;
using System.Threading.Tasks;
using TouchSocket.Core;
using XPrintServer.Api.Dto;
using XPrintServer.Api.Entities.Vol;
using XPrintServer.Api.Tools;

namespace XPrintServer.Api.Controllers.Ai
{

    [Route("api/[controller]/[action]")]
    [ApiController]
    public class VolController : ControllerBase
    {
        //private readonly TextToImageModel _textToImageModel;

        //public HttpVolController(TextToImageModel textToImageModel)
        //{
        //    _textToImageModel = textToImageModel;
        //}

        //public HttpVolController()
        //{
        //}


        private readonly VolInfos _volInfos;
        private readonly AliyunInfos _aliyunInfos;
        private readonly OssTool _ossTool;
        private static ConcurrentDictionary<string, bool> _queryTasks = new ConcurrentDictionary<string, bool>();
        public VolController(VolInfos volInfos, AliyunInfos aliyunInfos, OssTool ossTool)
        {
            _volInfos = volInfos;
            _aliyunInfos = aliyunInfos;
            _ossTool = ossTool;
        }



        //[HttpPost]
        //public void Test()
        //{
        //    _textToImageModel.TextToImage("Kirin's facial close-up, golden pupils, small scales around the eyes, partial close-up, high definition, megalophobia perspective, first person perspective, Lord of the Rings style, movie quality, stunning, realistic light and shadow, vivid, full of vitality, 8K, fantasy engine, rich details, conceptual art", @"D:\1.png");
        //}

        private static RequestInfo GetVolRequestInfo(object data, string action)
        {
            var info = new RequestInfo
            {
                Url = "https://visual.volcengineapi.com",
                Version = "2022-08-31",
                Action = action,//"CVProcess",
                ServiceName = "cv",
                Region = "cn-north-1",
                Data = data,
                Method = "POST"
            };
            return info;
        }

        //private static RequestInfo GetVolQueryRequestInfo(object data)
        //{
        //    var info = new RequestInfo
        //    {
        //        Url = "https://visual.volcengineapi.com",
        //        Version = "2022-08-31",
        //        Action = "CVGetResult",
        //        ServiceName = "cv",
        //        Region = "cn-north-1",
        //        Data = data,
        //        Method = "POST"
        //    };
        //    return info;
        //}

        [HttpPost]
        public async Task<PromptResult> CreateImageUrl([FromBody] PromptRequestInfo promptInfo)
        {
            //return new PromptResult
            //{
            //    Code = -3,
            //    Message = "调用达到上限"
            //};

            if (string.IsNullOrWhiteSpace(promptInfo.Prompt) && string.IsNullOrWhiteSpace(promptInfo.ImageUrl))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "提示词和参考图不能同时为空"
                };
            }

            RequestInfo? info = null;
            if (string.IsNullOrWhiteSpace(promptInfo.ImageUrl))
            {
                //Console.WriteLine((string.IsNullOrEmpty(promptInfo.LLmResult) && promptInfo.Prompt.Length < 50) ? true : false);
                info = GetVolRequestInfo(new VolTxt2ImgRequestInfo
                {
                    Width = promptInfo.Width,
                    Height = promptInfo.Height,
                    Seed = int.Parse(promptInfo.Seed),
                    UsePreLlm = false,//(string.IsNullOrEmpty(promptInfo.LLmResult) && promptInfo.Prompt.Length < 50) ? true : false,//promptInfo.Seed == "-1" && 
                    Prompt = string.IsNullOrEmpty(promptInfo.LLmResult) ? promptInfo.Prompt : promptInfo.LLmResult,// "一架飞机，飞在蔚蓝的天空上，旁边飘着几朵白云",
                    ReturnUrl = true
                }, "CVProcess");
            }
            else
            {
                info = GetVolRequestInfo(new VolImg2ImgRequestInfo
                {
                    Width = promptInfo.Width,
                    Height = promptInfo.Height,
                    GenMode = string.IsNullOrWhiteSpace(promptInfo.Prompt) ? "creative" : "reference",
                    ImageInput = promptInfo.ImageUrl,
                    Seed = int.Parse(promptInfo.Seed),
                    Prompt = string.IsNullOrEmpty(promptInfo.LLmResult) ? promptInfo.Prompt : promptInfo.LLmResult,// "一架飞机，飞在蔚蓝的天空上，旁边飘着几朵白云",
                    ReturnUrl = true
                }, "CVProcess");
            }

            var result = await HttpVolTool.RequestVol<VolResult>(info, _volInfos!);

            var promptResult = new PromptResult();

            if (result != null)
            {
                promptResult.Code = result.Code;
                if (result!.Code == 10000)
                {
                    var urls = result!.Data!.ImageUrls;
                    if (urls.Length > 0)
                    {
                        promptResult.LLmResult = result.Data.LlmResult;
                        promptResult.ImageUrl = urls[0];
                        promptResult.Message = string.Empty;

                        return promptResult;
                    }
                }
                else
                {
                    promptResult.Message = result.Message;
                }
            }
            return promptResult;
        }

        [HttpPost]
        public async Task<PromptResult> CreateScaleImageUrl([FromBody] ScaleRequestInfo scaleInfo)
        {
            string[] imageUrls = new string[scaleInfo.FileNames.Length];
            for (int i = 0; i < scaleInfo.FileNames.Length; i++)
            {
                imageUrls[i] = "https://" + _aliyunInfos!.Oss.Bucket + "." + _aliyunInfos!.Oss.Region + ".aliyuncs.com/cache/" + scaleInfo.FileNames[i];
            }

            //Console.WriteLine((string.IsNullOrEmpty(promptInfo.LLmResult) && promptInfo.Prompt.Length < 50) ? true : false);
            var info = GetVolRequestInfo(new OutPaintingRequest
            {
                ImageUrls = imageUrls,
                Top = Math.Min(1, Math.Max(0, float.Parse(scaleInfo.Top))),
                Bottom = Math.Min(1, Math.Max(0, float.Parse(scaleInfo.Bottom))),
                Left = Math.Min(1, Math.Max(0, float.Parse(scaleInfo.Left))),
                Right = Math.Min(1, Math.Max(0, float.Parse(scaleInfo.Right))),
                Strength = 0.8f,//和原图一样，基于原图扩展，不改变
                MaxWidth = scaleInfo.MaxWidth,
                MaxHeight = scaleInfo.MaxHeight,
                ReturnUrl = true
            }, "CVProcess");

            var result = await HttpVolTool.RequestVol<VolResult>(info, _volInfos!);

            var promptResult = new PromptResult();

            if (result != null)
            {
                promptResult.Code = result.Code;
                if (result!.Code == 10000)
                {
                    var urls = result!.Data!.ImageUrls;
                    if (urls.Length > 0)
                    {
                        promptResult.LLmResult = result.Data.LlmResult;
                        promptResult.ImageUrl = urls[0];
                        promptResult.Message = string.Empty;

                        return promptResult;
                    }
                }
                else
                {
                    promptResult.Message = result.Message;
                }
            }
            return promptResult;
        }

        //[HttpPost]
        //public async Task<PromptResult> CreateAlphaBgImageUrl([FromBody] PromptRequestInfo promptInfo)
        //{
        //    //if (string.IsNullOrWhiteSpace(promptInfo.Prompt))
        //    //{
        //    //    return new PromptResult
        //    //    {
        //    //        Code = -2,
        //    //        Message = "提示词不能为空"
        //    //    };
        //    //}

        //    //promptInfo.Prompt += "，分割背景，背景是值为255的绿色，相反区域则不能有值为255的绿色，值为255的绿色背景的图片，画的图不能有值为255的绿色";
        //    //var promptResult = await this.CreateImageUrl(promptInfo);
        //    //return promptResult;
        //    if (promptInfo.IsWhiteBG)
        //    {
        //        promptInfo.Prompt += ",要求白色背景。";
        //    }
        //    var result = await CreateImageUrl(promptInfo);
        //    if (result.Code == 10000)
        //    {
        //        result = await ImageSplit(result.ImageUrl);
        //        return result;
        //    }
        //    return result;
        //}

        [HttpPost]
        public async Task<PromptResult> SplitImage([FromBody] RequestImage requestImage)
        {
            if (string.IsNullOrWhiteSpace(requestImage.Url))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "图像URL不能为空"
                };
            }

            var info = GetVolRequestInfo(new ImageMainInfo
            {
                ImageUrls = [requestImage.Url],
                //RGB = [-1, -1, -1],
                //RefineMask = 1
                OnlyMask = 2
            }, "CVProcess");

            var result = await HttpVolTool.RequestVol<VolResult>(info, _volInfos!);

            var promptResult = new PromptResult();

            if (result != null)
            {
                promptResult.Code = result.Code;
                if (result!.Code == 10000)
                {
                    var urls = result!.Data!.ImageUrls;
                    byte[]? bytes = null;
                    if (urls == null || urls.Length == 0)
                    {
                        urls = result!.Data!.BinaryDataBase64;
                        bytes = Convert.FromBase64String(urls[0]);
                    }
                    else
                    {
                        bytes = await HttpTool.GetBytes(urls[0]);
                    }
                    if (bytes != null)
                    {
                        _ossTool.DeleteObject(_aliyunInfos.Oss.Bucket, requestImage.ObjectName);

                        var objectName = "cache/image/" + Guid.NewGuid().ToString("N") + ".png";
                        using (var mem = new MemoryStream(bytes!))
                        {
                            _ossTool.PutObject(_aliyunInfos.Oss.Bucket, objectName, mem, DateTime.UtcNow.AddDays(10));
                        }
                        //Console.WriteLine(urls[0]);
                        promptResult.ImageUrl = $"https://{_aliyunInfos.Oss.Bucket}.{_aliyunInfos.Oss.Region.Replace("-internal", "")}.aliyuncs.com/{objectName}";
                        promptResult.Message = string.Empty;
                        promptResult.ObjectName = objectName;

                        return promptResult;
                    }
                }
                else
                {
                    promptResult.Message = result.Message;
                }
            }
            return promptResult;
        }

        private async Task<QueryResult?> QueryTaskResult(string taskId, string action)
        {
            RequestInfo? info = null;
            if (action == "CVSync2AsyncGetResult")
            {
                info = GetVolRequestInfo(new TaskQuery
                {
                    ReqKey = "jimeng_vgfm_i2v_l20",
                    TaskId = taskId
                }, action);
            }
            else
            {
                info = GetVolRequestInfo(new TaskQuery
                {
                    ReqKey = "dressing_diffusionV2",
                    TaskId = taskId,
                    ReqJson = JsonSerializer.Serialize(new ReqJson { ReturnUrl = true })
                }, action);
            }

            var result = (await HttpVolTool.RequestVol<QueryResult>(info!, _volInfos!))!;
            return result;
        }


        [HttpPost]
        public async Task<PromptResult> ChangeCloth([FromBody] Dto.ClothRequestInfo clothInfo)
        {
            if (string.IsNullOrWhiteSpace(clothInfo.ClothUrl))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "服装Url不能为空"
                };
            }
            if (string.IsNullOrWhiteSpace(clothInfo.ModelUrl))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "模特Url不能为空"
                };
            }
            if (string.IsNullOrWhiteSpace(clothInfo.ClothType))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "衣服类型不能为空"
                };
            }

            var clothRequest = new Entities.Vol.ClothRequestInfo();
            clothRequest.Garment.Data = new GarmentData[] {
                new GarmentData
                {
                    Type = clothInfo.ClothType,
                    Url = clothInfo.ClothUrl,
                }
            };
            clothRequest.Model.Url = clothInfo.ModelUrl;
            clothRequest.InferenceConfig.KeepLower = true;

            RequestInfo info = GetVolRequestInfo(clothRequest, "CVSubmitTask");

            var result = await HttpVolTool.RequestVol<VolResult>(info, _volInfos!);

            var promptResult = new PromptResult();

            if (result != null)
            {
                promptResult.Code = result.Code;
                if (result!.Code == 10000)
                {
                    var taskId = result!.Data!.TaskId;
                    if (!string.IsNullOrEmpty(taskId))
                    {
                        //// 使用Task.Run将异步操作调度到线程池
                        //var task = Task.Run(async () =>
                        //{
                        //    while (true)
                        //    {
                        //        await Task.Delay(1000);
                        //        var queryResult = (await QueryTaskResult(taskId, "CVGetResult"))!;
                        //        if (queryResult.Code == 10000)
                        //        {
                        //            if (queryResult.Data.Status == "done")
                        //            {
                        //                //promptResult.LLmResult = result.Data.LlmResult;
                        //                if (queryResult.Data.ImageUrls.Length > 0)
                        //                {
                        //                    promptResult.ImageUrl = queryResult.Data.ImageUrls[0];
                        //                    promptResult.Message = string.Empty;
                        //                }
                        //                else
                        //                {
                        //                    promptResult.Message = queryResult.Message;
                        //                }
                        //                break;
                        //            }
                        //            else if (queryResult.Data.Status == "in_queue" || queryResult.Data.Status == "generating")
                        //            {
                        //                continue;
                        //            }
                        //            else if (queryResult.Data.Status == "not_found" || queryResult.Data.Status == "expired")
                        //            {
                        //                promptResult.Message = queryResult.Message;
                        //                break;
                        //            }
                        //            else
                        //            {
                        //                promptResult.Message = queryResult.Message;
                        //                break;
                        //            }
                        //        }
                        //        else
                        //        {
                        //            promptResult.Message = queryResult.Message;
                        //            break;
                        //        }
                        //    }

                        //    return promptResult;
                        //});
                        //return task.Result;

                        promptResult.TaskId = taskId;

                    }
                }
                else
                {
                    promptResult.Message = result.Message;
                }
            }
            return promptResult;
        }

        [HttpPost]
        public async Task<PromptResult> QueryTask([FromBody] TaskRequestInfo task)
        {
            if (string.IsNullOrWhiteSpace(task.TaskId))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "TaskId不能为空"
                };
            }
            if (_queryTasks.ContainsKey(task.TaskId))
            {
                return new PromptResult
                {
                    Code = 10000,
                    Message = "任务正在处理中，请稍后再试"
                };
            }
            _queryTasks[task.TaskId] = true;
            var queryResult = await QueryTaskResult(task.TaskId, task.Action);// "CVGetResult");
            var promptResult = new PromptResult();
            if (queryResult != null)
            {
                promptResult.Code = queryResult.Code;
                if (queryResult!.Code == 10000)
                {
                    promptResult.Code = queryResult.Code;
                    if (queryResult.Data.Status == "done")
                    {
                        if (task.TaskType == "image")
                        {
                            if (queryResult.Data.ImageUrls.Length > 0)
                            {
                                promptResult.ImageUrl = queryResult.Data.ImageUrls[0];
                            }
                        }
                        else if (task.TaskType == "video")
                        {
                            var videoUrl = queryResult.Data.VideoUrl;
                            var bytes = await HttpTool.GetBytes(videoUrl);
                            var objectName = "cache/video/" + task.TaskId + ".mp4";

                            using (var mem = new MemoryStream(bytes!))
                            {
                                _ossTool.PutObject(_aliyunInfos.Oss.Bucket, objectName, mem, DateTime.UtcNow.AddDays(10));
                            }

                            promptResult.VideoUrl = $"https://{_aliyunInfos.Oss.Bucket}.{_aliyunInfos.Oss.Region.Replace("-internal", "")}.aliyuncs.com/{objectName}";
                        }
                        promptResult.Message = string.Empty;
                    }
                    else
                    {
                        promptResult.Message = queryResult.Message;
                    }
                }
                else
                {
                    promptResult.Message = queryResult.Message;
                }
            }
            _queryTasks.TryRemove(task.TaskId, out _);
            return promptResult;
        }


        [HttpPost]
        public async Task<PromptResult> CreateVideo([FromBody] VideoRequestInfo videoInfo)
        {
            if (videoInfo.ImageUrls == null || videoInfo.ImageUrls.Length == 0)
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "ImageUrls不能为空"
                };
            }
            if (string.IsNullOrWhiteSpace(videoInfo.Prompt))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "Prompt不能为空"
                };
            }
            if (string.IsNullOrWhiteSpace(videoInfo.AspectRatio))
            {
                return new PromptResult
                {
                    Code = -2,
                    Message = "AspectRatio参数不能为空"
                };
            }

            var videoRequest = new VideoRequestInfo
            {
                AspectRatio = videoInfo.AspectRatio,
                Seed = -1,
                ImageUrls = videoInfo.ImageUrls,
                Prompt = videoInfo.Prompt
            };

            RequestInfo info = GetVolRequestInfo(videoRequest, "CVSync2AsyncSubmitTask");

            var result = await HttpVolTool.RequestVol<VolResult>(info, _volInfos!);

            var promptResult = new PromptResult();

            if (result != null)
            {
                promptResult.Code = result.Code;
                if (result!.Code == 10000)
                {
                    promptResult.TaskId = result!.Data!.TaskId;
                }
                else
                {
                    promptResult.Message = result.Message;
                }
            }
            return promptResult;
        }

        //[HttpPost]
        //public void Test([FromBody] PromptInfo promptInfo)
        //{
        //    _textToImageModel.TextToImage("一架飞机，飞在蔚蓝的天空上，旁边飘着几朵白云", @"D:\111.bmp");
        //}
    }
}
