using LessokajiWeaverUtilities.Utilities;
using Simple3.RCS;
using Simple3.RCS.CarTypes;
using Simple3.CADTools;
using Simple3.Props;
using Simple3.UI;
using SimpleCore;
using SimpleCore.Compiler;
using SimpleCore.Library;
using SimpleCore.PropType;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using StandardScene.Utils;

namespace StandardScene.CarTypes
{
    class ArmCarSiteFields:KivaSiteFields
    {
        public bool putNeedTurn = false;
    }

    class ArmCarTrackFields:KivaTrackFields
    {
        
    }

    class ArmCarPlanFields:KivaPlanFields
    {
        public bool charge = false;
    }

    // 自 VDA5050Car.cs 下沉至 Core：ArmCar 的 siteFields 引用它（见下方 [TemplateTrackCoderSettings]）。
    // VDA5050 拆为独立 dll 后 ArmCar 留 Core，不能反依赖 VDA dll，故该字段类置于 Core。
    class VDA5050SiteField : BasicSiteFields
    {
        public bool DI41 = false;
        public int SleepTime = 0;
        public bool workPlace = false;
    }
    //[TemplateTrackCoderSettings(
    //    priority = 1,
    //    templateString = "agv.BasicGo(${src.x},${src.y},${src.id},${dst.x},${dst.y},${dst.id}," +
    //                     "${track.id},${track.Speed},${track.Reverse||(track.ReverseDst==dst.id)}," +
    //                     "${track.CarDirectionBias},${track.EnableCarAbsoluteDirection},${track.CarAbsoluteDirection},${track.typeInfo});",
    //    siteFields = typeof(KivaSiteFields),
    //    trackFields = typeof(KivaTrackFields),
    //    planFields = typeof(KivaPlanFields))]
    //[TemplateSiteCoderSettings(
    //    priority = 5,
    //    useVerb = "plan.action=='fetch'&&plan.curSeg==plan.segN-1",
    //    blockVerb = "true",
    //    templateString = "agv.Wait();agv.Fetch(\"${dst.name}\");agv.Wait();",
    //    siteFields = typeof(ArmCarSiteFields),
    //    trackFields = typeof(ArmCarTrackFields),
    //    planFields = typeof(ArmCarPlanFields))]
    //[TemplateSiteCoderSettings(
    //    priority = 5,
    //    useVerb = "plan.action=='put'&&plan.curSeg==plan.segN-1",
    //    blockVerb = "true",
    //    templateString = "agv.Wait();agv.Put(${dst.putNeedTurn},\"${dst.name}\");agv.Wait();",
    //    siteFields = typeof(ArmCarSiteFields),
    //    trackFields = typeof(ArmCarTrackFields),
    //    planFields = typeof(ArmCarPlanFields))]
    //[TemplateSiteCoderSettings(
    //    priority = 5,
    //    useVerb = "plan.action=='putEmpty'&&plan.curSeg==plan.segN-1",
    //    blockVerb = "true",
    //    templateString = "agv.Wait();agv.PutEmpty(\"${dst.name}\");agv.Wait();",
    //    siteFields = typeof(ArmCarSiteFields),
    //    trackFields = typeof(ArmCarTrackFields),
    //    planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "plan.action=='pickFull'&&plan.curSeg==plan.segN-1",
        blockVerb = "true",
        templateString = "agv.Wait();agv.PickFull(\"${dst.name}\");agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "plan.action=='pickEmpty'&&plan.curSeg==plan.segN-1",
        blockVerb = "true",
        templateString = "agv.Wait();agv.PickEmpty(\"${dst.name}\");agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "plan.action=='putFull'&&plan.curSeg==plan.segN-1",
        blockVerb = "true",
        templateString = "agv.Wait();agv.PutFull(\"${dst.name}\");agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "plan.action=='putEmpty'&&plan.curSeg==plan.segN-1",
        blockVerb = "true",
        templateString = "agv.Wait();agv.PutEmpty(\"${dst.name}\");agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "plan.action=='MoveArm'&&plan.curSeg==plan.segN-1",
        blockVerb = "true",
        templateString = "agv.Wait();agv.MoveArm(${dst.MoveDirection});agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]
    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "dst.name=='charge'",
        templateString = "agv.Wait();agv.ControlChargePort(true);agv.Wait();",
        siteFields = typeof(ArmCarSiteFields),
        trackFields = typeof(ArmCarTrackFields),
        planFields = typeof(ArmCarPlanFields))]

    [TemplateSiteCoderSettings(
        priority = 5,
        useVerb = "dst.name=='charge'&&plan.curSeg==0",
        templateString = "agv.Wait();agv.ControlChargePort(false);",
        siteFields = typeof(VDA5050SiteField))]

    [CarType(Name = "ArmCar")]
    [I18N.DocumentTranslation(Name = "ArmCar", locale = "en")]
    public class ArmCar : GhostCar
    {
        public static async Task<ArmCar> Create()
        {
            var car = new ArmCar()
            {
                lstatus = "连接中",
                address = "127.0.0.1",
                name = $"Kiva",
                haveCoordination = true,
                speed = 0.3f,
            };
            return car;
        }
        private const float DrawWidth = 950, DrawLength = 650;
        private readonly Pen orientPen = new Pen(Color.White, 3);
        private bool twinkle = false;
        protected override void draw(Graphics eGraphics)
        {
            try
            {
                float scale = 1;
                var lineCap = new AdjustableArrowCap(5, 5, true);
                orientPen.CustomEndCap = lineCap;
                orientPen.StartCap = LineCap.RoundAnchor;
                var alarmLevel = Commons.GetCarStatus(this, "AlarmLevel");
                var soc = Commons.CarValue((Car)this, "Soc");
                var electricCurrent = Commons.CarValue((Car)this, "ElectricCurrent");
                var thresSpeed = Commons.CarValue(this, "ThresSpeed");
                LadderLogic.FlipFlop(ref twinkle, 500, true, false);
                Rectangle destRect = new Rectangle(
                    (int)((int)(-DrawWidth / 2) * scale),
                    (int)((int)(-DrawLength / 2) * scale),
                    (int)((int)DrawWidth * scale),
                    (int)((int)DrawLength * scale)
                );
                if (int.TryParse(alarmLevel, out var alarm) && alarm > 0)
                {
                    eGraphics.FillRectangle(twinkle ? Brushes.DarkRed : Brushes.Green, destRect);
                }
                else if (alarmLevel == "-1" || this.siteID == -1)
                    eGraphics.FillRectangle(Brushes.LightSeaGreen, destRect);
                else if (electricCurrent > 1)
                    eGraphics.FillRectangle(Brushes.YellowGreen, destRect);
                else if (thresSpeed <= 0)
                {
                    eGraphics.FillRectangle(twinkle ? Brushes.YellowGreen : Brushes.Green, destRect);
                }
                else if (soc < 25)
                {
                    eGraphics.FillRectangle(twinkle ? Brushes.DarkRed : Brushes.LightSeaGreen, destRect);
                }
                else
                    eGraphics.FillRectangle(Brushes.Green, destRect);

                eGraphics.DrawEllipse(Pens.Yellow, -160, -160, 320, 320);
                eGraphics.DrawLine(orientPen, 0, 0, 480, 0);

            }
            catch (Exception e)
            {
                Diagnosis.Post("绘制小车异常" + ExceptionFormatter.FormatEx(e), "绘制小车异常", true);
            }
        }


        public override string SetDisplayInfo()
        {
            try
            {
                var str = $"{name}({id})\n";
                status.enums.TryGetValue("ChassisMode", out var manual);
                var ms = manual == "0" ? "自动" : "手动";
                status.enums.TryGetValue("Soc", out var soc);
                str = $"{str}{ms}|soc:{soc}";
                var alarmStr = Commons.GetCarStatus(this, "AlarmInfo");
                if (alarmStr != "")
                    str = $"{str}|{alarmStr}";
                //if (status.enums.TryGetValue("mAlarm", out var mAlarm) && mAlarm != "")
                //    str = $"{str}|M:{mAlarm}";
                //var hasC = status.enums.TryGetValue("cAlarm", out var cAlarm) && cAlarm != "";
                //if (mAlarm != "" && hasC)
                //    str = $"{str}|";
                //if (hasC)
                //    str = $"{str}C:{cAlarm}";
                //var L_step = status.enums.TryGetValue("ls", out var ls) && ls != "";
                //if (L_step)
                //{
                //    str = $"{str}|ls:{ls}";
                //}
                if (status.enums.TryGetValue("ElectricCurrent", out var electricCurrent) &&
                    !string.IsNullOrEmpty(electricCurrent))
                {
                    var charging = float.Parse(electricCurrent) * 0.01f > 0 ? "充电中" : "未充电";
                    str = $"{str}|charge:{charging}";
                }

                var thresSpeed = Commons.CarValue(this, "ThresSpeed");
                str = $"{str}{((thresSpeed <= 0) ? "|避障触发" : "")}";
                return str;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return "bad car";
            }
        }
     
        [MethodMember(Name = "进入小车管理界面", Description = "在浏览器中打开小车 Web 页面")]
        [I18N.DocumentTranslation(Name = "Open vehicle management page", Description = "Open the car's management page in browser", locale = "en")]
        public void OpenVehicleManagementPage()
        {
            CarRemoteHelper.OpenVehicleWebPage(address);
        }


    }
}
