using System.Text;
using Autofac;
using Entity.Attr;
using Entity.Constant;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using log4net;
using Newtonsoft.Json;
using Repository.Station;
using Service.Execute.Api;
using Service.Execute.Model;
using Service.Execute.StaticTools;
using Service.Execute.SwapException;
using Service.Execute.Utils;
using Service.Init;
using Service.Station;
using Swapping.Business.Common;

namespace Service.Execute.Step;

public class StationReadyState : IState
{
    private readonly ILog _log = LogManager.GetLogger(typeof(StationReadyState));


    private readonly CommonMgr _CommonMgr = AppInfo.Container.Resolve<CommonMgr>();

    public static bool CanWelcomeInfo = true;

    public StateResult Handle(SwappingStateMachine machine)
    {
        _log.Info($"'goto stationReady");

        machine.Reset();
        machine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.Idle;
        machine.BusinessSwappingStateUpdateTime = DateTime.Now;

        //判断换电站是否具备换电条件
        if (!IsAutoSwapping())
        {
            return null;
        }

        //plc是否是远程模式
        var plcIsAuto = PlcIsAuto(machine);
        if (InvokeStatus.Done != plcIsAuto)
        {
            return SwappingStateMachine.ReturnWithInvokeErr(plcIsAuto, ExceptionReason.None);
        }

        //plc是否是远程模式
        var plcIsRemote = PlcIsRemote(machine);
        if (InvokeStatus.Done != plcIsRemote)
        {
            return SwappingStateMachine.ReturnWithInvokeErr(plcIsRemote, ExceptionReason.None);
        }


        //监测雷达
        var entranceRadar = EntranceRadar(machine);

        if (InvokeStatus.Done != entranceRadar)
        {
            return SwappingStateMachine.ReturnWithInvokeErr(entranceRadar, ExceptionReason.None);
        }


        //开始读rifd
        var beginRfid = BeginRead(machine);
        if (InvokeStatus.Done != beginRfid)
        {
            return SwappingStateMachine.ReturnWithInvokeErr(beginRfid, ExceptionReason.None);
        }


        // 读取rfid
        var readRfid = ReadRfid(machine);
        if (InvokeStatus.Done != readRfid)
        {
            return SwappingStateMachine.ReturnWithInvokeErr(readRfid, ExceptionReason.ReadRfidError);
        }

        return new StateResult()
        {
            SwappingState = SwappingState.CarPrepare,
        };
    }

    public InvokeStatus PlcIsAuto(SwappingStateMachine machine)
    {
        bool isAuto = false;
        return Invoker.Invoke("check plc auto", 1000, 5, machine.IsCanceled, () => isAuto,
            () =>
            {
                if (PlcApi.IsAuto())
                {
                    isAuto = true;
                }
            },
            () =>
            {
                SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoStationModel)
                    ;
            }, true, () => { }, 5, InvokeStatus.None);
    }


    public InvokeStatus PlcIsRemote(SwappingStateMachine machine)
    {
        bool isRemote = false;
        return Invoker.Invoke("check plc remote", 1000, 5, machine.IsCanceled, () => isRemote,
            () =>
            {
                if (PlcApi.IsRemote())
                {
                    //写入口灯绿灯
                    if (PlcApi.WriteEntranceLamp(1000))
                    {
                        //LED显示-欢迎光临_换电站点_正在营业
                        if (CanWelcomeInfo)
                        {
                            SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.WelcomeInfo);
                            CanWelcomeInfo = false;
                        }
                        
                        //  machine.LedTool?.WriteContent(welcomeContent);
                        //查看雷达
                        isRemote = true;
                    }
                }
            },
            () =>
            {
                SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoStationModelRemoteErr)
                    ;
            }, true, () => { }, 5, InvokeStatus.None);
    }

    public InvokeStatus EntranceRadar(SwappingStateMachine machine)
    {
        return Invoker.Invoke("wait entrance radar", 1000, 2, machine.IsCanceled,
            () => machine.RadarInFlag, () =>
            {
                if (!PlcApi.EntranceRadar())
                {
                    _log.Info("entrance radar false");
                }
                else
                {
                    StationReadyState.CanWelcomeInfo = true;
                    SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.CarInInfo);
                    machine.ExceptionReason = ExceptionReason.None;
                    _log.Info("entrance radar true");
                    machine.RadarInFlag = true;
                }
            }, () => { }, true, () => { }, 2, InvokeStatus.TimeOut);
    }

    public InvokeStatus BeginRead(SwappingStateMachine machine)
    {
        return Invoker.Invoke(" BeginRead read rfid", 1000, 20, machine.IsCanceled,
            () => machine.BeginRfidReadFlag, () =>
            {
                Task<bool> beginRead = RfidApi.BeginRead();
                beginRead.Wait();
                if (!beginRead.Result)
                {
                    _log.Info("begin read rfid error");
                }
                else
                {
                    machine.ExceptionReason = ExceptionReason.None;
                    _log.Info("begin read done");
                    machine.BeginRfidReadFlag = true;
                }
            }, () =>
            {
                //   machine.LedTool.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
                SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorReadRfid);
            }, false, () => { machine.ExceptionReason = ExceptionReason.ReadRfidError; }
            , 3, InvokeStatus.None);
    }

    /// <summary>
    /// 判断换电站是否具备换电的条件
    /// 1、换电站状态:
    /// 2、换电站方式:
    /// </summary>
    /// <returns></returns>
    private bool IsAutoSwapping()
    {
        var statusDes =
            BaseEnumExtensions.GetEnumDescriptionByCode<StationConstant.StationStatus>(
                StaticStationInfo.StationStatus);
        _log.Info($"站控处于{statusDes}状态");
        var wayDes =
            BaseEnumExtensions.GetEnumDescriptionByCode<StationConstant.StationWay>(
                StaticStationInfo.StationWay);
        _log.Info($"站控处于{wayDes}模式");

        if (StationConstant.StationStatus.Run ==
            BaseEnumExtensions.GetEnumByCode<StationConstant.StationStatus>(StaticStationInfo.StationStatus)
            && StationConstant.StationWay.Auto ==
            BaseEnumExtensions.GetEnumByCode<StationConstant.StationWay>(StaticStationInfo.StationWay))
        {
            return true;
        }

        return false;
    }

    private InvokeStatus ReadRfid(SwappingStateMachine machine)
    {
        //开始读rifd
        return Invoker.Invoke("read rfid", 3000, 20, machine.IsCanceled,
            () => machine.RfidReadFlag, () =>
            {
                Task<RfidReadModel?> rfidReadModel = RfidApi.ReadRfid();
                rfidReadModel.Wait();
                var machineRfidReadModel = rfidReadModel.Result;


                if (rfidReadModel.IsCompletedSuccessfully && machineRfidReadModel != null
                                                          && machineRfidReadModel.Result == 1
                                                          && !string.IsNullOrEmpty(machineRfidReadModel.VelVin))
                {
                    machine.RfidReadModel = machineRfidReadModel;
                    _log.Info($"read rfid={JsonConvert.SerializeObject(machine.RfidReadModel)}");

                    machine.ExceptionReason = ExceptionReason.None;
                    machine.BusinessSwappingStateUpdateTime = DateTime.Now;
                    _log.Info($"BusinessSwappingForCloudState={machine.BusinessSwappingForCloudState}");

                    //新增换电订单
                    machine.SwapOrder = _CommonMgr.SaveOrder(BuildOrder(machine.RfidReadModel));
                    //新增小步
                    _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.Idel,
                        machine);
                    _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.RadarInFlag,
                        machine);
                    _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.RfidReadFlag,
                        machine);
                    RfidApi.StopRead();
                    _log.Info("stop read rfid");
                    RfidApi.DisConnect();
                    machine.RfidReadFlag = true;
                }
            }, () =>
            {
                // machine.LedTool!.WriteProgramContent(InfoEnum.SwapInfo.ErrorReadRfid.GetLed());
                SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorReadRfid);
            }, false, () => { machine.ExceptionReason = ExceptionReason.ReadRfidError; }, 10,
            InvokeStatus.None);
    }


    private SwapOrder BuildOrder(RfidReadModel rfidReadModel)
    {
        SwapOrder swapOrder = new SwapOrder()
        {
            Sn = SwapOrderNoGenerator.GenerateOrderNo(StaticStationInfo.StationNo),
            VehicleVin = rfidReadModel.VelVin,
            VehicleMac = rfidReadModel.VelMac,
            VehicleNo = rfidReadModel.VelNo,
            VehicleEnterTime = DateTime.Now,
        };

        return swapOrder;
    }
}