using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using DbCommon.Enties.DbModels;
using DbCommon.BusinessCore.BaseCore;
using ProjectManagementSystem.Common.Function;
using ProjectManagementSystem.Common.Config;
using ProjectManagementSystem.Common.Logger;
using ScottPlot;
using ProjectManagementSystem.Common.Extenions;

namespace ProjectManagementSystem.UI
{
    public partial class AreaUI : UserControl
    {
        private ManualResetEvent m_manualResetEvent = new ManualResetEvent(false);

        private FormsPlot formsPlot1 = new FormsPlot();
        private FormsPlot formsPlot2 = new FormsPlot();
        private Plot plotStatus = new Plot();
        private Plot plotMaterial = new Plot();

        private double[] statusCounts;
        private string[] statusLables;
        private Color[] statusColors;

        private double[] materialCounts;
        private string[] materialLables;

        private int sLocationX = 5;
        private int sLocationY = 5;
        private int marginX = 5;
        private int marginY = 5;

        private string m_wareHouseCode;

        private List<LocationUI> m_listBtn = new List<LocationUI>();

        public event Action<object, LocationProperty> OnLocationSelected;

        private LocationPropertyManager m_locationManager;

        public string CurrentWareHouseCode 
        {
            get { return m_wareHouseCode; }
            set
            {
                if(value != m_wareHouseCode)
                {
                    SetDisplayArea(value);
                }
            }
        }

        public AreaUI()
        {
            InitializeComponent();

            for (int i = 0; i < 500; i++)
            {
                LocationUI stationUI = new LocationUI();
                stationUI.Click += Btn_ClickSelected;
                stationUI.Click += Btn_Click;
                m_listBtn.Add(stationUI);
            }
        }

        private void Btn_ClickSelected(object sender, EventArgs e)
        {
            LocationUI selectedStationUI = sender as LocationUI;
            if (selectedStationUI == null)
            {
                return;
            }

            foreach (var item in this.panel2.Controls)
            {
                LocationUI stationUI = item as LocationUI;
                if (stationUI == null)
                {
                    continue;
                }

                stationUI.StationSelected = selectedStationUI.Equals(stationUI) ? true : false;

                stationUI.Display();
            }
        }

        private void AreaUI_Load(object sender, EventArgs e)
        {
        }

        ///// <summary>
        ///// 解决页面频繁刷新时界面闪烁问题
        ///// </summary>
        //protected override CreateParams CreateParams
        //{
        //    get
        //    {
        //        CreateParams cp = base.CreateParams;
        //        cp.ExStyle |= 0x02000000;
        //        return cp;
        //    }
        //}

        public bool Init()
        {
            this.DoubleBuffered = true;//设置本窗体
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲

            int width = AppSetting.TryGetValue<int>("StationUIWidth");
            int height = AppSetting.TryGetValue<int>("StationUIHeight");

            foreach (var stationUI in m_listBtn)
            {
                stationUI.Width = width;
                stationUI.Height = height;
            }

            if (ColorSetting.Instance == null)
            {
                return false;
            }

            m_locationManager = new LocationPropertyManager();

            PlotStatusInit();
            PlotMaterialInit();

            splitContainer1.SplitterDistance = splitContainer1.Height;
            return true;
        }

        private void PlotStatusInit()
        {
            formsPlot1.Dock = DockStyle.Fill;
            splitContainer2.Panel1.Controls.Add(formsPlot1);

            formsPlot1.Reset(plotStatus);
            formsPlot1.Refresh();
        }

        private void PlotMaterialInit()
        {
            formsPlot2.Dock = DockStyle.Fill;
            splitContainer2.Panel2.Controls.Add(formsPlot2);

            formsPlot2.Reset(plotMaterial);
            formsPlot2.Refresh();
        }

        public void SetDisplayArea(string area)
        {
            m_manualResetEvent.Reset();

            m_wareHouseCode = area;
            var lists = m_locationManager.QueryDataList_Area(m_wareHouseCode);
            if (lists == null
                || lists.Count == 0)
            {
                m_manualResetEvent.Set();
                this.panel2.Controls.Clear();
                return;
            }

            var buttonPropertyDict = ExcelConfig.Instance.ButtonPropertyDict;

            int row = 0;
            int col = 0;

            int totalWidth = this.panel2.Width;
            int rowMaxCount = totalWidth / (m_listBtn[0].Width + 10);
            if (rowMaxCount == 0)
            {
                rowMaxCount = 10;
            }

            this.panel2.SuspendLayout();
            this.panel2.Controls.Clear();
            for (int i = 0; i < lists.Count; i++)
            {
                var list = lists[i];
                if (i >= m_listBtn.Count)
                {
                    break;
                }

                LocationUI stationUI = m_listBtn[i];
                if (i != 0 && i % rowMaxCount == 0)
                {
                    row++;
                    col = 0;
                }

                if (!buttonPropertyDict.ContainsKey(list.LocationCode))
                {
                    int posX = sLocationX + (col * (stationUI.Width + marginX));
                    int posY = sLocationY + (row * (stationUI.Height + marginY));
                    stationUI.Location = new Point(posX, posY);

                    CButton cBtn = new CButton();
                    cBtn.ButtonName = list.LocationCode;
                    cBtn.LocationX = stationUI.Location.X;
                    cBtn.LocationY = stationUI.Location.Y;
                    buttonPropertyDict.Add(list.LocationCode, cBtn);
                }
                else
                {
                    int posX = buttonPropertyDict[list.LocationCode].LocationX;
                    int posY = buttonPropertyDict[list.LocationCode].LocationY;
                    stationUI.Location = new Point(posX, posY);
                }

                stationUI.LocationProperty = list;
                stationUI.Display();
                this.panel2.Controls.Add(stationUI);
                col++;
            }

            Btn_Click(m_listBtn[0], null);//点击第一个仓位按钮
            Btn_ClickSelected(m_listBtn[0], null);

            this.panel2.ResumeLayout();
            m_manualResetEvent.Set();
        }

        public void UpdateDisplay()
        {
            if (!this.Visible)
            {
                return;
            }

            m_manualResetEvent.WaitOne();
            if (this.IsDisposed) return;

            var lists = m_locationManager.QueryDataList_Area(m_wareHouseCode);
            if (lists == null
                || lists.Count == 0)
            {
                return;
            }

            this.Invoke(new MethodInvoker(() =>
            {
                this.panel2.SuspendLayout();
                for (int i = 0; i < lists.Count; i++)
                {
                    var data = lists[i];
                    if (i < m_listBtn.Count && i < this.panel2.Controls.Count)
                    {
                        LocationUI stationUI = m_listBtn[i];
                        stationUI.LocationProperty = data;
                        stationUI.Display();
                    }
                }
                this.panel2.ResumeLayout();
            }));

            if(splitContainer2.Height > 10)
            {
                PlotStatus(lists);
                PlotMaterial(lists);
            }
        }


        private void PlotStatus(List<LocationProperty> locationList)
        {
            bool reset = true;
            //统计总状态
            LocationStatus[] locationStatuses = locationList.GroupBy(d => d.Status).Select(d => d.Key).ToArray();
            if (statusCounts == null
                || statusCounts.Length != locationStatuses.Length)
            {
                statusCounts = locationStatuses.Select(d => Convert.ToDouble(locationList.Count(f => f.Status == d))).ToArray();
                statusColors = locationStatuses.Select(d => d.ToColor()).ToArray();
                var statusLablesTemp = locationStatuses.Select(d => d.ToStatusString()).ToArray();

                statusLables = Enumerable.Range(0, statusCounts.Length)
                       .Select(i => $"{statusLablesTemp[i]}({statusCounts[i]})")
                       .ToArray();

                reset = true;
            }
            else
            {
                for (int i = 0; i < locationStatuses.Length; i++)
                {
                    var status = locationStatuses[i];

                    statusCounts[i] = locationList.Count(f => f.Status == status);
                    statusColors[i] = status.ToColor();
                    statusLables[i] = $"{status.ToStatusString()}({statusCounts[i]})";
                }
                reset = false;
            }

            if (statusLables.Length == 0
                || statusCounts.Length == 0)
            {
                plotStatus.Clear();
                formsPlot1.Reset();
            }
            else
            {
                if (reset)
                {
                    plotStatus.Clear();
                    var pie1 = plotStatus.AddPie(statusCounts);
                    pie1.SliceLabels = statusLables;
                    pie1.SliceFillColors = statusColors;
                    //pie1.ShowValues = true;
                    //pie1.ShowPercentages = true;
                    pie1.ShowLabels = true;
                    plotStatus.Legend();
                }
            }

            formsPlot1.Refresh();
        }

        private void PlotMaterial(List<LocationProperty> locationList)
        {
            bool reset = true;
            //统计总物料
            string[] materialLablesTemp = locationList
                .Where(d => d.Status != LocationStatus.Empty && d.Status != LocationStatus.None)
                .GroupBy(d => d.MaterialId)
                .Select(d => d.Key)
                .ToArray();

            if (materialLables == null
                || materialLables.Length != materialLablesTemp.Length)
            {
                materialLables = materialLablesTemp;
                materialCounts = materialLablesTemp.Select(d => Convert.ToDouble(locationList.Count(f => f.MaterialId == d))).ToArray();
                reset = true;
            }
            else
            {
                reset = false;
                for (int i = 0; i < materialLablesTemp.Length; i++)
                {
                    var material = materialLablesTemp[i];
                    int count = locationList.Count(f => f.MaterialId == material);

                    if (materialLables[i] != material
                        || materialCounts[i] != count)
                    {
                        reset = true;
                    }

                    materialLables[i] = material;
                    materialCounts[i] = count;
                }
            }

            if(materialLables.Length == 0
                || materialCounts.Length == 0)
            {
                plotMaterial.Clear();
                formsPlot2.Reset();
            }
            else
            {
                if (reset)
                {
                    plotMaterial.Clear();
                    var bar = plotMaterial.AddBar(materialCounts);
                    bar.ShowValuesAboveBars = true;

                    //plotMaterial.XLabel("物料");
                    plotMaterial.YLabel("数量");
                    plotMaterial.XTicks(materialLables);
                    plotMaterial.SetAxisLimits(yMin: 0);

                    formsPlot2.Reset(plotMaterial);
                }
            }
            
            formsPlot2.Refresh();
        }

        private void Btn_Click(object sender, EventArgs e)
        {
            if (OnLocationSelected != null)
            {
                LocationUI btn = (LocationUI)sender;
                OnLocationSelected(this, btn.LocationProperty);
            }
        }

        private void 保存布局ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < m_listBtn.Count; i++)
            {
                m_listBtn[i].Moveable = false;
            }

            this.panel2.HorizontalScroll.Value = 0;
            this.panel2.VerticalScroll.Value = 0;

            var buttonPropertyDict = ExcelConfig.Instance.ButtonPropertyDict;
            for (int i = 0; i < m_listBtn.Count; i++)
            {
                if (m_listBtn[i].LocationProperty == null)
                {
                    continue;
                }

                string locationCode = m_listBtn[i].LocationProperty.LocationCode;
                if (buttonPropertyDict.ContainsKey(locationCode))
                {
                    buttonPropertyDict[locationCode].LocationX = m_listBtn[i].Location.X;
                    buttonPropertyDict[locationCode].LocationY = m_listBtn[i].Location.Y;
                }
            }

            if (ExcelConfig.Instance.SaveButtonPropertyList())
            {
                MessageBox.Show("保存布局成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("保存布局失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void 允许移动ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < m_listBtn.Count; i++)
            {
                m_listBtn[i].Moveable = true;
            }
        }
    }
}
