using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using MisDataSaveDate.Helper;
using static MisDataSaveDate.Helper.ApiLogHelper;
using WebApi;

namespace MisDataSaveDate
{
    /// <summary>
    /// 临工AGV接口业务处理。
    /// </summary>
    public class LGAGV_BusinessLogic
    {
        private const string DirectionMesToAgv = "MES_TO_AGV";
        private const string DirectionAgvToMes = "AGV_TO_MES";

        /// <summary>
        /// MES调用临工AGV两点任务接口。
        /// </summary>
        public static LGAGV_CallResult CallAddTask(LGAGV_AddTaskRequest request)
        {
            if (request == null)
            {
                throw new Exception("AGV任务参数不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.requestTaskId))
            {
                throw new Exception("任务ID(requestTaskId)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.startPosition))
            {
                throw new Exception("起点位置(startPosition)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.endPosition))
            {
                throw new Exception("终点位置(endPosition)不能为空");
            }

            return PostToAgv("AddTaskFromMes", "/api/mes/AddTaskFromMes", request,
                request.requestTaskId, null, request.endPosition, null, request.materialCode, null);
        }

        /// <summary>
        /// MES调用临工AGV三点任务接口。
        /// </summary>
        public static LGAGV_CallResult CallAddTask2(LGAGV_AddTask2Request request)
        {
            if (request == null)
            {
                throw new Exception("AGV任务参数不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.requestTaskId))
            {
                throw new Exception("任务ID(requestTaskId)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.startPosition))
            {
                throw new Exception("起点位置(startPosition)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.midPosition))
            {
                throw new Exception("中间位置(midPosition)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.endPosition))
            {
                throw new Exception("终点位置(endPosition)不能为空");
            }

            return PostToAgv("AddTaskFromMes2", "/api/mes/AddTaskFromMes2", request,
                request.requestTaskId, null, request.endPosition, null, request.materialCode, null);
        }

        /// <summary>
        /// MES调用临工AGV放行接口。
        /// </summary>
        public static LGAGV_CallResult CallAllowLeave(LGAGV_AllowLeaveRequest request)
        {
            if (request == null)
            {
                throw new Exception("放行参数不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.requestId))
            {
                throw new Exception("请求ID(requestId)不能为空");
            }
            if (string.IsNullOrWhiteSpace(request.position))
            {
                throw new Exception("位置(position)不能为空");
            }

            request.allowLeave = 1;
            return PostToAgv("AllowLeave", "/api/mes/AllowLeave", request,
                null, request.requestId, request.position, null, null, request.agvNo);
        }

        /// <summary>
        /// 处理临工AGV到达/离开回调。
        /// </summary>
        public static string ProcessStatusUpdate(string url, [FromBody] JObject jobj)
        {
            var result = LGAGV_Response.Success();
            string requestText = jobj?.ToString() ?? "";
            SaveLog_Interface_Request(url, 2, requestText, out int aid);

            LGAGV_StatusUpdateRequest request = null;
            try
            {
                if (jobj == null)
                {
                    throw new Exception("请求参数不能为空");
                }

                request = JsonConvert.DeserializeObject<LGAGV_StatusUpdateRequest>(requestText);
                if (request == null)
                {
                    throw new Exception("请求参数格式不正确");
                }
                if (string.IsNullOrWhiteSpace(request.requestId))
                {
                    throw new Exception("请求ID(requestId)不能为空");
                }
                if (string.IsNullOrWhiteSpace(request.position))
                {
                    throw new Exception("位置(position)不能为空");
                }
                if (request.type != 1 && request.type != 2)
                {
                    throw new Exception("类型(type)只支持1到达、2离开");
                }

                string procedureName = request.type == 1 ? "LG_AGV_库位Moby_AGV到达" : "LG_AGV_库位Moby_AGV离开";
                var param = new SqlParameter[]
                {
                    new SqlParameter("@requestId", request.requestId ?? ""),
                    new SqlParameter("@position", request.position ?? ""),
                    new SqlParameter("@materialCode", request.materialCode ?? ""),
                    new SqlParameter("@agvNo", request.agvNo ?? "")
                };
                ExecuteResultProcedure(procedureName, ref param);

                SaveInterfaceRecord("StatusUpdate", DirectionAgvToMes, request.position, request.position,
                    null, request.requestId, request.position, request.type, request.materialCode, request.agvNo,
                    "", requestText, "", 1, "");

                string typeDesc = request.type == 1 ? "到达" : "离开";
                SaveMesLog("LGAGV_StatusUpdate", $"临工AGV{typeDesc}：位置={request.position}, requestId={request.requestId}, AGV={request.agvNo}", MesLogType.INFO);
            }
            catch (Exception ex)
            {
                result = LGAGV_Response.Fail(ex.Message);
                SaveInterfaceRecord("StatusUpdate", DirectionAgvToMes, request?.position, request?.position,
                    null, request?.requestId, request?.position, request?.type, request?.materialCode, request?.agvNo,
                    "", requestText, "", 2, ex.Message);
                SaveMesLog("LGAGV_StatusUpdate", ex.Message, MesLogType.ERROR);
            }

            string responseText = JsonConvert.SerializeObject(result);
            SaveLog_Interface_Response(responseText, aid);
            return responseText;
        }

        /// <summary>
        /// 处理临工AGV任务结果回调。
        /// </summary>
        public static string ProcessTaskResult(string url, [FromBody] JObject jobj)
        {
            var result = LGAGV_Response.Success();
            string requestText = jobj?.ToString() ?? "";
            SaveLog_Interface_Request(url, 2, requestText, out int aid);

            LGAGV_TaskResultRequest request = null;
            try
            {
                if (jobj == null)
                {
                    throw new Exception("请求参数不能为空");
                }

                request = JsonConvert.DeserializeObject<LGAGV_TaskResultRequest>(requestText);
                if (request == null)
                {
                    throw new Exception("请求参数格式不正确");
                }
                if (string.IsNullOrWhiteSpace(request.requestTaskId))
                {
                    throw new Exception("任务ID(requestTaskId)不能为空");
                }

                bool isSuccess = IsAgvSuccess(request.status);
                var param = new SqlParameter[]
                {
                    new SqlParameter("@requestTaskId", request.requestTaskId ?? ""),
                    new SqlParameter("@status", request.status ?? ""),
                    new SqlParameter("@agvNo", request.agvNo ?? ""),
                    new SqlParameter("@message", request.message ?? ""),
                    new SqlParameter("@materialCode", request.materialCode ?? "")
                };
                ExecuteResultProcedure("LG_AGV_库位Moby_任务结果", ref param);

                SaveInterfaceRecord("TaskResult", DirectionAgvToMes, null, null,
                    request.requestTaskId, null, null, null, request.materialCode, request.agvNo, request.status,
                    requestText, "", isSuccess ? 1 : 2, request.message ?? "");

                SaveMesLog("LGAGV_TaskResult", $"临工AGV任务结果：requestTaskId={request.requestTaskId}, status={request.status}, AGV={request.agvNo}, message={request.message}", MesLogType.INFO);
            }
            catch (Exception ex)
            {
                result = LGAGV_Response.Fail(ex.Message);
                SaveInterfaceRecord("TaskResult", DirectionAgvToMes, null, null,
                    request?.requestTaskId, null, null, null, request?.materialCode, request?.agvNo, request?.status,
                    requestText, "", 2, ex.Message);
                SaveMesLog("LGAGV_TaskResult", ex.Message, MesLogType.ERROR);
            }

            string responseText = JsonConvert.SerializeObject(result);
            SaveLog_Interface_Response(responseText, aid);
            return responseText;
        }

        public static void SaveInterfaceRecord(string interfaceName, string direction, string positionCode, string workStation,
            string requestTaskId, string requestId, string position, int? type, string materialCode, string agvNo, string status,
            string requestText, string responseText, int isSuccess, string errorMessage)
        {
            var param = new SqlParameter[]
            {
                new SqlParameter("@库位号", positionCode ?? ""),
                new SqlParameter("@工位号", workStation ?? ""),
                new SqlParameter("@接口名称", interfaceName ?? ""),
                new SqlParameter("@接口方向", direction ?? ""),
                new SqlParameter("@requestTaskId", requestTaskId ?? ""),
                new SqlParameter("@requestId", requestId ?? ""),
                new SqlParameter("@position", position ?? ""),
                new SqlParameter("@type", type.HasValue ? (object)type.Value : DBNull.Value),
                new SqlParameter("@materialCode", materialCode ?? ""),
                new SqlParameter("@agvNo", agvNo ?? ""),
                new SqlParameter("@status", status ?? ""),
                new SqlParameter("@message", errorMessage ?? ""),
                new SqlParameter("@请求报文", requestText ?? ""),
                new SqlParameter("@响应报文", responseText ?? ""),
                new SqlParameter("@是否成功", isSuccess),
                new SqlParameter("@错误信息", errorMessage ?? "")
            };
            DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("LG_AGV_接口记录_增加", ref param, out string errMessage);
            if (!string.IsNullOrEmpty(errMessage))
            {
                SaveMesLog("LGAGV_InterfaceRecord", errMessage, MesLogType.ERROR);
            }
        }

        public static bool IsAgvSuccess(string codeOrStatus)
        {
            string value = (codeOrStatus ?? "").Trim().ToLower();
            return value == "0" || value == "200" || value == "true" || value == "success" || value == "成功";
        }

        private static LGAGV_CallResult PostToAgv(string interfaceName, string path, object request,
            string requestTaskId, string requestId, string position, int? type, string materialCode, string agvNo)
        {
            string baseUrl = ConfigurationManager.AppSettings["LGAGV_BaseUrl"];
            if (string.IsNullOrWhiteSpace(baseUrl))
            {
                throw new Exception("未配置 LGAGV_BaseUrl");
            }

            string interfaceUrl = baseUrl.TrimEnd('/') + path;
            string requestText = JsonConvert.SerializeObject(request);
            SaveLog_Interface_Request("LGAGV_" + interfaceName, 1, requestText, out int aid);

            string responseText = Post.Post_Auto(interfaceUrl, requestText);
            SaveLog_Interface_Response(responseText, aid);

            JObject response = ParseResponse(responseText);
            string codeText = response["code"]?.ToString() ?? response["result"]?.ToString() ?? "";
            string message = response["desc"]?.ToString() ?? response["message"]?.ToString() ?? response["msg"]?.ToString() ?? "";
            bool success = IsAgvSuccess(codeText);
            if (response["success"] != null)
            {
                if (bool.TryParse(response["success"].ToString(), out bool successValue))
                {
                    success = successValue;
                }
            }

            SaveInterfaceRecord(interfaceName, DirectionMesToAgv, position, position, requestTaskId, requestId, position,
                type, materialCode, agvNo, codeText, requestText, responseText, success ? 1 : 2, success ? "" : message);

            if (success)
            {
                SaveMesLog("LGAGV_" + interfaceName, $"临工AGV接口调用成功：{interfaceName}, position={position}, requestTaskId={requestTaskId}", MesLogType.INFO);
            }
            else
            {
                SaveMesLog("LGAGV_" + interfaceName, $"临工AGV接口调用失败：{interfaceName}, code={codeText}, message={message}", MesLogType.ERROR);
            }

            return new LGAGV_CallResult
            {
                Success = success,
                Code = ToInt(codeText, success ? 0 : 500),
                Message = message,
                InterfaceUrl = interfaceUrl,
                RequestText = requestText,
                ResponseText = responseText,
                Response = response
            };
        }

        private static JObject ParseResponse(string responseText)
        {
            if (string.IsNullOrWhiteSpace(responseText))
            {
                return new JObject
                {
                    { "code", 500 },
                    { "message", "AGV返回空响应" },
                    { "success", false }
                };
            }

            try
            {
                return JObject.Parse(responseText);
            }
            catch (Exception ex)
            {
                return new JObject
                {
                    { "code", 500 },
                    { "message", "AGV返回非JSON响应：" + ex.Message },
                    { "raw", responseText },
                    { "success", false }
                };
            }
        }

        private static int ToInt(string value, int defaultValue)
        {
            if (int.TryParse(value, out int intValue))
            {
                return intValue;
            }
            return defaultValue;
        }

        private static void ExecuteResultProcedure(string procedureName, ref SqlParameter[] param)
        {
            DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure(procedureName, ref param, out DataTable dt, out string errMessage);
            if (!string.IsNullOrEmpty(errMessage))
            {
                throw new Exception(errMessage);
            }
            if (dt != null && dt.Rows.Count > 0 && dt.Columns.Contains("result") && dt.Rows[0]["result"].ToString() != "1")
            {
                string msg = dt.Columns.Contains("msg") ? dt.Rows[0]["msg"].ToString() : "存储过程执行失败";
                throw new Exception(msg);
            }
        }
    }
}
