using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using TellerSystem.Communication;
using Platform.Common.RunningParameters;
using TellerSystem.ServiceProxy.Ext.ServiceHelper;
using System.IO;
using System.Windows;
using TellerSystem.Library.Ext.Function;
using Newtonsoft.Json.Linq;
using TellerSystem.Library.Ext.TradeExtension;
using Newtonsoft.Json;
using TellerSystem.Contract.Function;
using TellerSystem.ServiceProxy.Ext;
using TellerSystem.Contract.ContractBase;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using System.Text.RegularExpressions;

namespace TellerSystem.Contract.Extend
{
    public class Reconciles
    {
        #region Ctor
        private Reconciles()
        {
        }

        private static Reconciles instance;

        public static Reconciles Instance
        {
            get
            {
                if (instance == null)
                    instance = new Reconciles();
                return instance;
            }
        }
        #endregion

        //文件分割符
        string Separator = "^|";


        #region Query
        /// <summary>
        /// 查询机构同步的最新记录
        /// </summary>
        /// <returns></returns>
        public List<Dictionary<string, string>> QuerySyncInfo()
        {
            var resp = AICapacity.GetInstence().AIRequest("/recon/manage/syncInfo", new Dictionary<string, string> { });
            if (resp.HasError)
                return null;
            return resp.Value<List<Dictionary<string, string>>>("data", null);
        }

        public bool SyncData2Branch(string branch, Action<Tuple<int, string>> report)
        {
            var list = QuerySyncInfo();
            if (list == null) return false;
            var info = list.FirstOrDefault(x => x["branch"] == branch);
            if (info == null) return false;
            //网银同步任务
            if (string.IsNullOrEmpty(info["ext"])) info["ext"] = "{}";
            var ext = JsonConvert.DeserializeObject<Dictionary<string, string>>(info["ext"]);
            return Work2Daily(branch, ext.ContainsKey("sync2netbank") ? ext["sync2netbank"] : "");
            //采用同步ODS数据进行数据同步,弃用柜面的数据同步功能
            //上传任务 status 0-可同步，1-上传完成，2-解析，21-解析出错，3-对账，31-对账出错，4-完结
            //if (info["status"] != "0") return false;//状态允许上传时，才触发 
            //return Work2Monthly(branch, info["syncIssue"]);
        }
        #endregion

        #region Monthly
        #region Dict
        private static Dictionary<string, string> _ID_TYPE_ = new Dictionary<string, string>
        {
            {"1","身份证"},
            {"2","户口簿"},
            {"3","护照"},
            {"4","军人证"},
            {"5","回乡证"},
            {"6","士兵证"},
            {"7","港澳居民来往通行证"},
            {"8","企业代码证"},
            {"9","经营许可证"},
            {"A","营业执照"},
            {"B","事业法人证书 "},
            {"C","工商核准号"},
            {"D","其他（对公）"},
            {"E","临时身份证"},
            {"F","外国人居留证 "},
            {"G","警官证"},
            {"H","其他证件（对私）"},
            {"I","台湾同胞来往通行证"},
            {"J","军官证"},
            {"K","文职干部证"},
            {"L","军官退休证"},
            {"M","文职干部退休证"},
            {"N","武警身份证"},
            {"O","武警士兵证"},
            {"P","武警文职干部证"},
            {"Q","武警军官退休证"},
            {"R","武警文职干部退休证"},
            {"S","机构信用代码证"},
            {"T","贷款卡"},
        };

        private static Dictionary<string, string> _COP_SIZE_ = new Dictionary<string, string>
        {
            //{"1","身份证"},
            {"2","大型企业"},
            {"3","中型企业"},
            {"4","小型企业"},
            {"5","微型企业"},
            {"6","小型企业"},
            {"9","其他"},
        };

        private static Dictionary<string, string> _DD_TYPE_ = new Dictionary<string, string>
        {
            {"1","基本户"},
            {"2","一般户"},
            {"3","专用存款户"},
            {"4","临时存款户"},
            {"5","个人存款户（储蓄户）"},
            {"6","协定（理财）户"},
            {"7","公积金活期户（个人）"},
            {"8","验证户"},
        };

        private static Dictionary<string, string> _TD_TYPE_ = new Dictionary<string, string>
        {
            {"0","整存整取"},
            {"1","零存整取"},
            {"2","整存零取"},
            {"3","存本取息"},
            {"4","通知存款"},
            {"5","协议存款"},
            {"6","定活两便"},
            {"7","教育储蓄"},
            {"A","利润最大化通知存款"},
        };

        private static Dictionary<string, string> _LN_TYPE_ = new Dictionary<string, string>
        {
            {"1","普通贷款"},
            {"2","按揭贷款"},
            {"5","承兑垫款"},
            {"7","委托贷款"},
            {"9","贴现"},
            {"A","授信贷款"},
            {"B","卡内融资、质押消费贷款"},
            {"C","银/社团贷款"},
        };

        private static Dictionary<string, string> _AC_STS_ = new Dictionary<string, string>
        {
            {"0","开户待确认"},
            {"1","正常"},
            //{"2",""},
            {"3","挂失结清"},
            {"4","开户更正"},
            {"5","临时销户"},
            {"6","久悬"},
            {"7","销户申请零余额"},
            {"8","销户申请"},
            {"9","挂失销户"},
            {"*","销户"},
            {"#","未激活"},
            {"A","损坏卡更换介质申请"},
        };

        private static Dictionary<string, string> _LN_STS_ = new Dictionary<string, string>
        {
            {"1","正常"},
            {"2","逾期90天内"},
            {"3","呆滞"},
            {"4","呆账"},
            {"5","逾期90天外"},
            {"8","开户未审核"},
            {"9","开户撤销"},
            {"*","销户"},
            {"#","已出表"},
        };

        private static Dictionary<string, string> _CUR_NO_ = new Dictionary<string, string>
        {
            {"01","人民币"},
        };

        private static Dictionary<string, string> _CT_IND_ = new Dictionary<string, string>
        {
            {"1","现金"},
            {"2","转账"},
        };
        #endregion

        private string Chg2Dict(string key, Dictionary<string, string> dict)
        {
            //不做翻译
            return key;
            if (dict == null || !dict.ContainsKey(key)) return key;
            return dict[key];
        }

        /// <summary>
        /// 同步机构数据
        /// </summary>
        /// <param name="kinbr"></param>
        /// <param name="report"></param>
        /// <returns></returns>
        private bool Work2Monthly(string branch, string last)
        {
            var current = last.ToDateTime();//上次同步截止日
            var sdate = current.AddDays(1).ToString("yyyyMMdd");//设定开始日
            var edate = LoginUserInfo.TradeDate.ToDateTime().AddDays(-1).ToString("yyyyMMdd");//截止到昨日
            if (string.Compare(edate, sdate) < 0) return false;//截止日必须大约开始日
            var regex_phone = new Regex("^1[3-9]{1}[0-9]{9}$");
            //数据载体
            var data = new List<Tuple<Dictionary<string, string>, List<Account>>>();
            //公共 
            var cif_basic_inf = Table("cif_basic_inf", " \"TYPE\" ='2' AND FILLER1 = '" + branch + "'");//客户基本信息
            var cif = string.Format(cif_basic_inf.Namespace, "CIF_NO");
            var add_info = Table("add_info", "INFO_TYPE ='1'");//联系人表
            var cif_cop_inf = Table("cif_cop_inf", "CIF_NO in (" + cif + ")");//对公客户信息表
            var cif_id_code_rel = Table("cif_id_code_rel", "CIF_NO in (" + cif + ")");//客户主证件信息表  //MAIN_FLAG ='1' and   去掉获取主证件的类型
            var cif_mger_rel = Table("cif_mger_rel", "CIF_NO in (" + cif + ") and STAT = '1'");//客户经理关系
            var note_parm = Table("note_parm", "1=1", new List<string> { "NOTE_TYPE", "NAME" }).Select().ToDictionary(x => x["NOTE_TYPE"].ToString(), x => x["NAME"].ToString());//凭证类型
            var prdt_acc_no = Table("prdt_acc_no", "DATA_CODE = '0152'");//科目和产品关系信息表
            var acc_no = string.Format(prdt_acc_no.Namespace, "ACC_NO");

            var com_item = Table("com_item", "ACC_NO in (" + acc_no + ")"); //科目名称
            foreach (DataRow row in cif_basic_inf.Rows)//装载客户信息
            {
                var cifcopinf = cif_cop_inf.Select("CIF_NO = '" + row["CIF_NO"].ToString() + "'").FirstOrDefault();
                if (cifcopinf == null) continue;
                var cifidcoderel = cif_id_code_rel.Select("MAIN_FLAG ='1' and CIF_NO = '" + row["CIF_NO"].ToString() + "'").FirstOrDefault();
                if (cifidcoderel == null)
                {
                    cifidcoderel = cif_id_code_rel.Select("CIF_NO = '" + row["CIF_NO"].ToString() + "'").FirstOrDefault();
                }
                if (cifidcoderel == null) continue;

                var dict = new Dictionary<string, string>
                {
                    {"客户编码", row["CIF_NO"].ToString()},
                    {"主证件类型", Chg2Dict(cifidcoderel["ID_TYPE"].ToString(),_ID_TYPE_)},
                    {"主证件号码", cifidcoderel["ID_NO"].ToString()},
                    {"开户网点", row["FILLER1"].ToString()},
                    {"客户名称", row["NAME"].ToString()},
                    {"企业规模", Chg2Dict(cifcopinf["COP_SIZE"].ToString(),_COP_SIZE_)},
                    {"企业联系人", cifcopinf["LINK_MAN"].ToString()},
                    {"固定电话", cifcopinf["TELEPHONE"].ToString()},
                    {"法人姓名", cifcopinf["AP_NAME"].ToString()},
                    {"法人证件类型", cifcopinf["AP_ID_TYPE"].ToString()},
                    {"法人证件号码", cifcopinf["AP_ID_NO"].ToString()},
                };
                //检测手机号合法性
                if (!regex_phone.IsMatch(dict["固定电话"]))
                {
                    if (string.IsNullOrEmpty(dict["固定电话"]) || regex_phone.IsMatch(cifcopinf["PHONE"].ToString()))
                        dict["固定电话"] = cifcopinf["PHONE"].ToString();
                }
                data.Add(new Tuple<Dictionary<string, string>, List<Account>>(dict, new List<Account>()));
            }
            //处理活期
            var dd_mst = Table("dd_mst", "CIF_NO in (" + cif + ") and AC_STS <> '*' and AC_SEQN < '9999'");//账户序号>9999的专户暂不纳入
            var acid = string.Format(dd_mst.Namespace, "ac_id");
            var mdm_ac_rel2dd_mst = Table("mdm_ac_rel", "ac_id in(" + acid + ")", new List<string> { "AC_NO", "AC_ID", "AC_SEQN", "NAME", "NOTE_STS" });
            var dd_mst_hst = Table("dd_mst_hst", "TX_DATE >= '" + sdate + "' and TX_DATE <= '" + edate + "' and ac_id in(" + acid + ")");
            var dd_parm = Table("dd_parm", "CIF_TYPE <> '1'", new List<string> { "PRDT_NO", "TITLE" });
            data.ForEach(x => //装载活期账户数据
            {
                var cifno = x.Item1["客户编码"];
                dd_mst.Select("CIF_NO = '" + cifno + "'").ToList().ForEach(row =>
                {
                    //mdm_ac_rel表中的 ac_seqn 不是账户序号
                   // var where = "AC_ID = '" + row["AC_ID"].ToString() + "' and AC_SEQN = '" + row["AC_SEQN"].ToString() + "'";
                    var where = "AC_ID = '" + row["AC_ID"].ToString() + "'";
                    var mdmacrel = mdm_ac_rel2dd_mst.Select(where).FirstOrDefault();
                    if (mdmacrel == null)
                    {
                        return;
                    }
                    var addinfo = add_info.Select("AC_NO = '" + mdmacrel["AC_NO"].ToString() + "'").Where(a => regex_phone.IsMatch(a["INFO4"].ToString()) || regex_phone.IsMatch(a["INFO6"].ToString())).ToArray();
                    var ddparm = dd_parm.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var prdtaccno = prdt_acc_no.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var comitem = com_item.Select("ACC_NO = '" + prdtaccno["ACC_NO"].ToString() + "'").FirstOrDefault();
                    var account = new Account
                    {
                        KHH = cifno,
                        ZH = mdmacrel["AC_NO"].ToString(),
                        ZHLX = Chg2Dict(row["AC_TYPE"].ToString(), _DD_TYPE_),
                        ZHMC = mdmacrel["NAME"].ToString(),
                        ZHXH = row["AC_SEQN"].ToString(),
                        ZHZT = Chg2Dict(row["AC_STS"].ToString(), _AC_STS_),
                        BZ = Chg2Dict(row["CUR_NO"].ToString(), _CUR_NO_),
                        JGH = row["OPN_BR_NO"].ToString(),
                        CPBH = ddparm["PRDT_NO"].ToString(),
                        CPMC = ddparm["TITLE"].ToString(),
                        KHJL = string.Join(",", cif_mger_rel.Select(where).Select(i => i["MANG"].ToString())),
                        LXRXX = string.Format("{0:D2}@{1}", addinfo.Length, string.Join("@", addinfo.Select(i => string.Format("{0}@{1}@{2}@{3}@{4}", i["INFO1"].ToString(), i["INFO2"].ToString(), i["INFO3"].ToString(), regex_phone.IsMatch(i["INFO4"].ToString()) ? i["INFO4"].ToString() : i["INFO6"].ToString(), string.Empty)))),
                        ZHZL = "0",
                        YE = row["YS_BAL"].ToString(),
                        KMH = prdtaccno["ACC_NO"].ToString(),
                        KMMC = comitem["ACC_NAME"].ToString(),
                        Details = new List<Dictionary<string, string>>(),
                    };
                    dd_mst_hst.Select(where).ToList().ForEach(i =>
                    {
                        var dict = new Dictionary<string, string>
                        {
                            {"序号", account.ZHXH},
                            {"交易日期", i["TX_DATE"].ToString()},
                            {"现转", Chg2Dict(i["CT_IND"].ToString(),_CT_IND_)},
                            {"摘要", i["BRF"].ToString()},
                            {"凭证号码", i["NOTE_NO"].ToString()},
                            {"凭证类型", Chg2Dict(i["NOTE_TYPE"].ToString(),note_parm)},
                            {"借方发生额", i["ADD_IND"].ToString() == "0" ? i["TX_AMT"].ToString() : "0.00"},
                            {"贷方发生额", i["ADD_IND"].ToString() == "1" ? i["TX_AMT"].ToString() : "0.00"},
                            {"余额", i["BAL"].ToString()},
                            {"记账柜员", i["TEL"].ToString()},
                            {"记账流水", i["TRACE_NO"].ToString()},
                            {"对方户名", i["DF_AC_NAME"].ToString()},
                        };
                        account.Details.Add(dict);
                    });
                    x.Item2.Add(account);
                });
            });
            //处理定期
            var td_mst = Table("td_mst", "CIF_NO in (" + cif + ") and AC_STS <> '*' and AC_SEQN < '9999'");
            acid = string.Format(td_mst.Namespace, "ac_id");
            var mdm_ac_rel2td_mst = Table("mdm_ac_rel", "ac_id in(" + acid + ")", new List<string> { "AC_NO", "AC_ID", "AC_SEQN", "NAME", "NOTE_STS" });
            var td_mst_hst = Table("td_mst_hst", "TX_DATE >= '" + sdate + "' and TX_DATE <= '" + edate + "' and ac_id in(" + acid + ")");
            var td_parm = Table("td_parm", "CIF_TYPE <> '1'", new List<string> { "PRDT_NO", "TITLE", "TD_TYPE" });
            data.ForEach(x => //装载定期账户数据
            {
                var cifno = x.Item1["客户编码"];
                td_mst.Select("CIF_NO = '" + cifno + "'").ToList().ForEach(row =>
                {
                    //mdm_ac_rel表中的 ac_seqn 不是账户序号
                  //  var where = "AC_ID = '" + row["AC_ID"].ToString() + "' and AC_SEQN = '" + row["AC_SEQN"].ToString() + "'";
                    var where = "AC_ID = '" + row["AC_ID"].ToString() + "'";
                    var mdmacrel = mdm_ac_rel2td_mst.Select(where).FirstOrDefault();
                    if (mdmacrel == null) return;
                    var addinfo = add_info.Select("AC_NO = '" + mdmacrel["AC_NO"].ToString() + "'").Where(a => regex_phone.IsMatch(a["INFO4"].ToString()) || regex_phone.IsMatch(a["INFO6"].ToString())).ToArray();
                    var tdparm = td_parm.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var prdtaccno = prdt_acc_no.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var comitem = com_item.Select("ACC_NO = '" + prdtaccno["ACC_NO"].ToString() + "'").FirstOrDefault();
                    var account = new Account
                    {
                        KHH = cifno,
                        ZH = mdmacrel["AC_NO"].ToString(),
                        ZHLX = Chg2Dict(tdparm["TD_TYPE"].ToString(), _TD_TYPE_),
                        ZHMC = mdmacrel["NAME"].ToString(),
                        ZHXH = row["AC_SEQN"].ToString(),
                        ZHZT = Chg2Dict(row["AC_STS"].ToString(), _AC_STS_),
                        BZ = Chg2Dict(row["CUR_NO"].ToString(), _CUR_NO_),
                        JGH = row["OPN_BR_NO"].ToString(),
                        CPBH = tdparm["PRDT_NO"].ToString(),
                        CPMC = tdparm["TITLE"].ToString(),
                        KHJL = string.Join(",", cif_mger_rel.Select(where).Select(i => i["MANG"].ToString())),
                        LXRXX = string.Format("{0:D2}@{1}", addinfo.Length, string.Join("@", addinfo.Select(i => string.Format("{0}@{1}@{2}@{3}@{4}", i["INFO1"].ToString(), i["INFO2"].ToString(), i["INFO3"].ToString(), regex_phone.IsMatch(i["INFO4"].ToString()) ? i["INFO4"].ToString() : i["INFO6"].ToString(), string.Empty)))),
                        ZHZL = "1",
                        YE = row["YS_BAL"].ToString(),
                        KMH = prdtaccno["ACC_NO"].ToString(),
                        KMMC = comitem["ACC_NAME"].ToString(),
                        Details = new List<Dictionary<string, string>>(),
                    };
                    td_mst_hst.Select(where).ToList().ForEach(i =>
                    {
                        var dict = new Dictionary<string, string>
                        {
                            {"序号", account.ZHXH},
                            {"交易日期", i["TX_DATE"].ToString()},
                            {"现转", Chg2Dict(i["CT_IND"].ToString(),_CT_IND_)},
                            {"摘要", i["BRF"].ToString()},
                            {"凭证号码", i["NOTE_NO"].ToString()},
                            {"凭证类型", Chg2Dict(i["NOTE_TYPE"].ToString(),note_parm)},
                            {"借方发生额", i["ADD_IND"].ToString() == "0" ? i["TX_AMT"].ToString() : "0.00"},
                            {"贷方发生额", i["ADD_IND"].ToString() == "1" ? i["TX_AMT"].ToString() : "0.00"},
                            {"余额", i["BAL"].ToString()},
                            {"记账柜员", i["TEL"].ToString()},
                            {"记账流水", i["TRACE_NO"].ToString()},
                            {"对方户名", i["DF_NAME"].ToString()},
                        };
                        account.Details.Add(dict);
                    });
                    x.Item2.Add(account);
                });
            });
            //处理贷款
            var ln_mst = Table("ln_mst", "CIF_NO in (" + cif + ") and AC_STS <> '*' and AC_SEQN < '9999'");
            acid = string.Format(ln_mst.Namespace, "ac_id");
            var mdm_ac_rel2ln_mst = Table("mdm_ac_rel", "ac_id in(" + acid + ")", new List<string> { "AC_NO", "AC_ID", "AC_SEQN", "NAME", "NOTE_STS" });
            var ln_mst_hst = Table("ln_mst_hst", "TX_DATE >= '" + sdate + "' and TX_DATE <= '" + edate + "' and ac_id in(" + acid + ")");
            var ln_parm = Table("ln_parm", "CIF_TYPE <> '1'", new List<string> { "PRDT_NO", "TITLE", "LN_TYPE" });
            data.ForEach(x => //装载定期账户数据
            {
                var cifno = x.Item1["客户编码"];
                ln_mst.Select("CIF_NO = '" + cifno + "'").ToList().ForEach(row =>
                {
                    //mdm_ac_rel表中的 ac_seqn 不是账户序号
                    //  var where = "AC_ID = '" + row["AC_ID"].ToString() + "' and AC_SEQN = '" + row["AC_SEQN"].ToString() + "'";
                    var where = "AC_ID = '" + row["AC_ID"].ToString() + "'";
                    var mdmacrel = mdm_ac_rel2ln_mst.Select(where).FirstOrDefault();
                    if (mdmacrel == null) return;
                    var addinfo = add_info.Select("AC_NO = '" + mdmacrel["AC_NO"].ToString() + "'").Where(a => regex_phone.IsMatch(a["INFO4"].ToString()) || regex_phone.IsMatch(a["INFO6"].ToString())).ToArray();
                    var lnparm = ln_parm.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var prdtaccno = prdt_acc_no.Select("PRDT_NO = '" + row["PRDT_NO"].ToString() + "'").FirstOrDefault();
                    var comitem = com_item.Select("ACC_NO = '" + prdtaccno["ACC_NO"].ToString() + "'").FirstOrDefault();
                    var account = new Account
                    {
                        KHH = cifno,
                        ZH = mdmacrel["AC_NO"].ToString(),
                        ZHLX = Chg2Dict(lnparm["LN_TYPE"].ToString(), _LN_TYPE_),
                        ZHMC = mdmacrel["NAME"].ToString(),
                        ZHXH = row["AC_SEQN"].ToString(),
                        ZHZT = Chg2Dict(row["AC_STS"].ToString(), _LN_STS_),
                        BZ = Chg2Dict(row["CUR_NO"].ToString(), _CUR_NO_),
                        JGH = row["OPN_BR_NO"].ToString(),
                        CPBH = lnparm["PRDT_NO"].ToString(),
                        CPMC = lnparm["TITLE"].ToString(),
                        KHJL = string.Join(",", cif_mger_rel.Select(where).Select(i => i["MANG"].ToString())),
                        LXRXX = string.Format("{0:D2}@{1}", addinfo.Length, string.Join("@", addinfo.Select(i => string.Format("{0}@{1}@{2}@{3}@{4}", i["INFO1"].ToString(), i["INFO2"].ToString(), i["INFO3"].ToString(), regex_phone.IsMatch(i["INFO4"].ToString()) ? i["INFO4"].ToString() : i["INFO6"].ToString(), string.Empty)))),
                        ZHZL = "2",
                        YE = row["YS_BAL"].ToString(),
                        KMH = prdtaccno["ACC_NO"].ToString(),
                        KMMC = comitem["ACC_NAME"].ToString(),
                        Details = new List<Dictionary<string, string>>(),
                    };
                    ln_mst_hst.Select(where).ToList().ForEach(i =>
                    {
                        var dict = new Dictionary<string, string>
                        {
                            {"序号", account.ZHXH},
                            {"交易日期", i["TX_DATE"].ToString()},
                            {"现转", Chg2Dict(i["CT_IND"].ToString(),_CT_IND_)},
                            {"摘要", i["BRF"].ToString()},
                            {"凭证号码", i["NOTE_NO"].ToString()},
                            {"凭证类型", Chg2Dict(i["NOTE_TYPE"].ToString(),note_parm)},
                            {"借方发生额", i["ADD_IND"].ToString() == "1" ? i["TX_AMT"].ToString() : "0.00"},
                            {"贷方发生额", i["ADD_IND"].ToString() == "0" ? i["TX_AMT"].ToString() : "0.00"},
                            {"余额", i["BAL"].ToString()},
                            {"记账柜员", i["TEL"].ToString()},
                            {"记账流水", i["TRACE_NO"].ToString()},
                            {"对方户名", i["DF_AC_NAME"].ToString()},
                        };
                        account.Details.Add(dict);
                    });
                    x.Item2.Add(account);
                });
            });
            if (data.Count == 0)
            {
                return false;
            }
            //执行压缩上传,剔除空白客户
            var zip = Zip(data.Where(x => x.Item2.Count > 0).ToList(), branch, edate);
            if (zip == null) return false;
            //上传文件服务器
            var resp = AICapacity.GetInstence().UploadFile(zip, string.Format("Reconciles_{0}_{1}.zip", branch, edate), 10);//留存10天
            if (resp.HasError) return false;
            //通知银企对账平台
            var req = new UploadData
            {
                branch = branch,
                fds = resp.Value("data", ""),
                syncIssue = edate,
            };
            resp = AICapacity.GetInstence().AIRequest("/recon/manage/uploadData", req);
            return !resp.HasError;
        }

        class UploadData : AICapacity.Req
        {
            public string branch { get; set; }
            public string fds { get; set; }
            public string syncIssue { get; set; }
        }

        /// <summary>
        /// 产生压缩文件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private byte[] Zip(List<Tuple<Dictionary<string, string>, List<Account>>> data, string branch, string date)
        {
            byte[] zipData = null;
            using (var ms = new MemoryStream())
            {
                var encoding = Encoding.UTF8;
                var zipStream = new ZipOutputStream(ms);
                zipStream.SetLevel(6);
                Crc32 crc = new Crc32();
                //var entry = new ZipEntry("20220520/");//一级目录
                //zipStream.PutNextEntry(entry);
                //处理客户文件
                var sb = new StringBuilder();
                sb.AppendLine("~" + string.Join(Separator, data.ElementAt(0).Item1.Keys));
                data.ToList().ForEach(x => sb.AppendLine(string.Join(Separator, x.Item1.Values)));
                var buffer = encoding.GetBytes(sb.ToString());
                ZipBuffer(buffer, zipStream, string.Format("{0}/{1}_customer.txt", date, branch));
                //处理账户文件
                sb = new StringBuilder();
                string customerheadle = "~客户号" + Separator + "账号" + Separator + "账户类型" + Separator + "账户种类" + Separator + "产品编号" + Separator + "产品名称" + Separator + "账户名称" + Separator + "账户序号" + Separator + "账户状态" + Separator + "余额" + Separator + "客户经理" + Separator + "交易明细" + Separator + "机构号" + Separator + "联系人信息" + Separator + "明细标志" + Separator + "币种" + Separator + "科目号" + Separator + "科目名称" + Separator;
                sb.AppendLine(customerheadle);
                data.Select(x => x.Item2).ToList().ForEach(list =>
                {
                    list.ForEach(acc =>
                    {
                        //处理账户明细
                        var detail = string.Empty;
                        if (acc.Details.Count > 0)
                        {
                            detail = string.Format("{0}_{1}.txt", acc.ZH, acc.ZHXH);
                            var hst = new StringBuilder();
                            hst.AppendLine("~" + string.Join(Separator, acc.Details[0].Keys));
                            acc.Details.ForEach(x => hst.AppendLine(string.Join(Separator, x.Values)));
                            buffer = encoding.GetBytes(hst.ToString());
                            ZipBuffer(buffer, zipStream, string.Format("{0}/{1}", date, detail));
                        }
                        var item = new List<string>
                        {
                            acc.KHH,
                            acc.ZH,
                            acc.ZHLX,
                            acc.ZHZL,
                            acc.CPBH,
                            acc.CPMC,
                            acc.ZHMC,
                            acc.ZHXH,
                            acc.ZHZT,
                            acc.YE,
                            acc.KHJL,
                            detail,
                            acc.JGH,
                            acc.LXRXX,
                            string.IsNullOrEmpty(detail)?"2":"1",
                            acc.BZ,
                            acc.KMH,
                            acc.KMMC,
                        };
                        sb.AppendLine(string.Join(Separator, item));
                    });
                });
                var name = string.Format("{0}/{1}_account.txt", date, branch);
                buffer = encoding.GetBytes(sb.ToString());
                ZipBuffer(buffer, zipStream, name);
                //写入到文件
                zipStream.CloseEntry();
                zipStream.Flush();
                zipStream.Close();
                zipData = ms.ToArray();
            }
            return zipData;
        }

        private void ZipBuffer(byte[] buffer, ZipOutputStream zipStream, string path)
        {
            Crc32 crc = new Crc32();
            var entry = new ZipEntry(path);
            entry.DateTime = DateTime.Now;
            entry.Size = buffer.Length;
            crc.Reset();
            crc.Update(buffer);
            entry.Crc = crc.Value;
            zipStream.PutNextEntry(entry);
            zipStream.Write(buffer, 0, buffer.Length);
        }

        #region table方案
        /// <summary>
        /// ~客户号|账号|账户类型|账户种类|产品名称|账户名称|账户序号|账户状态|余额|客户经理|交易明细|机构号|联系人信息|明细标志|币种|
        /// </summary>
        private class Account
        {
            /// <summary>
            /// 客户号
            /// </summary>
            public string KHH { get; set; }
            /// <summary>
            /// 账号
            /// </summary>
            public string ZH { get; set; }
            /// <summary>
            /// 账户类型
            /// </summary>
            public string ZHLX { get; set; }
            /// <summary>
            /// 账户种类
            /// </summary>
            public string ZHZL { get; set; }
            /// <summary>
            /// 产品名称
            /// </summary>
            public string CPMC { get; set; }
            /// <summary>
            /// 产品编号
            /// </summary>
            public string CPBH { get; set; }
            /// <summary>
            /// 账户名称
            /// </summary>
            public string ZHMC { get; set; }
            /// <summary>
            /// 账户序号
            /// </summary>
            public string ZHXH { get; set; }
            /// <summary>
            /// 账户状态
            /// </summary>
            public string ZHZT { get; set; }
            /// <summary>
            /// 余额
            /// </summary>
            public string YE { get; set; }
            /// <summary>
            /// 客户经理
            /// </summary>
            public string KHJL { get; set; }
            /// <summary>
            /// 机构号
            /// </summary>
            public string JGH { get; set; }
            /// <summary>
            /// 联系人信息
            /// </summary>
            public string LXRXX { get; set; }
            /// <summary>
            /// 币种
            /// </summary>
            public string BZ { get; set; }
            /// <summary>
            /// 科目号
            /// </summary>
            public string KMH { get; set; }
            /// <summary>
            /// 科目名称
            /// </summary>
            public string KMMC { get; set; }
            /// <summary>
            /// 明细记录
            /// </summary>
            public List<Dictionary<string, string>> Details { get; set; }
        }

        private DataTable Table(string table, string where, List<string> cols = null)
        {
            var dt = new DataTable(table);
            var sql = string.Format("select {0} from {1} where 1=1 and {2} ", "{0}", table, where);
            dt.Namespace = sql;
            var field = "*";
            if (cols == null)
                cols = Select("select column_name from user_tab_columns where table_name = '" + table.ToUpper() + "' order by  column_id ", "列名").Select(x => x["列名"].ToUpper()).ToList();
            else
                field = string.Join(",", cols);
            cols.ForEach(x => dt.Columns.Add(x));
            var rows = Select(string.Format(sql, field), string.Join("|", cols));
            rows.ForEach(row =>
            {
                dt.Rows.Add(row.Values.ToArray());
            });
            return dt;
        }

        private List<Dictionary<string, string>> Select(string sql, string format)
        {
            Message msg = new Message();
            SystemFunction.InitFd(null, msg);
            SystemFunction.CommSend(null, msg);
            msg.Fd16 = "9598";
            msg.Fd123 = sql;
            msg.DoTransit();
            if (msg.Fd12 != "0000")
            {
                Platform.Common.LogSystem.PlatformLogger.SystemErrorInfo("Reconciles.Select:查询失败!" + SystemFunction.GetError(null, msg), null);
                return null;
            }
            return TFInput.AnilyzeFileData(msg.FileData, format, x => x);
        }
        #endregion
        #endregion

        #region Daily



        /// <summary>
        /// 网银文件列
        /// </summary>
        private List<string> netBankcomList = new List<string>();


        private bool Work2Daily(string branch, string last)
        {
            var date = LoginUserInfo.TradeDate.ToDateTime().AddDays(-1);
            var start = string.IsNullOrEmpty(last) ? (date.ToString("yyyyMM") + "01") : last.ToDateTime().AddDays(1).ToString("yyyyMMdd");
            var end = date.ToString("yyyyMMdd");
            if (start.CompareTo(end) > 0) return false;//无效区间
            var dt = Recon2Netbank(LoginUserInfo.KinbrNo, start, end);
            //提取数据，调用银企对账接口处理同步，记得更新同步状态ext内sync2netbank=end
            //没有获取到网银数据
            if (dt == null)
            {
                return false;
            }
            return uploadReconDetail(branch, end, dt);
        }
        /// <summary>
        /// 网银数据上传和组装txt
        /// </summary>
        /// <param name="branch"></param>
        /// <param name="end"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        private bool uploadReconDetail(string branch, string end, DataTable dt)
        {
            byte[] zipData = null;
            string fileName = string.Format("{0}/{1}_reconDetailInfo", end, branch);
            using (var ms = new MemoryStream())
            {
                var encoding = Encoding.UTF8;
                var zipStream = new ZipOutputStream(ms);
                zipStream.SetLevel(6);
                Crc32 crc = new Crc32();
                //处理客户文件
                var sb = new StringBuilder();
                sb.AppendLine("~" + string.Join(Separator, netBankcomList.ToArray()) + Separator);
                foreach (DataRow row in dt.Rows)
                {
                    string rowstring = string.Empty;

                    foreach (var item in netBankcomList)
                    {
                        rowstring += row[item].ToString() + Separator;
                    }

                    sb.AppendLine(rowstring);
                }
                var buffer = encoding.GetBytes(sb.ToString());

                ZipBuffer(buffer, zipStream, fileName+".txt");
                //写入到文件
                zipStream.CloseEntry();
                zipStream.Flush();
                zipStream.Close();
                zipData = ms.ToArray();
            }
            var resp = AICapacity.GetInstence().UploadFile(zipData, fileName+".zip", 10);//留存10天
            if (resp.HasError) return false;

            //通知银企对账平台
            var req = new UploadNetbank
            {
                checkChannel = "NetBank",//渠道类型
                filePath = resp.Value("data", ""),
                syncEndDate = end,//结束日期
                branch = LoginUserInfo.KinbrNo//机构号
            };
            resp = AICapacity.GetInstence().AIRequest("/recon/manage/uploadReconDetailByTxt", req);
            return !resp.HasError;
        }

        /// <summary>
        /// 文件 转 Byte[]
        /// </summary>
        /// <param name="fileUrl"></param>
        /// <returns></returns>
        public byte[] FileToByteArray(string fileUrl)
        {
            using (FileStream fs = new FileStream(fileUrl, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                byte[] buffur = new byte[fs.Length];
                fs.Read(buffur, 0, (int)buffur.Length);
                return buffur;
            }
        }

        /// <summary>
        /// 网银对账数据类
        /// </summary>
        class UploadNetbank : AICapacity.Req
        {
            public string checkChannel { get; set; }
            public string filePath { get; set; }
            public string syncEndDate { get; set; }
            public string branch { get; set; }
        }
        /// <summary>
        /// 查询网银对账记录
        /// </summary>
        /// <param name="branch"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private DataTable Recon2Netbank(string branch, string start, string end)
        {
            var sb = new StringBuilder();
            var pagenum = 1;
            while (true)
            {
                Message message = new Message(Message.BitMap.Agn);
                SystemFunction.InitFd(null, message);
                SystemFunction.CommSend(null, message);
                message.Fd16 = "3004";
                message.Fd63 = "1";//对账标志
                message.Fd38 = branch;//本机构
                message.Fd18 = "ENT";
                message.Fd25 = start;//对账日期-开始
                message.Fd37 = end;//对账日期-截止
                message.Fd30 = pagenum.ToString();//页码
                message.TransitNode = Communication.MessageHelper.TransitType.CallAgn_CZYYSW;
                message.DoTransit();
                if (message.Fd12 == "0000")
                {
                    if (string.IsNullOrEmpty(message.FileData))
                        break;
                    sb.Append(message.FileData);
                }
                else
                {
                    sb.Clear();
                    break;
                }
                pagenum++;
            }
            if (sb.Length == 0) return null;
            var sr = new StringReader(sb.ToString());
            var dt = new DataTable();
            #region 原始处理数据情况
            //dt.Columns.Add("账号");
            //dt.Columns.Add("账户名称");
            //dt.Columns.Add("对账日期");
            //dt.Columns.Add("对账状态");//{ { "0", "未对账" }, { "1", "余额相符" }, { "2", "余额不符" } }
            //dt.Columns.Add("导入日期");
            //while (true)
            //{
            //    var line = sr.ReadLine();
            //    if (string.IsNullOrEmpty(line)) break;
            //    if (line.StartsWith("~")) continue;
            //    var tmp = line.Split('|').Take(5).ToArray();//注意，中牟的格式与其他行有异
            //    //只有中牟才返回了导入日期，其他行需要另处理
            //    if (ServiceSettings.BankFlag != "V0")
            //    {
            //        //TODO:其他行没有返回导入日期，可能需要用单笔再循环查询；暂采用对账日期计算上月底
            //        tmp[4] = (tmp[2].Substring(6) + "01").ToDateTime().AddDays(-1).ToString("yyyyMMdd");
            //    }
            //    dt.Rows.Add(tmp);
            //} 
            #endregion
            netBankcomList.Clear();
            netBankcomList.Add("账号");
            netBankcomList.Add("账户序号");
            netBankcomList.Add("对账期次");
            netBankcomList.Add("核心余额");
            netBankcomList.Add("核心余额日期");
            netBankcomList.Add("用户余额");
            netBankcomList.Add("用户余额备注");
            netBankcomList.Add("对账时间");
            netBankcomList.Add("完结时间");
            netBankcomList.Add("对账方式");//{ { "0", "周期对账" }, { "1", "相对对账" } }
            netBankcomList.Add("对账状态");//对账状态 0 未对账,1 待授权,2 差错处理中,3 对账完成
            netBankcomList.Add("对账结果");//{ { "0", "未对账" }, { "1", "余额相符" }, { "2", "余额不符" } }
            netBankcomList.Add("客户经理");


            foreach (var item in netBankcomList)
            {
                dt.Columns.Add(item);
            }
            while (true)
            {
                var line = sr.ReadLine();
                if (string.IsNullOrEmpty(line)) break;
                if (line.StartsWith("~")) continue;
                var tmp = line.Split('|').Take(6).ToArray();//注意，返回的格式是6列
                string[] row = new string[13];
                //只有中牟才返回了导入日期，其他行需要另处理
               // if (ServiceSettings.BankFlag == "V0" || ServiceSettings.BankFlag == "V8" || ServiceSettings.BankFlag == "V23" || (ServiceSettings.BankFlag == "V2" && LoginUserInfo.KinbrNo.Substring(0, 3) == "152"))
                #region 返回6列
                //@账号 | @账户名称 | @对账日期 | @对账状态|余额日期 |@对账余额
                if (tmp[5]!=null&& tmp[5].StartsWith("."))
                {
                    tmp[5] = "0" + tmp[5];
                }
                row[0] = tmp[0];	    //账号
                row[1] = "1";	    //账户序号
                row[2] = (tmp[4].Substring(0, 6) + "01").ToDateTime().AddMonths(1).ToString("yyyyMMdd");	 //对账期次   //对账期次
                row[3] = tmp[5];	    //核心余额
                row[4] = tmp[4];	    //核心余额时间
                row[5] = tmp[3] == "1" ? tmp[5] : string.Empty;//    //用户余额
                row[6] = string.Empty;	    //用户余额备注
                row[7] = tmp[2];	    //对账时间
                row[8] = tmp[2];	    //完结时间
                row[9] = "0";	    //对账方式
                row[10] = "3";    //对账状态
                row[11] = tmp[3];    //	对账结果
                row[12] = string.Empty;    //客户经理 
                #endregion


                #region 网银返回5列的情况  废除
                    //    //@账号 | @账户名称 | @对账日期 | @对账状态 |@对账余额
                    //    //TODO:其他行没有返回导入日期，可能需要用单笔再循环查询；暂采用对账日期计算上月底
                    //    string impdate = (tmp[2].Substring(0, 6) + "01").ToDateTime().AddDays(-1).ToString("yyyyMMdd");
                    //    row[0] = tmp[0];	    //账号
                    //    row[1] = "1";	    //账户序号
                    //    row[2] = tmp[2].Substring(0, 6) + "01";	    //对账期次
                    //    row[3] = tmp[4];	    //核心余额
                    //    row[4] = impdate;	    //核心余额时间
                    //    row[5] = tmp[3] =="1" ? tmp[4] : string.Empty;//   //用户余额
                    //    row[6] = string.Empty;	    //用户余额备注
                    //    row[7] = tmp[2];	    //对账时间
                    //    row[8] = tmp[2];	    //完结时间
                    //    row[9] = "0";	    //对账方式
                    //    row[10] = "3";    //	对账状态
                    //    row[11] = tmp[3];    //	对账结果
                    //    row[12] = string.Empty;    //	客户经理 
                    #endregion


                //0 余额相符
                //1 余额不符
                //2 差错相符
                //3 差错不符

                switch (row[11].ToString())
                {
                    case "0"://"未对账"
                        row[11] = "";
                        break;
                    case "1"://"余额相符"
                        row[11] = "0";
                        break;
                    case "2":// "余额不符"
                        row[11] = "1";
                        break;
                    default:
                        row[11] = "";
                        break;
                }

                dt.Rows.Add(row);
            }
            return dt;
        }
        #endregion
    }
}
