using Newtonsoft.Json.Linq;
using PTMedicalInsurance.Business;
using PTMedicalInsurance.Helper;
using PTMedicalInsurance.Variables;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PTMedicalInsurance.Forms
{
    public partial class FeeUpload : Form
    {
        private InvokeHelper invoker = new InvokeHelper();
        private MIIrisServices mIS = new MIIrisServices();
        private ManualResetEvent manualReset = new ManualResetEvent(true);
        private HisIrisServices hIS = new HisIrisServices();
        private string funNO;
        private int singleCount;
        private JArray jaFeeDetail;
        public string outParam;

        public struct userState
        {
            public int childProgress;
            public string description;
            public string error;
            public string detailHisCode;
            public string detailHisName;
            public string detailInsuCode;
        }

        private userState getUserState(int progress,string desc,string err, JToken jt)
        {
            userState us = new userState();
            us.childProgress = progress;
            us.description = desc;
            us.error = err;
            JObject jo = (JObject)jt;
            if (jt != null)
            {
                us.detailHisCode = jo["medins_list_codg"].ToString();
                us.detailHisName = jo["medins_list_desc"].ToString();
                us.detailInsuCode = jo["med_list_codg"].ToString();
            }
            
            return us;
        }
        public FeeUpload(string funNO, int singleCount, JArray jaFeeDetail)
        {
            InitializeComponent();
            this.funNO = funNO;
            this.singleCount = singleCount;
            this.jaFeeDetail = jaFeeDetail;
            this.pbFee.Maximum = 3;
            this.pbDetail.Maximum = jaFeeDetail.Count;

        }

        public FeeUpload(string funNO, int singleCount)
        {
            InitializeComponent();
            this.funNO = funNO;
            this.singleCount = singleCount;
        }

        private void btExit_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            Close();
        }

        public void setPos(int pos)
        {
            pbFee.Value = pos;
        }
        public void writeError(string error)
        {
            rtbRecord.AppendText(error + System.Environment.NewLine);
        }

        private void ProgressBar_Load(object sender, EventArgs e)
        {
            bgWorker1.WorkerReportsProgress = true;
            bgWorker1.WorkerSupportsCancellation = true;
            bgWorker1.RunWorkerAsync();
        }

        private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            string errMsg;
            int errorCount = 0;
            outParam = "";
            userState us = new userState();
            try
            {
                us = getUserState(0, "获取HIS费用", "......", null);
                bgWorker.ReportProgress(0, us);
                //获取IS费用
                if (hIS.getHisFee(Global.pat, out errMsg) != 0)
                {
                    us = getUserState(0, "获取HIS费用", "失败", null);
                    bgWorker.ReportProgress(0, us);
                    outParam = errMsg;
                    return;
                }
                else
                {
                    us = getUserState(1, "获取HIS费用", "成功", null);
                    bgWorker.ReportProgress(0, us);
                }
                //调用医保平台转换HIS费用（转换医保编码等）
                JObject joHisFee = JObject.Parse(errMsg);
                us = getUserState(0, "转换HIS费用", "......", null);
                bgWorker.ReportProgress(0, us);
                if (mIS.convertHisFeeWithInsuCode(joHisFee, out errMsg) != 0)
                {
                    us = getUserState(0, "转换HIS费用", "失败"+ errMsg, null);
                    bgWorker.ReportProgress(0, us);
                    outParam = errMsg;
                    return;
                }
                else
                {
                    us = getUserState(0, "转换HIS费用", "成功", null);
                    bgWorker.ReportProgress(0, us);
                }

                JArray jaFeeDetail = JArray.Parse(JsonHelper.getDestValue(JObject.Parse(errMsg), "data"));
                int feeCount = jaFeeDetail.Count();
                this.pbFee.Maximum = jaFeeDetail.Count;
                JArray jaTmp = new JArray();
                for (int i = 0; i < feeCount; i++)
                {
                    manualReset.WaitOne();

                    if (bgWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                    decimal cnt = decimal.Parse(jaFeeDetail[i]["cnt"].ToString());
                    decimal pric = decimal.Parse(jaFeeDetail[i]["pric"].ToString());
                    //decimal sumamt = decimal.Parse(jaFeeDetail[i]["det_item_fee_sumamt"].ToString());
                    jaFeeDetail[i]["dise_codg"] = new JObject();
                    jaFeeDetail[i]["dise_codg"] = Global.pat.disCode;
                    jaFeeDetail[i]["cnt"] = cnt.ToString("#0.0000");
                    jaFeeDetail[i]["pric"] = pric.ToString("#0.000000");
                    jaFeeDetail[i]["chrg_bchno"] = Global.pat.adm_Dr.ToString();
                    jaFeeDetail[i]["med_type"] = Global.pat.medType;
                    if (jaFeeDetail[i]["validFlag"].ToString() == "N")
                    {
                        bgWorker.ReportProgress(i, null);
                        continue;
                    }
                    jaTmp.Add(jaFeeDetail[i]);
                    if (((i + 1) % singleCount == 0) || ((i + 1) == jaFeeDetail.Count))
                    {

                        JObject joFeeDetail = new JObject();
                        joFeeDetail.Add("feedetail", jaTmp);
                        JObject joRtn = invoker.invokeCenterService(funNO, JsonHelper.setCenterInpar(funNO,joFeeDetail));
                        if (JsonHelper.parseCenterRtnValue(joRtn, out errMsg) != 0)
                        {
                            outParam = outParam + errMsg + System.Environment.NewLine;
                            us = getUserState(1, "解析中心返回值", "失败。原因：" + errMsg, jaFeeDetail[i]);
                            bgWorker.ReportProgress(i, us);
                            errorCount++;
                        }
                        else
                        {
                            us = getUserState(1, "解析中心返回值", "成功", jaFeeDetail[i]);
                            bgWorker.ReportProgress(i, us);
                            //广州需要检查每条MEMO是否为空
                            JArray jaRtnDetail = new JArray();
                            jaRtnDetail = JArray.Parse(JsonHelper.getDestValue(joRtn, "output.result"));
                            //foreach (JToken jt in jaRtnDetail)
                            //{
                            //    if (jt["memo"].ToString() != "")
                            //    {
                            //        outParam = outParam + errMsg + System.Environment.NewLine;
                            //        us = getUserState(2, "中心返回明细报错", jt["memo"].ToString(), jt);
                            //        errorCount++;
                            //    }
                            //}

                            //for (int j = 0; j < jaRtnDetail.Count; j++)
                            //{
                            //    if (jaRtnDetail[j]["memo"] != null)
                            //    {
                            //        var memo = jaRtnDetail[j]["memo"];

                            //        if (memo.ToString() != "")
                            //        {
                            //            outParam = outParam + memo + System.Environment.NewLine;
                            //            us = getUserState(2, "中心返回明细报错", memo.ToString(), null);
                            //            bgWorker.ReportProgress(i, us);
                            //            errorCount++;
                            //        }
                            //    }
                                
                            //}
                            //成功后插入医保平台
                            if (mIS.insertFee(jaTmp, out errMsg) != 0)
                            {
                                outParam = outParam + errMsg + System.Environment.NewLine;
                                us = getUserState(2, "插入医保平台", "失败。原因：" + errMsg, jaFeeDetail[i]);
                                errorCount++;
                            }
                            else
                                us = getUserState(2, "插入医保平台", "成功", jaFeeDetail[i]);
                            bgWorker.ReportProgress(i, us);
                            //更新2301返回的数据
                            if (mIS.updateFee(JArray.Parse(JsonHelper.getDestValue(joRtn, "output.result")), out errMsg) != 0)
                            {
                                outParam = outParam + errMsg + System.Environment.NewLine;
                                us = getUserState(3, "根据中心返回数据更新费用明细", "失败。原因：" + errMsg, jaFeeDetail[i]);
                                errorCount++;
                            }
                            else
                                us = getUserState(3, "根据中心返回数据更新费用明细", "成功", jaFeeDetail[i]);
                            bgWorker.ReportProgress(i, us);
                        }
                        jaTmp = new JArray();
                    }
                    bgWorker.ReportProgress(i + 1, null);
                }
                if ((errorCount == 0) && (e.Cancel == false))
                {
                    Thread.Sleep(1000);
                    this.DialogResult = DialogResult.OK;
                }
                else
                {
                    Global.writeLog("outParam:" +outParam);
                }
            }
            catch (Exception ex)
            {
                outParam = "费用上传异常:" + ex.Message;
            }

        }

        private void bgWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage < 0)
            {
                setPos(0);
            }
            else
            {
                setPos(e.ProgressPercentage);
            }

            if (e.UserState != null)
            {
                userState us = (userState)e.UserState;
                string upDetailRecord = "";
                upDetailRecord = "【His名称：" + us.detailHisName + ";";
                upDetailRecord = upDetailRecord + "His编码：" + us.detailInsuCode + "; ";
                upDetailRecord = upDetailRecord + "医保编码：" + us.detailInsuCode + ";";
                upDetailRecord = upDetailRecord + "当前节点：" + us.description + "】";
                upDetailRecord = upDetailRecord + us.error + System.Environment.NewLine;

                this.rtbRecord.AppendText(upDetailRecord);
                pbDetail.Value = us.childProgress;
            }

        }



        private void rtbRecord_TextChanged(object sender, EventArgs e)
        {
            rtbRecord.SelectionStart = rtbRecord.Text.Length;
            rtbRecord.ScrollToCaret();
        }

        private void btUpload_Click(object sender, EventArgs e)
        {
            if (!bgWorker1.IsBusy)
            {
                rtbRecord.Clear();
                bgWorker1.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("请点击停止按钮！");

            }
        }

        private void btPause_Click(object sender, EventArgs e)
        {
            if (btPause.Text == "暂停")
            {
                manualReset.Reset();//暂停当前线程的工作，发信号给waitOne方法，阻塞
                btPause.Text = "继续";
            }
            else
            {
                manualReset.Set();//继续某个线程的工作
                btPause.Text = "暂停";
            }
        }

        private void btStop_Click(object sender, EventArgs e)
        {
            if (bgWorker1.IsBusy)  bgWorker1.CancelAsync();
        }

        private void bgWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            { }

            if (e.Error != null)
            {
                outParam = e.Error.ToString();
            }
            //e.Result  
        }
    }
}
