
///////////////////////////////////////////////////////////////////////////////
//文件名称: VmInsuerProjectInfo.cs
//文件描述: 保险项目信息
//创 建 者: xls
//创建日期: 2018/5/24 21:58:36
//版 本 号：1.0.0.0
////////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using CEFSharpWpf;
using Com.FirmLib.Bll;
using Com.FirmLib.Entity;
using Com.FirmLib.UI.BllCommon;
using Com.FirmLib.UI.Common.Model;
using Com.FirmLib.UI.Insuer.Model;
using FWindSoft.DataFramework;
using FWindSoft.Handle;
using FWindSoft.MVVM;
using FWindSoft.SystemExtensions;
using FWindSoft.Wpf;
using FWindSoft.Wpf.Common;

namespace Com.FirmLib.UI.Insuer
{
    public class VmInsuerProjectInfo : BaseViewModel
    {
        public VmInsuerProjectInfo()
        {
            Init();
        }

        private void Init()
        {
            ContactItem = new ContactInformationItem();
        }
        public void Init(LoadParameter parameter)
        {
            var para = parameter.Parameter as InsuerParameter;
            InsuerId = para.Insuer.Id;
            ProjectId = para.Project.Id;

            LoadInsuerItem(InsuerId);
            LoadProjectItem(ProjectId);
            LoadLinkerItem(InsuerId, ProjectId);
            LoadAssetItems(InsuerId, ProjectId);
        }
        #region 属性相关
        /// <summary>
        /// 供应商Id
        /// </summary>
        private string InsuerId { get; set; }
        /// <summary>
        /// 项目Id
        /// </summary>
        public string ProjectId { get; private set; }
        /// <summary>
        /// 项目名称
        /// </summary>
        public string ProjectName { get; private set; }
        private string m_InsuerName;
        /// <summary>
        /// 保险商名称
        /// </summary>
        public string InsuerName
        {
            get { return this.m_InsuerName; }
            set
            {
                this.m_InsuerName = value;
                RaisePropertyChanged(() => this.InsuerName);
            }
        }


        private string m_InsuerUrl;
        /// <summary>
        /// 保险商地址
        /// </summary>
        public string InsuerUrl
        {
            get { return this.m_InsuerUrl; }
            set
            {
                this.m_InsuerUrl = value;
                RaisePropertyChanged(() => this.InsuerUrl);
            }
        }



        private ContactInformationItem m_ContactItem;
        /// <summary>
        /// 联系人信息
        /// </summary>
        public ContactInformationItem ContactItem
        {
            get { return this.m_ContactItem; }
            set
            {
                this.m_ContactItem = value;
                RaisePropertyChanged(() => this.ContactItem);
            }
        }



        private ObservableCollection<AssetShowItem> m_AssetItems;
        /// <summary>
        /// 保单资产信息
        /// </summary>
        public ObservableCollection<AssetShowItem> AssetItems
        {
            get { return this.m_AssetItems; }
            set
            {
                this.m_AssetItems = value;
                RaisePropertyChanged(() => this.AssetItems);
            }
        }


        private ObservableCollection<PolicyShowItem> m_PolicyItems;
        /// <summary>
        /// 项目保单信息
        /// </summary>
        public ObservableCollection<PolicyShowItem>  PolicyItems
        {
            get { return this.m_PolicyItems; }
            set
            {
                this.m_PolicyItems = value;
                RaisePropertyChanged(() => this.PolicyItems);
            }
        }
        #endregion

        #region 命令相关


        /// <summary>
        /// 查看资产详情
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void ScanAsset(object parameter)
        {

            try
            {
                AssetShowItem item = parameter as AssetShowItem;
                if (item == null)
                    return;
                AssetItem parItem = new AssetItem();
                parItem.Id = item.AssetNo;
                parItem.ProjectId = item.ProjectId;
                parItem.FamilyCode = item.FamilyCode;
                string url = BllFactory<AssetBll>.Instance.GetAssetUrl(parItem);
                WinBrowser.Instance.Show(url, "资产信息");
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
        }
        public bool CanScanAsset(object parameter)
        {
            return true;
        }
        /// <summary>
        /// 编辑保单
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void EditPolicy(object parameter)
        {

            try
            {
                PolicyShowItem item = parameter as PolicyShowItem;
                WinInsurancePolicyEditor win = new WinInsurancePolicyEditor();
                var f = new InsuerParameter();
                f.Insuer.Id = item.InsuerId;
                f.Project.Id = item.ProjectId;
                f.Policy.Id = item.PolicyNo;//传递表单编号
                LoadParameter.StartParameter(win, new LoadParameter(f));
                win.Show(this.GetNavigationBar());
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
        }
        public bool CanEditPolicy(object parameter)
        {
            return true;
        }
        /// <summary>
        /// 增加保单
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void AddInsuracncePolicy(object parameter)
        {

            try
            {
                WinInsurancePolicyEditor win = new WinInsurancePolicyEditor();
                var f = new InsuerParameter();
                f.Project.Id = ProjectId;
                f.Insuer.Id = InsuerId;
                LoadParameter.StartParameter(win, new LoadParameter(f));
                win.Show(this.GetNavigationBar());
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
        }
        public bool CanAddInsuracncePolicy(object parameter)
        {
            return true;
        }
        /// <summary>
        /// 保存功能
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void SaveCommand(object parameter)
        {

            try
            {
                if (CreatePolicyAsset())
                {
                    AfterSuccessSave();
                    MessageTip.Show(this.GetWindow(), "保存成功");
                }
                else
                {
                    MessageTip.Show(this.GetWindow(), "保存失败");
                }
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
           
        }
        public bool CanSaveCommand(object parameter)
        {
            return true;
        }

        /// <summary>
        /// 更新指定字段信息
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public bool SingleUpdateLinkerItem(string field)
        {

            LinkerItem item = new LinkerItem();
            item.VenderId = this.InsuerId;
            item.ProjectId = this.ProjectId;
            SetFieldValue(item, field);
            var result = BllFactory<InsuerBll>.Instance.UpdateLinker(item);
            if (!result)
            {
                MessageTip.Show(this.GetWindow(), BllFactory<InsuerBll>.Instance.ErrorMessage ?? string.Empty);
            }
            return result;
        }
        private void SetFieldValue(LinkerItem item, string field)
        {
            item.Name = ContactItem.People;
            item.Phone = this.ContactItem.Telephone;
            item.Email = this.ContactItem.Email;
            item.Fax = this.ContactItem.Fax;
            #region 修改相关
            //if (field == "People")
            //{
            //    item.Name = ContactItem.People;
            //    return;
            //}
            //if (field == "Telephone")
            //{
            //    item.Phone = this.ContactItem.Telephone;
            //    return;
            //}
            //if (field == "Email")
            //{
            //    item.Email = this.ContactItem.Email;
            //    return;
            //}
            //if (field == "Fax")
            //{
            //    item.Fax = this.ContactItem.Fax;
            //    return;
            //} 
            #endregion
        }



        /// <summary>
        /// 编辑保单号信息
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void EditPolicyNoCommand(object parameter)
        {

            try
            {
                AssetShowItem item = parameter as AssetShowItem;
                if (item == null)
                    return;
                item.CacheParameters.Clear();
                string originPolicyNo = item.InsurancePolicyNo;
                #region 初始化传入参数
                PolicyUpdateContext context = new PolicyUpdateContext();
                context.InsuerParameter.Policy.Id = item.InsurancePolicyNo;
                context.InsuerParameter.Project.Id = item.ProjectId;
                context.InsuerParameter.Insuer.Id = InsuerId;
                context.PolicyNo = item.InsurancePolicyNo;
                #endregion
                #region 保单编辑节点
                WizardState wizardState = new WizardState("Root");
                wizardState.SetHandle((obj) =>
                {
                    WinSimplePolicyEditor win = new WinSimplePolicyEditor();
                    win.Owner = this.GetWindow();
                    LoadParameter.StartParameter(win, new LoadParameter(obj));
                    if (win.ShowDialog() == true)
                    {
                        var tempContext = win.GetRealResult<PolicyUpdateContext>();
                        if (string.IsNullOrEmpty(originPolicyNo) || tempContext.PolicyNo == originPolicyNo)
                        {
                        //如果原始单号为null,获取与新单号相同，则直接完成修改
                        tempContext.CanExecute = false;
                            return WizardState.CompletedState;
                        }
                        else
                        {
                            return WizardState.NextState;
                        }
                    }
                    else
                    {
                        (obj as PolicyUpdateContext).CanExecute = false;
                        return WizardState.CancelState;
                    }
                });
                #endregion

                #region 确认修改时间节点
                WizardState ensureState = new WizardState("Ensure");
                ensureState.SetHandle((obj) =>
                {
                    WinPolicyEnsure win = new WinPolicyEnsure();
                    win.Owner = this.GetWindow();
                    LoadParameter.StartParameter(win, new LoadParameter(obj));
                    if (win.ShowDialog() == true)
                    {
                        var tempContext = win.GetRealResult<PolicyUpdateContext>();
                        tempContext.CanExecute = true;
                        return WizardState.CompletedState;
                    }
                    else
                    {
                        (obj as PolicyUpdateContext).CanExecute = false;
                        return WizardState.CancelState;
                    }
                });
                #endregion
                wizardState.AddState(WizardState.NextState, ensureState);
                wizardState.Execute(context);
                //不增加完成节点，直接通过context的CanExecute判断是否执行修改
                if (UpdateAssetPolicyNo(item, context))
                {
                    item.InsurancePolicyNo = context.PolicyNo;
                    item.EndDate = DateTimeManager.ConvertDateTime(context.ExpiryDate).ToString("yyyy-MM-dd");
                    item.PolicyFile = context.PolicyFile;
                    var items = CollectionViewSource.GetDefaultView(this.AssetItems);
                    items.Refresh();
                }
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
        }
        public bool CanEditPolicyNoCommand(object parameter)
        {
            return true;
        }


        /// <summary>
        /// 删除保单关联资产
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void DeleteAssetPolicy(object parameter)
        {

            try
            {
                AssetShowItem showItem = parameter as AssetShowItem;
                if (showItem == null)
                    return;
                //todo 删除资产关联关系，是直接删除，不需要保存确定
                var result = MessageTip.Show(this.GetWindow(), "是否要删除", "提示", MessageBoxButton.YesNo);
                if (result == MessageBoxResult.Yes)
                {
                    bool flag = false;
                    if (showItem.InsuerId == InsuerId)
                    {
                        flag = AssetManager.DeleteInsuerAssets(ProjectId, new List<string>() { showItem.Id });
                    }
                    else
                    {
                        flag = true;
                    }
                    if (flag)
                    {
                        this.AssetItems.Remove(showItem);
                    }
                    else
                    {
                        MessageTip.Show(this.GetWindow(), "删除失败");
                    }

                }
            }
            catch (Exception ex)
            {
                MessageTipEx.Show(ex);
            }
        }
        public bool CanDeleteAssetPolicy(object parameter)
        {
            return true;
        }



        /// <summary>
        /// 下载保单
        /// </summary>
        /// <param name="parameter"></param>
        [Command]
        public void FileDownLoadCommand(object parameter)
        {
            try
            {
                string fileKey = string.Empty;
                do
                {
                    if (parameter is AssetShowItem showItem)
                    {
                        fileKey = showItem.PolicyFile;
                        break;
                    }

                    if (parameter is PolicyShowItem policyItem)
                    {
                        fileKey = policyItem.PolicyFile;
                         break;
                    }
                } while (false);
             
                InsuerUtils.LoadPolicyFile(fileKey);
            }
            catch ( Exception ex)
            {

                MessageTip.Show(this.GetWindow(), "下载失败");
            }
        }
        public bool CanFileDownLoadCommand(object parameter)
        {
            return true;
        }


        #endregion
        #region 私有方法
        /// <summary>
        /// 加载供应商信息
        /// </summary>
        /// <param name="venderId">厂商id</param>
        private void LoadInsuerItem(string venderId)
        {
            var seller = BllFactory<InsuerBll>.Instance.GetAllItems().FirstOrDefault(c => c.Id == venderId);
            if (seller != null)
            {
                this.InsuerName = seller.Name;
                this.InsuerUrl = seller.Website;
            }

        }
        /// <summary>
        /// 加载联系人信息
        /// </summary>
        /// <param name="venderId">厂商库id</param>
        /// <param name="projectId">项目Id</param>
        private void LoadLinkerItem(string venderId, string projectId)
        {
            var linkerItem = BllFactory<InsuerBll>.Instance.GetLinker(venderId, projectId);
            if (linkerItem != null)
            {
                this.ContactItem.Telephone = linkerItem.Phone;
                this.ContactItem.People = linkerItem.Name;
                this.ContactItem.Fax = linkerItem.Fax;
                this.ContactItem.Email = linkerItem.Email;
            }
        }
        /// <summary>
        /// 获取相关资产信息
        /// </summary>
        /// <param name="venderId"></param>
        /// <param name="projectId"></param>
        private void LoadAssetItems(string venderId, string projectId)
        {
            AssetItems = new ObservableCollection<AssetShowItem>();
            PolicyItems = new ObservableCollection<PolicyShowItem>();
       
            var policyItems = BllFactory<InsuerBll>.Instance.GetAllPolicyItems(venderId, projectId);
            foreach (var dataItem in policyItems)
            {
                var item = ConvertPolicyShowItem(dataItem);
                item.InsuerId = venderId;
                item.ProjectId = projectId;
                PolicyItems.Add(item);
            }

            var dataItems = BllFactory<InsuerBll>.Instance.GetAllAssetItems(venderId, projectId);
            string venderName = BllFactory<InsuerBll>.Instance.GetItem(InsuerId)?.Name;
            foreach (var dataItem in dataItems)
            {
                var tempItem = ConvertAssetShowItem(dataItem);
              
                tempItem.InsuerName=venderName;
                //给日期赋值 
                if (!string.IsNullOrEmpty(tempItem.InsurancePolicyNo))
                {
                    var contractItem = policyItems.FirstOrDefault(c => c.InsuranceNo == tempItem.InsurancePolicyNo);
                    if (contractItem != null)
                    {
                        tempItem.EndDate =contractItem.ExpireDate;
                        tempItem.PolicyFile = contractItem.InsuranceFile;
                    }

                    
                }              
                 tempItem.InsuerId = venderId;
                tempItem.ProjectId = projectId;
                AssetItems.Add(tempItem);
            }
        }

        #region 信息转换
        private AssetShowItem ConvertAssetShowItem(InsuerAssetItem dataItem)
        {
            var showItem = new AssetShowItem();
            showItem.FamilyCode = dataItem.Family;
            showItem.Id = dataItem.Id;

            showItem.AssetNo = dataItem.Id;
            showItem.LocalName = dataItem.Asset.EquipLocalName;
            showItem.LocalCode = dataItem.Asset.EquipLocalId;
            showItem.Brand = dataItem.Asset.Brand;
            showItem.Product = dataItem.Asset.Product;
            showItem.Type = dataItem.Asset.Specification;

            showItem.EndDate = dataItem.Asset.ExpireDate;
            showItem.InsurancePolicyNo = dataItem.Asset.InsuranceNo;
            showItem.PolicyFile = dataItem.Asset.InsuranceFile;
            return showItem;
        }
        private PolicyShowItem ConvertPolicyShowItem(InsuerContractStatisticsItem dataItem)
        {
            var showItem = new PolicyShowItem();
            showItem.PolicyNo = dataItem.InsuranceNo;
            showItem.RefAssetCount = (int)dataItem.PropertyCount.ToDouble();
            showItem.EndDate = dataItem.ExpireDate;
            showItem.PolicyFile = dataItem.InsuranceFile;
            return showItem;
        }
        #endregion
        private void LoadProjectItem(string projectId)
        {
            var projectItem = BllFactory<ProjectBll>.Instance.GetProjectItem(projectId);
            if (projectItem != null)
            {
                this.ProjectName = projectItem.Name;
            }

        }



        private bool UpdateAssetPolicyNo(AssetShowItem item,PolicyUpdateContext context)
        {
            if (!context.CanExecute)
            {
                //没对资产信息进行修改
                return false;
            }
            var useItem = ConvertUpdateItem(item);
            useItem.InsurancePolicyNo = context.PolicyNo;
            if (context.EditType == EditType.Correct)
            {
                useItem.CacheParameters.SetAllParameterTime(context.EffectiveTime);
            }
            bool flag = AssetManager.UpdateAssetItems(ProjectId, new List<AssetShowItem>() {useItem });
            if (flag)
            {
                MessageTip.Show(this.GetWindow(), "修改保单号成功");
            }
            else
            {
                MessageTip.Show(this.GetWindow(), "修改保单号失败");
            }
            return flag;
        }

        private AssetShowItem ConvertUpdateItem(AssetShowItem item)
        {
            var newItem = new AssetShowItem();
            newItem.Id = item.Id;
            newItem.InsurancePolicyNo = item.InsurancePolicyNo;
            newItem.CacheParameters.Merge(item.CacheParameters);
            newItem.CacheParameters.Add((new WatchParameter(MBIBuiltInParameter.InsuranceNum)));
            return newItem;
        }
        #endregion
        #region 保存资产相关
        private bool CreatePolicyAsset()
        {
            if (this.AssetItems == null || !this.AssetItems.Any())
                return true;
            //保单或保险商任意发生变化，都修改
            //判断当前保险单号，和item中的保险单号
            List<AssetShowItem> changedItems = new List<AssetShowItem>();
            foreach (var item in this.AssetItems)
            {
                item.CacheParameters.Clear();
                var parameters = GetChangeParameters(item);
                if (!parameters.IsEmpty)
                {
                    item.CacheParameters.Merge(parameters);
                    changedItems.Add(item);
                }
            }
            //关掉也不影响保存流程
            if (changedItems.Any())
            {
                AssetSaveContext context = new AssetSaveContext();
                context.ChangedItems = changedItems;
                WinPolicySaveEnsure win = new WinPolicySaveEnsure();
                win.Owner = this.GetWindow();
                LoadParameter.StartParameter(win, new LoadParameter(context));
                if (win.ShowDialog() == true)
                {
                    context = win.GetRealResult<AssetSaveContext>();
                    if (context != null)
                    {
                        var items = context.ChangedItems ?? new List<AssetShowItem>();
                        foreach (var item in items)
                        {
                            if (context.EditType == EditType.Correct)
                            {
                                item.CacheParameters.SetAllParameterTime(context.EffectiveTime);
                            }
                        }
                    }
                }
            }

            #region 修改厂商，保单号发生变化的资产
            List<AssetShowItem> updateItems = new List<AssetShowItem>();
            AssetItems.ToList().ForEach(assetItem =>
            {
                ///todo 历史值存储
                if (!assetItem.CacheParameters.IsEmpty)
                {
                    assetItem.CacheParameters.CheckAdd((new WatchParameter(MBIBuiltInParameter.InsuranceNum)));
                }
               
            });
            bool flag = AssetManager.UpdateAssetItems(ProjectId, updateItems.ToList());
            #endregion
            return flag;

        }
        /// <summary>
        /// 初始化变化参数
        /// </summary>
        /// <param name="item"></param>
        private WatchParameters GetChangeParameters(AssetShowItem item)
        {
            WatchParameters parameters = new WatchParameters();
            //获取变化的资产：缺原始数据
            //if (!string.IsNullOrEmpty(item.InsurancePolicyNo)&&item.InsurancePolicyNo != "")
            //{
            //    parameters.Add(new WatchParameter(MBIBuiltInParameter.InsuranceNum));
            //}
            return parameters;
        }
        #endregion
        /// <summary>
        /// 成功保存后处理
        /// </summary>
        private void AfterSuccessSave()
        {
               LoadAssetItems(InsuerId, ProjectId);
        }
    }
}
