using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Windows;
using Platform.Presentation.Interfaces;
using TellerSystem.Communication;
using TellerSystem.Library.Ext.Function;
using System.Windows.Controls;
using Platform.Controls.ControlsHelper;
using Platform.Presentation.PageFunctions;
using TellerSystem.ServiceProxy.Ext.ServiceEntitys;
using TellerSystem.ServiceProxy.Ext.ServiceHelper;
using Platform.Common.RunningParameters;
using System.Xml;
using TellerSystem.Library.Ext.Variables;
using Platform.Controls.NumericContainer;
using TellerSystem.PrintTemplate.Extension;
using TellerSystem.Library.Ext.TradeExtension;
using TellerSystem.Contract.ContractBase;

namespace TellerSystem.Contract.Function
{
    /// <summary>
    /// 复核对象，交易中使用此对象来提交一个复核请求
    /// </summary>
    public class CheckManager
    {
        public static CheckManager GetCheckManager(DependencyObject obj)
        {
            return (CheckManager)obj.GetValue(CheckManagerProperty);
        }

        public static void SetCheckManager(DependencyObject obj, CheckManager value)
        {
            obj.SetValue(CheckManagerProperty, value);
        }

        // Using a DependencyProperty as the backing store for AuthManager.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CheckManagerProperty =
            DependencyProperty.RegisterAttached("CheckManager", typeof(CheckManager), typeof(CheckManager), new UIPropertyMetadata(null));


        public delegate void AsksuperResultHandle(AsksuperResultType result, TradeBusData busData);

        /// <summary>
        /// 复核有结果时触发的事件
        /// </summary>
        public event AsksuperResultHandle AsksuperResultMessage;

        public CheckManager()
        {

        }

        //private IEnumerable<FrameworkElement> 
        /// <summary>
        /// 检查是否符合复核条件并提交申请复核
        /// </summary>
        /// <param name="target">交易对象</param>
        /// <param name="element">要素集合</param>
        /// <param name="msg">交易Message对象</param>
        /// <returns></returns>
        public bool DoSuper(PageBase target, CheckConditionElements element, Message msg, string funcnum, string accountno, double amount, string custname, string des)
        {
            //绑定到对象
            //((TradePage)target).GetCurrentTabItem().Tag = this;
            SetCheckManager(target, this);
            // 检查要素api
            bool t = CheckSuper(target, element, msg, TradeInfoData.GetTradeInfo(target as DependencyObject).TradeCode, funcnum);
            // 需要复核
            if (t)
            {
                TradeBusData tradedata = TradeInfoData.GetTradeInfo(target as DependencyObject).TradeBus;
                //将报文对象序列化上传到总线
                tradedata["MSG"] = target.Serialize(msg);
                return AskSuper(target, this.GetIPageElements((FrameworkElement)target), accountno, amount, custname, des);
            }
            else //不需要复核
                return true;
        }

        /// <summary>
        /// 得到tradepage中的需要复核回显和复核的数据项
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        private CheckElements GetIPageElements(FrameworkElement page)
        {
            List<FrameworkElement> elementList = new List<FrameworkElement>();
            List<TextBlock> textlockList = new List<TextBlock>();

            this.forElemengt((FrameworkElement)page, elementList, textlockList);

            CheckElements c = new CheckElements();

            for (int i = 0; i < elementList.Count; i++)
            {
                if (elementList[i] is CurrencyEditor)
                {
                    c.AddElement(CheckManager.GetAuthShowTitle(elementList[i]), ((CurrencyEditor)elementList[i]).Text.Replace(",", "")
                        , CheckManager.GetAuthCheckTitle(elementList[i]), InputType.Decimal);
                }
                else if (elementList[i] is TextBox)
                {
                    c.AddElement(CheckManager.GetAuthShowTitle(elementList[i]), ((TextBox)elementList[i]).Text
                        , CheckManager.GetAuthCheckTitle(elementList[i]), TextBoxHelper.GetInputType(elementList[i]), TextBoxHelper.GetIsToSBC(elementList[i]));
                }
                else if (elementList[i] is ComboBox)
                {
                    string selectedtext = ((ComboBox)elementList[i]).SelectedItem == null ? "" : ((ComboBox)elementList[i]).GetSelectedKey();
                    c.AddElement(CheckManager.GetAuthShowTitle(elementList[i]), selectedtext
                        , CheckManager.GetAuthCheckTitle(elementList[i]), TextBoxHelper.GetInputType(elementList[i]), false, ((ComboBox)elementList[i]).Items);
                }
            }

            return c;
        }

        /// <summary>
        /// 遍历需要复核的元素和复核是需要回显的元素
        /// </summary>
        /// <param name="element"></param>
        /// <param name="elementList"></param>
        /// <param name="textlockList"></param>
        private void forElemengt(FrameworkElement element, List<FrameworkElement> elementList, List<TextBlock> textlockList)
        {
            if (!string.IsNullOrEmpty(CheckManager.GetAuthShowTitle(element)) || !string.IsNullOrEmpty(CheckManager.GetAuthCheckTitle(element)))
            {
                if (element is TextBox || element is Platform.Controls.NumericContainer.CurrencyEditor || element is ComboBox)
                {
                    elementList.Add(element);
                }
                else if (element is TextBlock)
                {
                    textlockList.Add((TextBlock)element);
                }
            }

            int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(element);

            for (int i = 0; i < count; i++)
            {
                DependencyObject d = System.Windows.Media.VisualTreeHelper.GetChild(element, i);

                if (d is FrameworkElement)
                    forElemengt((FrameworkElement)d, elementList, textlockList);
            }
        }

        /// <summary>
        /// 有复核结果时，调用此方法，激活此对象的回调函数
        /// 在收到复核的结果消息或者用户取消撤销申请时调用此函数
        /// </summary>
        /// <param name="type"></param>
        /// <param name="flag"></param>
        public void Result(AsksuperResultType type, TradeBusData busData)
        {
            if (this.AsksuperResultMessage != null)
                this.AsksuperResultMessage(type, busData);
        }

        /// <summary>
        /// 可能有多个交易已经申请复核，这里使用前端流水号来作为区别标识，
        /// 在复核有返回结果的时候使用它找到此对象并激活复核结果事件
        /// </summary>
        public string SystemSerialNumber
        {
            get;
            set;
        }

        #region 是否为需要复核的数据项
        public static string GetAuthCheckTitle(DependencyObject obj)
        {
            return (string)obj.GetValue(AuthCheckTitleProperty);
        }

        public static void SetAuthCheckTitle(DependencyObject obj, string value)
        {
            obj.SetValue(AuthCheckTitleProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsAuthCheck.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AuthCheckTitleProperty =
            DependencyProperty.RegisterAttached("AuthCheckTitle", typeof(string), typeof(CheckManager), new UIPropertyMetadata(null));
        #endregion

        #region 是否作为回显数据项传递到复核界面
        public static string GetAuthShowTitle(DependencyObject obj)
        {
            return (string)obj.GetValue(AuthShowTitleProperty);
        }

        public static void SetAuthShowTitle(DependencyObject obj, string value)
        {
            obj.SetValue(AuthShowTitleProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsAuthShow.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AuthShowTitleProperty =
            DependencyProperty.RegisterAttached("AuthShowTitle", typeof(string), typeof(CheckManager), new UIPropertyMetadata(null));
        #endregion

        #region 复核机制API   added by chenming
        /// <summary>
        /// 检查复核
        /// </summary>
        /// <param name="target"></param>
        /// <param name="Element"> 复核要素</param>
        /// <param name="msg">报文对象</param>
        /// <param name="TradeNo">交易号</param>
        /// <param name="funcnum">复核条件序号</param>
        /// <returns></returns>
        private bool CheckSuper(PageBase target, CheckConditionElements Element, Message msg, string TradeNo, string funcnum)
        {
            bool result = false;
            CheckInfo checkinfo = new CheckInfo();
            checkinfo.tx_code = TradeNo;
            checkinfo.funcnum = funcnum;
            checkinfo.flag = 2;
            TradeBusData tradedata = TradeInfoData.GetTradeInfo(target as DependencyObject).TradeBus; //TradeBusData.GetTradeBusData((TradePage)target);
            string element = MergeElement(Element, msg);
            checkinfo.element = element;
            CheckResult res = TradeHandle.Check(checkinfo);
            if (res == null)
            {
                throw new Exception("检查是否复核出错，请检查网络是否正常");
            }
            else
            {
                if (res.checkresult)
                {
                    AuthDataHelper authdata = new AuthDataHelper(target);
                    CheckDataHelper checkdata = new CheckDataHelper(target);
                    //if (tradedata.ContainsKey("SuperFlag") || tradedata.ContainsKey("AuthFlag")) 
                    //之前做过复核或授权操作
                    if (!string.IsNullOrEmpty(authdata.AuthFlag) || !string.IsNullOrEmpty(checkdata.SuperFlag))
                    {
                        // 将上一流程的提交岗向服务端提交数据
                        var tradeInfo = new TellerInfo
                        {
                            TellerNo = LoginUserInfo.TellerNo,
                            TradeNo = TradeNo,
                            Tlrlvl = "",
                            BrNo = LoginUserInfo.KinbrNo,
                            //默认为1，标明该流程为正常结束
                            Status = 0,
                            TradeFileName = target.GetType().FullName,
                            BusinessDate = LoginUserInfo.TradeDate
                        };
                        WorkFlowHandle.GetWorkFlowTradeSubmit(
                                        tradeInfo, target.SaveTradePage(target as FrameworkElement), (Dictionary<string, string>)tradedata.Serialize(), checkdata.WorkItemId, target.CreateSerialNumber(), false, true);
                        authdata.ClearAuthData();
                        checkdata.ClearCheckData();
                    }
                    result = res.checkresult;
                    checkdata.Lvl = res.lvl;
                    //tradedata["lvl"] = res.lvl;
                    checkdata.Branch = res.brno;
                    //tradedata["Branch"] = res.brno;
                    //tradedata["AuthMode"] = res.mode;
                }
            }
            return result;
        }
        /// <summary>
        /// 申请复核
        /// </summary>
        /// <param name="target"></param>
        /// <param name="basedatas"></param>
        /// <param name="Superdata"></param>
        /// <param name="accountno">账号</param>
        /// <param name="amount">金额</param>
        /// <param name="custname">用户名</param>
        /// <param name="des">复核描述</param>
        private bool AskSuper(PageBase target, CheckElements Superdata, string accountno, double amount, string custname, string des)
        {
            TradePage page = (TradePage)target;
            // 记下此授权管理对象，后面可能需要再触发它的授权结果事件
            this.SystemSerialNumber = page.CreateSerialNumber();// 这里是获得前端流水号

            TradeInfoData data = TradeInfoData.GetTradeInfo(target as DependencyObject);
            TradeBusData tradedata = data.TradeBus;//TradeBusData.GetTradeBusData((TradePage)target);
            AskSuperInfo asksuper = new AskSuperInfo();
            CheckDataHelper checkdata = new CheckDataHelper(target);
            asksuper.accountno = accountno;
            asksuper.amount = amount;
            asksuper.custname = custname;
            asksuper.des = des;
            string serials = page.CreateSerialNumber();// WorkFlowHandle.GenNextSerialNo("2000", LoginUserInfo.TellerNo, LoginUserInfo.KinbrNo, "20120523");
            // string tellerSerials = page.CreateTellerSerialNumber(serials);
            asksuper.serialID = serials;
            asksuper.TellerNo = LoginUserInfo.TellerNo;
            asksuper.WorkFlowID = "Super";
            tradedata["TradeNo"] = data.TradeCode;
            tradedata["TradeName"] = data.TradeName;
            checkdata.SuperData = Superdata.XmlString;
            // tradedata["SuperData"] = Superdata.XmlString;
            tradedata["SerialId"] = serials;
            checkdata.IsWorkFlow = "true";
            //tradedata["IsWorkFlow"] = "true";
            if (TradeHandle.AskSuper(asksuper, (Dictionary<string, string>)tradedata.Serialize(), target.SaveTradePage((FrameworkElement)((TradePage)target).Content)))
            {
                //SystemFunction.ShowComfirmBox(target, "提示：已提交复核，稍后请从待办任务中继续做此交易", new string[] { "确定" });
                target.TradeAPIs.ShowInfoMessageBox("已提交复核，稍后请从待办任务中继续做此交易\n流水号：["+serials+"]");
                // 申请完毕打印凭证
                //TellerSystem.Controls.Ext.PrintsHelper.Print_AuthOrCheck form = new PrintTemplate.Common.Print_AuthOrCheck()
                //    {
                //        IsForSeach="True",
                //        IsShowAuthentic="False",
                //        IsShowTellerNo = "True"
                //    };
                //form.SerialNumber = tellerSerials;
                //form.BranchNo = LoginUserInfo.KinbrNo;
                //form.TradeName = data.TradeName;
                //form.VoucherNo = "";
                //form.SerialNo = serials;
                //form.AskDescription = "前端流水号" + serials + "   柜员：" + LoginUserInfo.TellerNo + "  时间：" + UserFunction.FormatDateTime(LoginUserInfo.TradeDate)[0] + " " +DateTime.Now.ToString("hh:mm:ss")  + "  申请复核。";

                //TradePageExtension.PrintCertificate(target, new Platform.Print.PrintContainer[] { form });

                //HideTrade(target); 
                target.HideTradeTab(target);
                //return true;
            }
            else
            {
                target.TradeAPIs.ShowErrorMessageBox("申请复核失败");
                //return false;
            }
            return false;
        }
        /// <summary>
        /// 整合核心返回要素值与前台要素值
        /// </summary>
        /// <param name="property"></param>
        /// <param name="dic"></param>
        /// <returns></returns>
        private string MergeElement(CheckConditionElements Element, Message msg)
        {
            StringBuilder result = new StringBuilder();
            result.Append("{\"Message\":");
            result.Append(msg.SerializeForAuth());
            result.Append(",\"Element\":");
            result.Append(Element.JsonValue);
            result.Append("}");
            return result.ToString();
        }

        #endregion 复核机制API   added by chenming
    }
    /// <summary>
    /// 复核和授权结果类型
    /// </summary>
    public enum AsksuperResultType
    {
        Success = 0,
        Failed = 1,
        Undo = 2,
    }
}
