using SimpleLite.RCS;
using SimpleLite.RCS.CarTypes;
using System;
using System.Collections.Generic;
using System.Linq;

namespace StandardScene.Model
{
    public class TaskRequest
    {
        public string CarCode { get; set; }
        public string CarType { get; set; }
        public string TaskCode { get; set; }
        public string MissionType { get; set; }
        public string TaskType { get; set; }
        public string Material { get; set; }
        public ContainerSize ContainerSize { get; set; }
        public List<Node> Nodes { get; set; }
        public int priority { get; set; }
    }

    public class ContainerSize
    {
        public double Length { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
    }

    public class Node
    {
        public int Code { get; set; }
        //public List<Action> Actions { get; set; }
    }

    public class Action
    {
        public string Code { get; set; }
        public string ActionType { get; set; }
        public string BlockingType { get; set; }
        public List<ActionParameter> Parameters { get; set; }
    }

    public class ActionParameter
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }

    public class BaseRespose<T>
    {
        public bool Success { get; set; }
        public int Code { get; set; } = 200;
        public string Message { get; set; }
        public T Data { get; set; }
    }

    public class BaseRespose
    {
        public bool Success { get; set; } = true;
        public int Code { get; set; } = 200;
        public string Message { get; set; }
    }
    public class CarInfo
    {


        public string Code { get; set; }
        public string Name { get; set; }
        public double Voltage { get; set; }

        public string Address { get; set; }

        public string Speed { get; set; }

        public int siteId { get; set; }

    }
    public class CarStateInfo
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public string CurrState { get; set; }
        public bool IsOnline { get; set; } = false;
        public double Battery { get; set; }
        public double ElectricCurrent { get; set; }
        public double Voltage { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public double Theta { get; set; }
        public double Speed { get; set; }
        public int Load { get; set; }
        public string CurrNodeCode { get; set; }
        public string StartNodeCode { get; set; }
        public string EndNodeCode { get; set; }
        public string CurrEdgeCode { get; set; } = "";
        public string StartEdgeCode { get; set; } = "";
        public string EndEdgeCode { get; set; } = "";
        public List<int> HoldingLocks { get; set; }
        public List<int> PendingLocks { get; set; }
        public List<BlockedByItem> BlockedBy { get; set; }
        public string BlockingTime { get; set; } = "";
        public string TrafficMessage { get; set; } = "";
        public int AquiringLock { get; set; } = -1;
        public bool StopAccept { get; set; } = false;

        public List<CarAlarm> Alarms { get; set; }

        public List<TaskInfo> Tasks { get; set; }

        public List<TaskAction> Actions { get; set; }

    }

    public class BlockedByItem
    {
        public string CarCode { get; set; }
        public int Type { get; set; }
    }

    public class CarAlarm
    {
        public string Code { get; set; }
        public string Name { get; set; }
    }

    public class TaskInfo
    {
        public string Code { get; set; }
        public string State { get; set; }
        public List<ResponseNode> Nodes { get; set; }
    }

    public class TaskAction
    {
        public string Code { get; set; }
        public string ActionType { get; set; }
        public string BlockingType { get; set; }
        public string State { get; set; }
    }

    public class ResponseNode
    {
        public string Code { get; set; }
        //public List<TaskAction> Actions { get; set; }
    }

    public class TaskCancel
    {
        public string TaskCode { get; set; }
        public string MissionType { get; set; }
        public string TaskStatus { get; set; }
    }
    public class TaskRecord
    {
        public string TaskId { get; set; }
        public string Name { get; set; }
        public string CarId { get; set; }
        public string CarName { get; set; }
        public string SrcSiteId { get; set; }
        public string DestSiteId { get; set; }
        public int Priority { get; set; } = 0;
        public string State { get; set; }
        public DateTime? StartTime { get; set; }
        public DateTime? EndTime { get; set; }
        public DateTime Created { get; set; }

    }

    public class CarBaseInfo
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public string CarType { get; set; }
        public double Length { get; set; }
        public double Width { get; set; }
        public string CurrNodeCode { get; set; }
        public string CurrState { get; set; }
        public double Battery { get; set; }
        public string Address { get; set; }
        public double Speed { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public double Theta { get; set; }
        public double Voltage { get; set; }
        public double ElectricCurrent { get; set; }
        public bool IsOnline { get; set; } = false;
        public Dictionary<string, string> Additional { get; set; }

        public CarBaseInfo()
        {
            Additional = new Dictionary<string, string>();
        }

        public static CarBaseInfo FromCar(Car car)
        {
            var info = new CarBaseInfo()
            {
                Code = car.id.ToString(),
                Name = car.name,
                Address = car.address.Equals("/") ? "127.0.0.1" : car.address,
                CurrNodeCode = car.status.holdingLocks.FirstOrDefault().ToString(),
                X = car.x,
                Y = car.y,
                Theta = car.th,
                Speed = car.speed
            };
            //info.Length = car.latestShape.lx;
            //info.Width  = car.latestShape.ly;
            info.CarType = car.fields.ContainsKey("CarType") ? car.fields["CarType"] : "Car";
            info.Battery = car.status.enums.ContainsKey("Soc") ? int.Parse(car.status.enums["Soc"]) : 100;
            info.Voltage = car.status.enums.ContainsKey("Voltage") ? double.Parse(car.status.enums["Voltage"]) : 0;
            info.ElectricCurrent = car.status.enums.ContainsKey("ElectricCurrent") ? double.Parse(car.status.enums["ElectricCurrent"]) : 0;
            var isOnline = false;
            string carState = SwitchCarState(car, ref isOnline);
            info.IsOnline = isOnline;
            info.CurrState = carState;
            return info;
        }

        public static string SwitchCarState(Car car, ref bool isOnline)
        {
            string state = "Stopping";
            if (car.GetLastSite() == -1)
            {
                isOnline = false;
                return state;
            }
            if (Commons.GetVehicleStatus(car)!= VehicleStatus.Offline)
            {
                if (Commons.GetVehicleStatus(car) is VehicleStatus.Normal or VehicleStatus.NeedInit)
                    state = "Stopping"; //Idle
                var lp = car.status.programs.latest;
                if (lp != null)
                {
                    if (
                        lp.status.state >= SimpleCore.Compiler.CarProgram.StatusEnum.Programming
                        && lp.status.state <= SimpleCore.Compiler.CarProgram.StatusEnum.Running
                    )
                    {
                        state = "Running"; //Executing
                    }
                }
                //存在报警信息
                if (car.status.enums.ContainsKey("AlarmInfo"))
                {
                    if (!string.IsNullOrEmpty(car.status.enums["AlarmInfo"]))
                    {
                        state = "Faulting"; //Malfunction
                    }
                }
                if (car.tags.Contains("charging"))
                    state = "Charging";
                isOnline = true;
            }
            else
            {
                isOnline = false;
            }
            return state;
        }
    }
}
