using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Data.OleDb;
using System.Data.SQLite;
using System.Data;
using System.Configuration;
using SimpleCRM.ViewDAO;
using SimpleCRM.Units;
using Telerik.Windows.Controls;
using System.Collections;
using System.Windows.Data;
using System.Windows;
using Telerik.Windows.Controls.GridView;
using System.Globalization;
using SimpleCRM.Service;

namespace SimpleCRM.ViewModels
{
    public class OrderFormViewModel : Caliburn.Micro.Screen, IHandle<OrderEventArgs>
    {
        private readonly IEventAggregator eventAggregator;
        private readonly OrderService orderService;
        private readonly GoodsService goodsService;
        private readonly DictionarysService dictionarysService;

        private List<Goods> newInsertGoods = new List<Goods>();
        private Dictionary<int, Goods> editedGoods = new Dictionary<int, Goods>();
        private Dictionary<string, string> doubleColumns = new Dictionary<string, string>();

        //private readonly CacheHelper cacheHelper;
        public OrderFormViewModel(IEventAggregator _eventAggregator, DictionarysService _DictionarysService, OrderService _OrderService, GoodsService _GoodsService)
        {
            eventAggregator = _eventAggregator;
            eventAggregator.Subscribe(this);
            orderService = _OrderService;
            goodsService = _GoodsService;
            dictionarysService = _DictionarysService;
            SetDoubleColumns();
        }

        public void SetDoubleColumns()
        {
            doubleColumns.Add("Gross", "毛重");
            doubleColumns.Add("Tare", "皮重");
            doubleColumns.Add("Suttle", "净重");
            doubleColumns.Add("Deduction", "扣损");
            doubleColumns.Add("TaxPrice", "含税单价");
            doubleColumns.Add("Total", "价税合计");
        }


        //protected override void OnActivate()
        //{
        //    eventAggregator.Subscribe(this);
        //    base.OnActivate();
        //}

        private DateTime _startDateTime = DateTime.Now;
        public DateTime StartDateTime
        {
            get
            {
                return _startDateTime;
            }
            set
            {
                if (_startDateTime != value)
                {
                    _startDateTime = value;
                    NotifyOfPropertyChange(() => StartDateTime);
                }
            }
        }

        private ObservableCollection<Order> items = new ObservableCollection<Order>();
        public ObservableCollection<Order> Items { get { return items; } set { items = value; } }

        private ObservableCollection<Goods> goods = new ObservableCollection<Goods>();
        public ObservableCollection<Goods> Goods { get { return goods; } set { goods = value; NotifyOfPropertyChange(() => Goods); } }

        public RadDataForm MyRadDataForm { get; set; }

        public RadGridView MyGoodsGridView { get; set; }

        public FormViewModel FormViewModel { get; set; }
        protected override void OnViewLoaded(object view)
        {
            this.MyRadDataForm = (Telerik.Windows.Controls.RadDataForm)((System.Windows.Controls.ContentControl)view).Content;
            this.MyRadDataForm.EditEnded += MyRadDataForm_EditEnded;
            MyRadDataForm.CommandProvider = new CustomCommandProvider(MyRadDataForm, this);
            this.Goods = goodsService.GetGoods(" orderid=" + GetCurrentOrder().ID);

            int i = 1;
            this.Goods.Apply((item) =>
            {
                item.RowNum = i++;
            });

            this.MyGoodsGridView = this.MyRadDataForm.ChildrenOfType<Telerik.Windows.Controls.RadGridView>().FirstOrDefault(t => t.Name == "radGridView");
            //goodsGrid.IsLocalizationLanguageRespected = false;
            this.MyGoodsGridView.AddingNewDataItem += MyGoodsGridView_AddingNewDataItem;
            this.MyGoodsGridView.RowEditEnded += MyGoodsGridView_RowEditEnded;
            this.MyGoodsGridView.CellEditEnded += MyGoodsGridView_CellEditEnded;
            this.MyGoodsGridView.CellValidating += MyGoodsGridView_CellValidating;
            Binding bdname = new Binding();
            bdname.Source = this;
            bdname.Mode = BindingMode.TwoWay;
            bdname.Path = new PropertyPath("Goods");
            this.MyGoodsGridView.SetBinding(RadGridView.ItemsSourceProperty, bdname);

            var comboBoxs = this.MyRadDataForm.ChildrenOfType<RadComboBox>();
            foreach (var combo in comboBoxs)
            {
                combo.IsEditable = false;
                combo.IsReadOnly = true;
                combo.SelectionChanged += Combo_SelectionChanged;
            }
            BindComboboxItems(comboBoxs, "customerCombobox", dictionarysService.GetAllCustomers());
            BindComboboxItems(comboBoxs, "salerCombobox", dictionarysService.GetAllSalers());
            BindComboboxItems(comboBoxs, "salesDepartmentCombobox", dictionarysService.GetAllSalesDepartments());
            BindComboboxItems(comboBoxs, "provinceCombobox", dictionarysService.GetAllProvinces());

            if (this.FormViewModel == FormViewModel.Edit)
            {
                SetComboboxSelectedItem(GetCurrentOrder(), comboBoxs);
            }
        }

        #region combobox
        private void SetComboboxSelectedItem(Order order, IEnumerable<RadComboBox> comboBoxs)
        {
            Dictionary<string, int> oMaps = new Dictionary<string, int>();
            oMaps.Add("customerCombobox", order.Customer);
            oMaps.Add("salerCombobox", order.Saler);
            oMaps.Add("salesDepartmentCombobox", order.SalesDepartment);
            oMaps.Add("provinceCombobox", order.SaleArea);

            foreach (var item in oMaps)
            {
                var combobox = comboBoxs.Where(c => c.Name == item.Key).FirstOrDefault();
                foreach (var oneItem in combobox.Items)
                {
                    var tempItem = oneItem as IIDSign;
                    if (tempItem != null && tempItem.ID == item.Value)
                    {
                        combobox.SelectedItem = oneItem;
                        break;
                    }
                }
            }
        }

        private void Combo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            var combobox = sender as Telerik.Windows.Controls.RadComboBox;
            var selectedItem = e.AddedItems;

            var order = GetCurrentOrder();

            switch (combobox.Name)
            {
                case "customerCombobox":
                    var customerItem = selectedItem[0] as Customer;
                    order.Customer = customerItem.ID;
                    break;

                case "salerCombobox":
                    var salerItem = selectedItem[0] as Saler;
                    order.Saler = salerItem.ID;
                    break;

                case "salesDepartmentCombobox":
                    var salesDepartment = selectedItem[0] as SalesDepartment;
                    order.SalesDepartment = salesDepartment.ID;
                    break;

                case "provinceCombobox":
                    var provinceItem = selectedItem[0] as Province;
                    order.SaleArea = provinceItem.ID;
                    break;
            }
        }

        private void BindComboboxItems(IEnumerable<RadComboBox> comboBoxs, string comboxName, IEnumerable datas)
        {
            var combobox = comboBoxs.FirstOrDefault(t => t.Name == comboxName);
            combobox.ItemsSource = datas;
            combobox.DisplayMemberPath = "Name";
            if (comboxName == "provinceCombobox" && this.FormViewModel == FormViewModel.Insert)
            {
                combobox.SelectedIndex = 2;
            }
        }
        #endregion

        #region gridview

        private void MyGoodsGridView_AddingNewDataItem(object sender, GridViewAddingNewEventArgs e)
        {
            //r googs = e.NewObject as Goods;
            //googs.RowNum = ;
            e.NewObject = new Goods() { RowNum = this.MyGoodsGridView.Items.Count + 1 };

        }

        private void MyGoodsGridView_CellValidating(object sender, GridViewCellValidatingEventArgs e)
        {
            if (e.Cell.Column.UniqueName == "Acount")
            {
                int acount = 0;
                if (!Int32.TryParse(e.NewValue.ToString(), out acount))
                {
                    e.IsValid = false;
                    e.ErrorMessage = "头数必须是整数";
                    return;
                }
            }

            if (doubleColumns.Keys.Contains(e.Cell.Column.UniqueName))
            {
                if (!ValidatingDouble(e.NewValue.ToString()))
                {
                    e.IsValid = false;

                    string columnsDisplayName = doubleColumns[e.Cell.Column.UniqueName];
                    e.ErrorMessage = string.Format("{0}必须是数字", columnsDisplayName);
                    return;
                }
            }
        }

        private void MyGoodsGridView_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
        {
            if (e.Row is GridViewNewRow)
            {
                if (e.EditOperationType == GridViewEditOperationType.Insert)
                {
                    var goods = e.NewData as Goods;
                    goods.OrderID = this.GetCurrentOrder().ID;
                    newInsertGoods.Add(goods);
                }

                //if (e.EditOperationType == GridViewEditOperationType.Edit)
                //{
                //    var goods = e.NewData as Goods;
                //    editedGoods.Add(goods);
                //}
            }
        }

        private void MyGoodsGridView_CellEditEnded(object sender, GridViewCellEditEndedEventArgs e)
        {
            if (this.FormViewModel == FormViewModel.Insert)
            {
                return;
            }

            var goods = e.Cell.ParentRow.DataContext as Goods;
            if (goods.ID != 0 && !editedGoods.Keys.Contains(goods.ID))
            {
                editedGoods.Add(goods.ID, goods);
            }
        }

        #endregion

        private bool ValidatInput()
        {
            List<bool> oResult = new List<bool>();
            var comboBoxs = this.MyRadDataForm.ChildrenOfType<RadComboBox>();
            oResult.Add(ValidatInputComboBox(comboBoxs, "customerCombobox", "客户"));
            oResult.Add(ValidatInputComboBox(comboBoxs, "salerCombobox", "销售员"));

            if (this.Goods.Count < 1)
            {
                MessageBox.Show("请添加商品");
                return false;
            }

            if (oResult.Contains(false))
            {
                return false;
            }

            return true;
        }
        private bool ValidatInputComboBox(IEnumerable<RadComboBox> comboBoxs, string comboxName, string message)
        {
            var combobox = comboBoxs.FirstOrDefault(t => t.Name == comboxName);
            if (combobox.SelectedIndex < 0)
            {
                MessageBox.Show("请选择" + message);
                return false;
            }
            return true;
        }

        private void MyRadDataForm_EditEnded(object sender, Telerik.Windows.Controls.Data.DataForm.EditEndedEventArgs e)
        {
            if (!ValidatInput())
            {
                return;
            }

            if (this.FormViewModel == FormViewModel.Insert)
            {
                AddOrderRecord();  //保存订单信息
                AddGoodsRecord();  //保存商品信息
                ModifyCode();      //更新订单的流水号字典信息
            }

            if (this.FormViewModel == FormViewModel.Edit)
            {
                EditOrderRecord();
                EditGoodsRecord();
                AddGoodsRecord();
            }

            eventAggregator.PublishOnUIThread(new OrderAddedEventArgs());
            this.TryClose();
        }

        private bool ValidatingDouble(string value)
        {
            double doubleValue = 0.0;
            if (!Double.TryParse(value, out doubleValue))
            {
                return false;
            }
            return true;
        }

        private void AddOrderRecord()
        {
            var item = this.GetCurrentOrder();
            orderService.AddOrder(item);
        }

        private void AddGoodsRecord()
        {
            foreach (var item in newInsertGoods)
            {
                if (string.IsNullOrEmpty(item.Name))
                {
                    continue;
                }
                goodsService.AddGoods(item, this.GetCurrentOrder());
            }
        }

        private void EditOrderRecord()
        {
            var item = this.GetCurrentOrder();
            orderService.UpdateOrder(item);
        }
        private void EditGoodsRecord()
        {
            foreach (var item in editedGoods.Values)
            {
                if (string.IsNullOrEmpty(item.Name))
                {
                    continue;
                }
                goodsService.UpdateGoods(item);
            }
        }


        private void ModifyCode()
        {
            CodeHelper.UpdateDataVal(StartDateTime);
        }

        private Order GetCurrentOrder()
        {
            return this.Items.FirstOrDefault();
        }

        public void Handle(OrderEventArgs message)
        {
            eventAggregator.Unsubscribe(this);
            this.FormViewModel = message.FormViewModel;
            var order = message.Order;
            if (message.FormViewModel == FormViewModel.Insert)
            {
                order.ID = CodeHelper.GetNextID();
                order.Code = CodeHelper.GetNextCode(StartDateTime);
                order.Date = DateTimeConvertHelper.GetFormatDate(StartDateTime);
                order.CreateDate = StartDateTime;
            }
            if (message.FormViewModel == FormViewModel.Edit)
            {
                IFormatProvider ifp = new CultureInfo("zh-CN", true);
                order.CreateDate = DateTime.ParseExact(order.Date, "yyyyMMdd", ifp);
            }
            this.Items.Clear();
            this.Items.Add(order);
        }
    }
}
