using BPA.Model;
using BPA.Model.Table;
using BPA.SingleDevice.Services;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media.Media3D;

namespace BPA.SingleDevice.ViewModel
{
    public class MaterialManagementViewModel : NotifyBase
    {
        private readonly ILogService logService;

        public MaterialManagementViewModel(ILogService logService)
        {
            this.logService = logService;
            MaterialInfos = new();

            GetAllMaterialAsync();
            AddCommand = new BPARelayCommand(async () =>
            {
                var content = new AddMaterialDialogView();
                var para = await Dialog.Show(content, new Parameters(), "添加物料", (d) => { }, async (d, o) =>
                {
                    if (o is MaterialTB rm)
                    {
                        //string id = Guid.NewGuid().ToString();
                        string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        var material = new MaterialTB()
                        {
                            Name = rm.Name,
                            MaterialCode = rm.MaterialCode,
                            IsActive = true,

                            CreateTime = time,
                            LastModified = time,
                            Description = rm.Description
                        };
                        bool isExist = true;
                        var queryResult = await SqlHelper.GetInstance.GetListAsync<MaterialTB>();
                        if (queryResult.IsSuccess)
                        {
                            isExist= queryResult.Content.Where(m => m.MaterialCode == material.MaterialCode || m.Name == material.Name).Any();
                        }
                        if (isExist)
                        {
                            Message.Error("MaterialManagementView", $"添加物料【{rm.Name}】失败，已有物料编码或名称相同的物料。");

                        }
                        else
                        {
                            var result = await SqlHelper.GetInstance.AddAsync(material);
                            result.OnSuccess(() =>
                            {
                                //MaterialInfos.Add(material);
                                Message.Success("MaterialManagementView", $"添加物料【{rm.Name}】成功。");
                                logService.LogUserInfo($"成功添加物料【{rm.Name}】，物料编码【{rm.MaterialCode}】。");
                                GetAllMaterialAsync();
                            }).OnFail(s => {
                                Message.Error("MaterialManagementView", $"添加物料【{rm.Name}】,物料编码【{rm.MaterialCode}】失败。");
                                logService.LogDebugInfo($"添加物料【{rm.Name}】失败，信息：{s}"); });
                        }
                    }
                });
            });

            EditCommand = new(async (o) =>
            {
                if (o is int id)
                {
                    var index = MaterialInfos.ToList().FindIndex(p => p.ID == id);
                    if (index >= 0)
                    {
                        var material = MaterialInfos[index];
                        if (await GetIsOccupyAsunc(material.MaterialCode))
                        {
                            Message.Error("MaterialManagementView", $"修改物料【{material.Name}】,物料编码【{material.MaterialCode}】失败，该物料已被绑定到设备，请解绑后重试。");
                            return;
                        }
                        var para = await Dialog.Show(new AddMaterialDialogView(), new MaterialTB()
                        {
                            ID = MaterialInfos[index].ID,
                            Name = MaterialInfos[index].Name,
                            MaterialCode = MaterialInfos[index].MaterialCode,
                            Description = MaterialInfos[index].Description,
                        }, "物料编辑", (d) => { }, async (d, o) =>
                        {
                            if (o is MaterialTB rm)
                            {
                                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                                var material = new MaterialTB()
                                {
                                    ID= MaterialInfos[index].ID,
                                    Name=rm.Name,
                                    MaterialCode=rm.MaterialCode,
                                    IsActive= MaterialInfos[index].IsActive,
                                    //CreateTime = MaterialInfos[index].CreateTime,
                                    LastModified =time,
                                    Description = rm.Description,
                                };

                                bool isExist = false;
                                var queryResult = await SqlHelper.GetInstance.GetListAsync<MaterialTB>();
                                if (queryResult.IsSuccess)
                                {
                                    var existList = queryResult.Content.Where(m => m.MaterialCode == material.MaterialCode);
                                    foreach (var item in existList)
                                    {
                                        if (item.ID!=material.ID)
                                        {
                                            isExist = true;
                                            break;
                                        }
                                    }
                                }
                                if (isExist)
                                {
                                    Message.Error("MaterialManagementView", $"修改物料【{rm.Name}】失败，已有物料编码或名称相同的物料。");

                                }
                                else
                                {
                                    SqlHelper.GetInstance.UpdateAsync(material).Result.OnSuccess(() =>
                                    {
                                        Message.Success("MaterialManagementView", $"修改物料【{rm.Name}】，物料编码【{rm.MaterialCode}】成功。");
                                        logService.LogUserInfo($"成功修改物料【{rm.Name}】，物料编码【{rm.MaterialCode}】。");
                                        GetAllMaterialAsync();
                                    }).OnFail(s => {
                                        Message.Error("MaterialManagementView", $"修改物料【{rm.Name}】,物料编码【{rm.MaterialCode}】失败。");
                                        logService.LogDebugInfo( $"修改物料【{rm.Name}】，物料编码【{rm.MaterialCode}】失败：{s}"); });
                                }
                            }
                        });
                    }
                }
            });

            RemoveCommand = new(async (o) =>
            {
                if (o is int id)
                {
                    var index = MaterialInfos.ToList().FindIndex(p => p.ID == id);
                    if (index >= 0)
                    {
                        var material = MaterialInfos[index];
                        if (await GetIsOccupyAsunc(material.MaterialCode))
                        {
                            Message.Error("MaterialManagementView", $"删除物料【{material.Name}】,物料编码【{material.MaterialCode}】失败，该物料已被绑定到设备，请解绑后重试。");
                            return;
                        }
                        var result = await MessageBoxR.Confirm("是否删除该数据?");
                        if (result == System.Windows.MessageBoxResult.Yes)
                        {
                            SqlHelper.GetInstance.DeleteMaterialByIDAsync<MaterialTB>(id).OnSuccess((result) =>
                            {
                                //MaterialInfos.RemoveAt(index);
                                Message.Success("MaterialManagementView", $"删除物料【{material.Name}】,物料编码【{material.MaterialCode}】成功。");
                                logService.LogUserInfo($"删除物料【{material.Name}】,物料编码【{material.MaterialCode}】成功。");
                                GetAllMaterialAsync();
                            }).OnFail(s => { Message.Error("MaterialManagementView", $"删除物料【{material.Name}】,物料编码【{material.MaterialCode}】失败。");
                                logService.LogDebugInfo($"删除物料【{material.Name}】,物料编码【{material.MaterialCode}】失败，信息【{s}】。");
                            });
                        }
                    }
                }
            });

            RefreshCommand = new(() => GetAllMaterialAsync());
        }

        public ObservableCollection<MaterialTB> MaterialInfos { get; set; }

        public BPARelayCommand AddCommand { get; set; }

        public BPARelayCommand RefreshCommand { get; set; }
        public BPARelayCommand<object> EditCommand { get; set; }
        public BPARelayCommand<object> RemoveCommand { get; set; }

        private async void GetAllMaterialAsync(CancellationToken? cancellationToken=null)
        {
            var token = cancellationToken ?? CancellationToken.None;
            try
            {
                var result = await SqlHelper.GetInstance.GetListAsync<MaterialTB>();
                if (result.IsSuccess)
                {
                    MaterialInfos.Clear();
                    var list = result.Content.OrderBy(m => m.MaterialCode);
                    foreach (var item in list)
                    {
                        MaterialInfos.Add(item);
                    }
                }
            }
            catch (Exception e)
            {
                logService.LogDebugInfo(e.ToString());
            }
        }
        /// <summary>
        /// 查找该物料编码是否已经被绑定到设备了。
        /// </summary>
        /// <param name="materialCode"></param>
        /// <returns></returns>
        private async Task<bool> GetIsOccupyAsunc(string materialCode)
        {
            if (String.IsNullOrEmpty(materialCode))
            {
                return true;
            }
            var getAllBindedMaterial = await SqlHelper.GetInstance.GetListAsync<MaterialBindTB>();
            if (getAllBindedMaterial.IsSuccess)
            {
                return getAllBindedMaterial.Content.Any(m => m.MaterialCode == materialCode);
            }
            return true;
        }
    }
}
