using NPOI.HSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DuoVia.FuzzyStrings;
/// <summary>
/// 功能: 建立檢查資料檔與影像的背景程序。
/// 維護: 
/// [108/04/24][] > 完成基礎代碼撰寫，未測試。
/// 建立於: 108/04/24
/// </summary>
namespace ETC_App1
{
    public partial class ETCBackgroundWorker3 : BackgroundWorker
    {
        public Dictionary<string, List<Dictionary<string, string>>> Data = new Dictionary<string, List<Dictionary<string, string>>>();

        public Dictionary<string, string> Images = new Dictionary<string, string>();

        public Dictionary<string, string> Processed = new Dictionary<string, string>();

        public string SelectedKey { get; set; }


        public ETCBackgroundWorker3()
        {
            InitializeComponent();
        }

        private double Elapsed(long milliseconds, out string message)
        {
            double elapsed = Convert.ToDouble(milliseconds);

            double temp = elapsed;

            message = "";

            if (temp >= 1000)
            {
                if ((temp /= 1000) >= 60)
                {
                    if ((temp /= 60) >= 60)
                    {
                        if ((temp /= 60) >= 24)
                        {
                            message = message + "約 " + temp + " 天。";
                        }
                        else
                        {
                            message = message + "約 " + temp + " 小時。";
                        }
                    }
                    else
                    {
                        message = message + "約 " + temp + " 分鐘。";
                    }
                }
                else
                {
                    message = message + "約 " + temp + " 秒。";
                }
            }
            else
            {
                message = message + " " + temp + " 毫秒。";
            }

            return elapsed;
        }

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            if (Data.Count > 0 && Data.ContainsKey(SelectedKey) && Data[SelectedKey].Count > 0)
            {
                List<Dictionary<string, string>> data = Data[SelectedKey];

                HyperLPR server = new HyperLPR();

                double elapsed = 0;

                int start = Convert.ToInt32(e.Argument);

                StreamWriter sw = new StreamWriter("output.txt");

                for (int i = start; i < data.Count && !CancellationPending; i++)
                {
                    Stopwatch stopwatch = Stopwatch.StartNew();

                    string key = data[i]["帳單編號"];

                    string filename = Images.ContainsKey(key) ? Images[key] : Processed.ContainsKey(key) ? Processed[key] : "找無檔案";

                    //string filename = data[i].ContainsKey("帳單編號") && Images.ContainsKey(data[i]["帳單編號"]) ? /*data[i]["帳單編號"] = */Images[data[i]["帳單編號"]] : "";
                    
                    string plate = data[i]["車牌號碼"].Replace("-", "");
                    
                   
                    Json json = File.Exists(filename) ? server.Process(filename) : new Json() { message2 = "影像遺失", lost1 = true, };
                    

                    if (Images.ContainsKey(key) && !Processed.ContainsKey(key))
                    {
                        Processed.Add(key, Images[key]);

                        Images.Remove(key);
                    }

                    json.index = Convert.ToString(i).PadLeft(Convert.ToInt32(Math.Log10(data.Count) + 1), '0');

                    json.filename = filename;

                    json.success = !(json.failed = json.tickoff = true);

                    if (File.Exists(filename))
                    {
                        using (FileStream stream = new FileStream(filename, FileMode.Open))
                        {
                            json.content = stream.Length > 0 ? true : false;

                            stream.Close();
                        }
                    }



                    if (json.result != null && json.result.Count > 0)
                    {
                        json.lost1 = json.lost2 = false;

                        for (int j = 0; j < json.result.Count && !json.success; j++)
                        {
                            if (json.result[j].plate != null && json.result[j].plate.Count > 0)
                            {
                                json.roi = json.result[j].roi;

                                for (int k = 0; k < json.result[j].plate.Count; k++)
                                {
                                    string result = json.result[j].plate[k];

                                    if (result.Length > 0)
                                    {
                                        double fuzzy = StringExtensions.FuzzyMatch(result, data[i]["車牌號碼"]);

                                        sw.WriteLine(string.Format("{0}. {1} fuzzy {2} = {3}", i, data[i]["車牌號碼"], result, fuzzy));

                                        sw.Flush();

                                        if (result == plate || plate.Contains(result))
                                        {
                                            // 辨識成功，比對正確
                                            json.message1 = data[i]["車牌號碼"];

                                            json.success = true;

                                            json.failed = false;

                                            json.tickoff = false;

                                            break;
                                        }
                                        else if (fuzzy > 0.1)
                                        {
                                            // 辨識成功，比對錯誤
                                            json.message1 = data[i]["車牌號碼"];

                                            json.success = true;

                                            json.failed = true;

                                            json.tickoff = false;

                                            break;

                                            //json.message2 = (json.message2 == null ? "資料異常" : json.message2) + "[" + result + "]";
                                        }
                                        else
                                        {
                                            json.success = false;
                                            json.failed = true;
                                            json.tickoff = true;
                                            json.lost1 = false;
                                            json.lost2 = false;
                                            json.message1 = data[i]["車牌號碼"];
                                            json.message2 = "車牌定位無結果";
                                        }
                                    }
                                    else { json.message2 = "車牌辨識無結果"; }
                                }
                            }
                            else { json.message2 = "車牌辨識無結果"; }
                        }
                    }
                    else {
                        json.success = false;
                        json.failed = true;
                        json.tickoff = true;
                        json.lost1 = false;
                        json.lost2 = false;
                        json.message1 = data[i]["車牌號碼"];
                        json.message2 = "車牌定位無結果";
                    }

                    int percent = Convert.ToInt32(Math.Round(Convert.ToDouble(i) * 10000 / data.Count) / 100);

                    elapsed += Elapsed(stopwatch.ElapsedMilliseconds, out string message1);

                    Elapsed(Convert.ToInt64(elapsed), out string message2);

                    ReportProgress(percent, json);

                    ReportProgress(percent, "車牌辨識，" + message1 + "，目前累積耗時" + message2);

                    stopwatch.Restart();

                    e.Result = i + 1;

                    Thread.Sleep(100);
                }

                foreach (string key in Images.Keys)
                {
                    if (!CancellationPending)
                    {
                        string filename = Images[key];

                        Json json = new Json() { filename = filename, message2 = "缺少比對資料", lost2 = true, tickoff = true, content = true };

                        ReportProgress(100, json);

                        Thread.Sleep(500);
                    }
                    else { break; }
                }
                sw.Close();
            }
            else  // 一維條碼模式
            {
                SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

                D1 setting = D1.Load();

                D1.Code39 code = new D1.Code39();

                string[] key = Images.Keys.ToArray();

                int start = Convert.ToInt32(e.Argument);

                double elapsed = 0;

                builder.DataSource = "192.168.6.233";

                builder.InitialCatalog = "nhpb";

                builder.UserID = "sa";

                builder.Password = "jack";

                using (SqlConnection db = new SqlConnection(builder.ConnectionString))
                {
                    db.Open();

                    for (int i = start; i < key.Length && !CancellationPending; i++)
                    {
                        Stopwatch stopwatch = Stopwatch.StartNew();

                        string filename = Images[key[i]];

                        Json json = new Json()
                        {
                            index = Convert.ToString(i).PadLeft(Convert.ToInt32(Math.Log10(Images.Count) + 1), '0'),
                            filename = filename,
                            success = true,
                            failed = false,
                            tickoff = false,
                            roi = new JsonPlateROI() { x = setting.ROI.X, y = setting.ROI.Y, w = setting.ROI.Width, h = setting.ROI.Height },
                        };

                        FileStream file = new FileStream(filename, FileMode.Open);

                        MemoryStream memory = new MemoryStream();

                        file.CopyTo(memory);

                        file.Close();

                        memory.Flush();

                        json.content = memory.Length > 0;

                        try
                        {
                            json.message1 = code.ProcessMethod1(setting.ROI, new Bitmap(memory));

                            json.message1 = json.message1.Replace("$", "");

                            json.message1 = json.message1.Replace("?", "");

                            json.message2 = json.message1.Length != 9 ? "掃描異常，已移入隔離資料夾" : json.message1;

                            json.success = json.message1.Length == 9;

                            json.failed = json.tickoff = json.message1.Length != 9;
                        }
                        catch (Exception ex)
                        {
                            json.message2 = ex.Message;

                            json.success = false;

                            json.failed = true;

                            json.tickoff = true;

                            json.content = false;
                        }

                        memory.Close();

                        SqlDataAdapter query = new SqlDataAdapter("SELECT * FROM ETC二次寄存主檔 WHERE tkt_no='" + json.message1 + "'", db);

                        DataTable table = new DataTable();

                        int percent = Convert.ToInt32(Math.Round(Convert.ToDouble(i) * 10000 / Images.Count) / 100);

                        query.Fill(table);

                        if (table.Rows.Count > 0 && !table.Rows[0].HasErrors)
                        {
                            json.message2 = json.message1 + "，" + table.Rows[0][0] + "，" + table.Rows[0][11];
                        }

                        elapsed += Elapsed(stopwatch.ElapsedMilliseconds, out string message1);

                        Elapsed(Convert.ToInt64(elapsed), out string message2);

                        ReportProgress(percent, json);

                        ReportProgress(percent, "條碼掃描，" + message1 + "，目前累積耗時" + message2);

                        stopwatch.Restart();

                        e.Result = i + 1;
                    }
                }

                
            }

            
        }
        public void SaveExcel()
        {
            List<Dictionary<string, string>> data = Data[SelectedKey];
            HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿
            workbook2003.CreateSheet("Sheet1");  //新建1個Sheet工作表            
            HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //獲取名稱為Sheet1的工作表
            for (int i = 1; i < 13; i++)    //列數
            {
                SheetOne.CreateRow(i);
                for (int j = 0; j < 20; j++)    //行數
                {
                    SheetOne.GetRow(i).CreateCell(j).SetCellValue(data[i]["帳單編號"]);
                }
            }
            FileStream file2003 = new FileStream("C:\\Users\\admin\\e-eye\\eee.xls", FileMode.Create);
            workbook2003.Write(file2003);
            file2003.Close();
            workbook2003.Close();
        }

    }
}
