using Common;
using DeviceLibrary.bean;
using DeviceLibrary.manager;
using DeviceLibrary.service.model;
using System;

namespace DeviceLibrary
{
    public abstract class Job
    {
        public Job(JobParam jobParam)
        {
            JobParam = jobParam;
            if (jobParam != null && jobParam.GetMissionInfo() != null)
                JobName = jobParam.GetMissionInfo().JobName;
        }
        public Job() { }
        public JobParam JobParam { get; set; }

        public JobStep<RunStep> JobRunStep = new JobStep<RunStep>(RunStep.NONE);
        /// <summary>
        /// Job里的agv任务信息
        /// </summary>
        public AgvTask Task { get; set; }
        /// <summary>
        /// 运行信息
        /// </summary>
        public string RunInfo { get { return $"{JobName} {TaskStateInfo}{FixInfo}:{runInfo}"; } }
        /// <summary>
        /// agv任务状态信息
        /// </summary>
        public string TaskStateInfo = "";
        public string FixInfo = "";
        public string runInfo = "";
        /// <summary>
        /// 等待人员操作超时时间
        /// </summary>
        public int WaitTimeOut = AppConfigHelper.GetIntValue(SettingString.WaitTimeout);
        /// <summary>
        /// 根据任务状态继续执行任务
        /// </summary>
        public Job Execute(AgvInfo agv)
        {
            SetRunInfo(agv);
            return Run(agv);
        }
        public abstract Job Run(AgvInfo agv);
        /// <summary>
        /// 设置相关运行信息
        /// </summary>
        /// <param name="agv"></param>
        public void SetRunInfo(AgvInfo agv)
        {
            JobRunStep.Agv = agv.Name;
            JobRunStep.StepRunInfo.SetInfo(agv.Name.PadLeft(4, '0'), JobName, agv.Place.AliceName, JobRunStep.CurStep(), runInfo, StartJobTime, DateTime.Now);
            TaskStateInfo = agv.TaskRunState.ToTaskInfo();
            //FixInfo = JobParam.FixMissionInfo != null ? JobParam.FixMissionInfo.ToTxt():"";
            StartJobTime = JobRunStep.startTime;
        }
        /// <summary>
        /// Job开始时间
        /// </summary>
        public DateTime StartJobTime { get; set; } = DateTime.Now;
        /// <summary>
        /// Job名称
        /// </summary>
        public string JobName { get; set; } = "";

        protected void AllocateTask(AgvInfo agv, string taskName)
        {
            Task = AgvTaskManager.GetTaskByName(taskName,agv);
            AgvTaskManager.AssignMission(agv, taskName);
        }
        protected void AllocateTask(AgvInfo agv,ChargePile chargePile)
        {
            Task = new AgvTask() { AliceName = chargePile.AliceName, Name = chargePile.Name, Guid=chargePile.Guid};
            AgvTaskManager.AssignMission(agv, chargePile,Task);
        }
        protected void AllocateStandbyTask(AgvInfo agv)
        {
            Task = AgvTaskManager.GetTaskByName($"{SettingString.Standby}", agv);
            AgvTaskManager.AssignMission(agv, $"{SettingString.Standby}");
        }
        /// <summary>
        /// 设置PLC值
        /// </summary>
        /// <param name="agv"></param>
        /// <param name="port"></param>
        /// <param name="val"></param>
        protected void SetPlc(AgvInfo agv, int port, int val)
        {
            int times = 0;
            while (!MiR_API.Set_Register(agv, port, val))
            {
                if (times > 5)
                    break;
            }
        }
        /// <summary>
        /// 入库类型-1
        /// </summary>
        /// <param name="agv"></param>
        protected void SetPlcWithToInstore(AgvInfo agv)
        {
            SetPlc(agv, 51, 1);
        }
        /// <summary>
        /// 出库类型-2
        /// </summary>
        /// <param name="agv"></param>
        protected void SetPlcWithToOutstore(AgvInfo agv)
        {
            SetPlc(agv, 51, 2);
        }

        protected void CloseSound(AgvInfo agv)
        {
            SetPlc(agv, 51, 0);
        }
        /// <summary>
        /// 任务重发
        /// </summary>
        /// <returns></returns>
        public bool ResendTask(AgvInfo agv)
        {
            bool rtn = false;
            if (!Task.Equals(agv.TaskRunState.Task))//agv运行的任务与Job任务不同
            {
                rtn = AgvTaskManager.AssignMission(agv, Task.Name);
                if (rtn)
                {
                    return true;
                }
            }
            else if (!agv.TaskRunState.TaskID.Equals(-1))
            {
                if (agv.TaskRunState.TaskState.Equals(SettingString.Aborted) || agv.TaskRunState.TaskState.Equals(SettingString.Invalid))
                {
                    rtn = AgvTaskManager.AssignMission(agv, Task.Name);
                    if (rtn)
                    {
                        return true;
                    }

                }
            }
            else if (agv.TaskRunState.TaskID.Equals(-1))//任务发送失败,重新发送
            {
                rtn = AgvTaskManager.AssignMission(agv, Task.Name);
                if (rtn)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 是否需要确认
        /// </summary>
        /// <returns></returns>
        protected bool NeedConfirm()
        {
            if(JobParam.GetMissionInfo()!=null)
            {
                service.model.ProjectType type =  JobParam.GetMissionInfo().projectType;
                if(type.Equals(service.model.ProjectType.空台车领用) || type.Equals(service.model.ProjectType.空台车归还))
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 清除AGV占用的任务
        /// </summary>
        /// <param name="missionInfo"></param>
        protected void ResetOccupiedAgv(MissionInfo missionInfo)
        {
            missionInfo.ResetOccupied();
        }
    }
}