using DocumentFormat.OpenXml.EMMA;
using Elastic.Clients.Elasticsearch;
using Furion.Logging;
using Furion.RemoteRequest.Extensions;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Reflection.PortableExecutable;
using System.Text;
using WCS.Application.Entity;
using WCS.Application.Util;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBBatchCreateContainerServiceVersionResponse.Types;

namespace WCS.Application;
public class HttpService
{
    private dynamic Urls;

    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); 
    private static Dictionary<string, string> dicConverCar = new Dictionary<string, string>();
    public HttpService()
    {
        var _sysConfigService = App.GetService<SysConfigService>();
        Urls = _sysConfigService.GetSystemInfo().Result;
        dicConverCar = new Dictionary<string, string>
        {
            {"013","190601"},
            {"014","191201"},
            {"015","190602"},
            {"016","191202"},

            {"002","030401"},
            {"006","030402"},
            {"003","030601"},
            {"007","030602"},
            {"005","031201"},
            {"008","031202"},
        };
    }

    /// <summary>
    /// 调用WMS接口申请叠托机空托入库接口
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public string RequestLiKuPallet(NullPallInRequest model)
    {
        string returnStr = "";

        var task = _db.Queryable<WcsTask>().First(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.TaskType == TaskTypeEnum.In && m.PalletNo == model.PalletNo);

        if (task == null)
        {
            string url = Urls.WMSAddress + ":" + Urls.WMSPort;
            var result = (url + "/api/DownAPi/RequestPalletIn").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasks>().Result;
            Log.Information("调用WMS接口反馈空托入库任务接口" + result.ToJson());
            if (result.Success == 0)
            {

                var taskAdd = new WcsTask()
                {
                    TaskType = TaskTypeEnum.In,
                    Status = TaskStatusEnum.Wait,
                    Type = PLCTypeEnum.AGV,
                    Origin = "WMS",

                    Qty = result.TaskList.Qty,
                    PalletNo = model.PalletNo,
                    TaskNo = result.TaskList.TaskNo,
                    Levels = 999,

                    StartLocate = model.Locate,
                    StartRoadway = result.TaskList.StartRoadway,
                    EndLocate = result.TaskList.EndLocate,
                    EndRoadway = result.TaskList.EndRoadway,
                    TaskId = FourWayCarUtil.GetTaskId()
                };

                _db.Insertable(taskAdd).ExecuteCommand();
                
                returnStr = result.TaskList.EndLocate;

            }
            else
            {
                returnStr = "-1:" + result.Message;
                return returnStr;
            }
        }
        else
        {
            returnStr = task.EndLocate; 
        }

        return returnStr;
    }

    /// <summary>
    /// 调用WMS接口申请巷道接口
    /// </summary>
    /// <param name="palletNo"></param>
    /// <param name="startLocat"></param> 
    /// <param name="endLocat"></param>
    /// <param name="taskNo"></param>
    /// <returns></returns>
    public string RequestRoadWay(string palletNo, string startLocat, ref string endLocat, ref string taskNo)
    {
        string returnStr = "";
        var stationNum = startLocat.PadLeft(3, '0');

        var task = _db.Queryable<WcsTask>().First(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.TaskType == TaskTypeEnum.In && m.PalletNo == palletNo);

        if (task == null)
        {
            var model = new RequestAsnTask()
            {
                PalletNo = palletNo,
                HouseNo = "W01"
            };

            string url = Urls.WMSAddress + ":" + Urls.WMSPort;
            var result = (url + "/api/DownAPi/RequestMiJiRoadWay").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasks>().Result;
            Log.Information("调用WMS接口反馈任务接口" + result.ToJson());
            if (result.Success == 0)
            {

                var taskAdd = new WcsTask()
                {
                    TaskType = TaskTypeEnum.In,
                    Status = TaskStatusEnum.Wait,
                    Type = PLCTypeEnum.ConveyorLine,
                    Origin = "WMS",
                    StartLocate = startLocat,
                    PalletNo = palletNo,
                    TaskNo = result.TaskList.TaskNo,
                    Levels = 999,
                    EndLocate = result.TaskList.EndLocate,
                    EndRoadway = result.TaskList.EndRoadway,
                    TaskId = FourWayCarUtil.GetTaskId()
                };
                
                var endLocat2 = PLCCommon.RoadwayToStationNum(taskAdd.EndRoadway, stationNum);
                taskAdd.StartRoadway = dicConverCar[endLocat2];
                _db.Insertable(taskAdd).ExecuteCommand();
                endLocat = result.TaskList.EndRoadway;
                taskNo = result.TaskList.TaskNo;
                returnStr = result.TaskList.EndLocate;

            }
            else
            {
                returnStr = "-1:" + result.Message;
                return returnStr;
            }
        }
        else
        {
            returnStr = task.EndLocate;
            endLocat = task.EndRoadway;
            taskNo = task.TaskNo;
        }

        endLocat = PLCCommon.RoadwayToStationNum(endLocat, stationNum);

        return returnStr;
    }

    /// <summary>
    /// 调用WMS接口申请储位接口
    /// </summary>
    /// <param name="palletNo"></param>
    /// <param name="taskId"></param>
    /// <param name="taskNo"></param>
    /// <returns></returns>
    public string RequestLocate(string palletNo, int taskId,ref string taskNo)
    {
        string returnStr = "";
        
        var task = _db.Queryable<WcsTask>().First(m => m.IsDelete == false
        && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing)
        && m.TaskType == TaskTypeEnum.In && m.PalletNo == palletNo && m.TaskId == taskId);

        if (task != null)
        {
            var model = new RequestAsnTask()
            {
                PalletNo = palletNo,
                HouseNo = "W01",
                RoadWayNo = task.EndRoadway,
            };
             
            string url = Urls.WMSAddress + ":" + Urls.WMSPort;
            var result = (url + "/api/DownAPi/RequestMiJiLocation").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasks>().Result;
            Log.Information("调用WMS申请储位接口反馈任务接口" + result.ToJson());
            if (result.Success == 0)
            {
                task.Status = TaskStatusEnum.Wait; 
                task.Type = PLCTypeEnum.ShuttleCar;
                task.EndLocate = result.TaskList.EndLocate;
                _db.Updateable(task).ExecuteCommand();
                HubUtil.PublicTask(task.Adapt<WcsTaskOutput>());
                
                returnStr = result.TaskList.EndLocate;
                taskNo = result.TaskList.TaskNo;
            }
            else
            {
                returnStr = "-1:" + result.Message;
                return returnStr;
            }
        }
        else
        {
            returnStr = "-1:没有找到任务";
        }

        return returnStr;
    }


    /// <summary>
    /// 调用WMS接口 反馈任务接口
    /// </summary>
    /// <param name="model">任务完成状态</param>
    /// <returns></returns>
    public async Task<ResponseModel> RequestTask(TaskRequestWMS model)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/ReceiveWcsSignal").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseModel>();
        Log.Information("调用WMS接口反馈任务接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用WMS接口 反馈任务取货完成接口
    /// </summary>
    /// <param name="model">任务完成状态</param>
    /// <returns></returns>
    public async Task<ResponseModel> RequestTaskQh(TaskRequestWMS model)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/UpLocateByAgvOut").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseModel>();
        Log.Information("调用WMS接口-反馈任务取货完成接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用WMS接口反馈空取异常接口
    /// </summary>
    /// <param name="model">任务信息</param>
    /// <returns></returns>
    public async Task<ResponseTasks> RequestEmptyException(TaskRequest model)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/EmptyException").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasks>();
        Log.Information("调用WMS接口反馈空取异常接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用WMS接口反馈满取异常接口
    /// </summary>
    /// <param name="model">任务信息</param>
    /// <returns></returns>
    public async Task<ResponseTasks> RequestFullException(TaskRequest model)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/FullException").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasks>();
        Log.Information("调用WMS接口反馈满取异常接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用WMS接口申请空托跺出库
    /// </summary>
    /// <param name="Num"></param>
    /// <param name="OutMode"></param>
    /// <returns></returns>
    public string IssuePlnOutHouseWcs(string Num, string OutMode)
    {
        string returnStr = "";

        var model = new OutPalletModel()
        {
            Num = Num,//出库跺数
            OutMode = OutMode//出库口
        };
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = (url + "/api/DownAPi/IssuePlnOutHouseWcs").SetBody(model, "application/json", Encoding.UTF8).PostAsAsync<ResponseOutPallet>().Result;
        Log.Information("调用WMS接口反馈任务接口" + result.ToJson());

        if (result.Success == 0)
        {
            foreach (var item in result.TaskList)
            {
                var taskUp = _db.Queryable<WcsTask>().First(m => m.IsDelete == false && m.TaskNo == item.TaskNo);
                if (taskUp == null)
                {
                    var taskAdd = new WcsTask()
                    {
                        TaskNo = item.TaskNo,
                        TaskType = (TaskTypeEnum)(int.Parse(item.TaskType)),
                        Status = TaskStatusEnum.Wait,
                        //IsSuccess =TaskSuccessEnum.Success,
                        Origin = "WMS",
                        StartLocate = item.StartLocate,
                        StartRoadway = item.StartRoadway,
                        PalletNo = item.PalletNo,
                        EndLocate = item.EndLocate,
                        EndRoadway = item.EndRoadway
                    };
                    _db.Insertable(taskAdd).ExecuteCommand();
                    HubUtil.PublicTask(taskAdd.Adapt<WcsTaskOutput>());
                }
                else
                {
                    taskUp.EndRoadway = item.EndRoadway;
                    taskUp.EndLocate = item.EndLocate;
                    _db.Updateable(taskUp).ExecuteCommand();
                    HubUtil.PublicTask(taskUp.Adapt<WcsTaskOutput>());
                }
            }
        }
        else
        {
            returnStr = "-1:" + result.Message;
            return returnStr;
        }
        return returnStr;
    }
    /// <summary>
    /// 调用WMS接口申请巷道接口
    /// </summary>
    /// <param name="palletNo"></param>
    /// <returns></returns>
    public async Task<ResponseTasksModel> RequestRoadway(string palletNo)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/RequestRoadway").SetBody(palletNo, "application/json", Encoding.UTF8).PostAsAsync<ResponseTasksModel>();
        Log.Information("调用WMS接口申请巷道接口" + result.ToJson());
        return result;
    }
    /// <summary>
    /// 调用WMS接口申请工位接口
    /// </summary>
    /// <returns></returns>
    public async Task<ResponseStationModel> RequestStationNum(RequestStation mod)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/RequestStationNum").SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseStationModel>();
        Log.Information("调用WMS接口申请工位接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用WMS接口C口到A口完成回写
    /// </summary>
    /// <returns></returns>
    public async Task<ResponseStationModel> EditLogPalletTask(RequestStation mod)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/EditLogPalletTask").SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseStationModel>();
        Log.Information("调用WMS接口C口到A口完成回写" + result.ToJson());
        return result;
    }
    /// <summary>
    /// 调用WMS接口申请2楼工位接口
    /// </summary>
    /// <returns></returns>
    public async Task<ResponseStationModel> RequestStationNum2(RequestStation mod)
    {
        string url = Urls.WMSAddress + ":" + Urls.WMSPort;
        var result = await (url + "/api/DownAPi/RequestStationNum2").SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseStationModel>();
        Log.Information("调用WMS接口申请工位接口" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用AGV小车接口下发任务
    /// </summary>
    /// <param name="mod"></param>
    /// <returns></returns>
    public async Task<ResponseAgvDto> GenAgvSendTask(AgvTaskSend mod)
    {
        string url = Urls.RCSAddress + "/rcs/rtas/api/robot/controller/task/submit";
        var requestId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
        var dic = new Dictionary<string, string>()
        {
            {"X-lr-request-id",requestId },
            {"X-lr-version","4.2" },
        };
        Log.Information("调用AGV小车接口下发任务记录" + mod.ToJson());
        var result = await url.SetHeaders(dic).SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseAgvDto>();
        Log.Information("调用AGV小车接口下发任务" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用AGV小车接口继续执行任务
    /// </summary>
    /// <param name="taskNo">任务号</param>
    /// <returns></returns>
    public async Task<ResponseAgvDto> GenAgvContinueTask(string taskNo)
    {
        

        string url = Urls.RCSAddress + "/rcs/rtas/api/robot/controller/task/continue";
        var requestId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
        var dic = new Dictionary<string, object>()
        {
            {"X-lr-request-id",requestId },
            {"X-lr-version","4.2" },
        };
        var mod = new
        {
            robotTaskCode = taskNo
        };

        var result = await url.SetHeaders(dic).SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseAgvDto>();
        Log.Information("调用AGV小车接口继续执行任务" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用AGV小车接口 载具(托盘)与站点(储位)解绑定接口
    /// </summary>
    /// <param name="palletNo">托盘号</param>
    /// <param name="locateNo">储位号</param>
    /// <returns></returns>
    public async Task<ResponseAgvDto> GenAgvUnbind(string palletNo,string locateNo)
    {


        string url = Urls.RCSAddress + "/rcs/rtas/api/robot/controller/carrier/unbind";
        var requestId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
        var dic = new Dictionary<string, string>()
        {
            {"X-lr-request-id",requestId },
            {"X-lr-version","4.2" },
        };
        var mod = new
        {
            carrierCode = palletNo,
            siteCode = locateNo
        };
         
        var result = await url.SetHeaders(dic).SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<ResponseAgvDto>();
        Log.Information("调用AGV小车接口继续执行任务" + result.ToJson());
        return result;
    }

    /// <summary>
    /// 调用AGV小车接口反馈开门成功
    /// </summary>
    /// <param name="mod"></param>
    /// <returns></returns>
    public async Task<AgvResponse2> NotifyExcuteResultInfo(AgvNotifyInput mod)
    {
        string url = Urls.RCSAddress + ":" + Urls.RCSPort;
        var result = await (url + "/rcms/services/rest/liftCtlService/notifyExcuteResultInfo").SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<AgvResponse2>();
        Log.Information("调用AGV小车接口反馈开门成功" + result.ToJson());
        return result;
    }
    /// <summary>
    /// 调用AGV小车接口取消任务
    /// </summary>
    /// <param name="mod"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    public async Task<AgvResponse> CancelTask(CancelTaskModel mod)
    {
        string url = Urls.RCSAddress + ":" + Urls.RCSPort;
        var result = await (url + "/rcms/services/rest/hikRpcService/cancelTask").SetBody(mod, "application/json", Encoding.UTF8).PostAsAsync<AgvResponse>();
        Log.Information("调用AGV小车接口取消任务" + result.ToJson());
        return result;
    }
}