using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Project.Dialog
{
    public partial class fImp : Form
    {
        DataTable dt;
        public fImp(DataTable dt_, string title, string[] collist)
        {
            InitializeComponent();
            this.dt = dt_;
            foreach (var col in collist)
            {
                var uc = new UserControl1();
                uc.label1.Text = col;
                uc.numericUpDown1.Value = 0;
                uc.Size = new Size(163, 29);
                uc.numericUpDown1.Tag = col;
                uc.numericUpDown1.ValueChanged += NumericUpDown1_ValueChanged;
                uc.numericUpDown1.BackColor = Color.LightGray;
                this.flowLayoutPanel1.Controls.Add(uc);
            }
            this.Text = "Excel Import(" + title + ")";
        }

        private void NumericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            //값에 따라서 색상을 달리한다.
            var ctl = sender as NumericUpDown;
            var col = ctl.Tag.ToString();
            if (ctl.Value == 0)
                ctl.BackColor = Color.LightGray;
            else
                ctl.BackColor = Color.Lime;
            UpdateColName();
        }

        void UpdateColName()
        {
            //reset name
            for (int i = 1; i <= this.listView1.Columns.Count; i++)
                listView1.Columns[i - 1].Text = "COL" + i.ToString();

            //remap name
            foreach (UserControl1 ctl in this.flowLayoutPanel1.Controls)
            {
                var colname = ctl.label1.Text;
                var colNo = (int)ctl.numericUpDown1.Value;
                if (colNo < 1) continue;
                listView1.Columns[colNo - 1].Text = colname;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var od = new OpenFileDialog();
            od.RestoreDirectory = true;
            if (od.ShowDialog() == DialogResult.OK)
            {
                this.textBox1.Text = od.FileName;
                btPreView.PerformClick();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var fn = this.textBox1.Text.Trim();
            var ext = System.IO.Path.GetExtension(fn);
            libxl.Book book;

            if (ext == "xls") book = new libxl.BinBook();
            else book = new libxl.XmlBook();

            //Amkor Technology/windows-242f240302c3e50d6cb1686ba2q4k0o9
            book.setKey("Amkor Technology", "windows-242f240302c3e50d6cb1686ba2q4k0o9");
            book.load(fn);
            var sheet = book.getSheet((int)numericUpDown3.Value);
            var cols = sheet.lastCol();
            var rows = sheet.lastRow();
            if (numericUpDown1.Value < 1) numericUpDown1.Value = 0;

            if(numericUpDown2.Value > rows)   this.numericUpDown2.Value = rows;
            else if(numericUpDown2.Value < 1) this.numericUpDown2.Value = rows;

            var sn = (int)numericUpDown1.Value;
            var en = (int)numericUpDown2.Value;

            if (sn < 1)
            {
                MessageBox.Show("Start row number must be greater than 0");
                return;
            }
            if (en < sn)
            {
                MessageBox.Show("End row number must be greater than start number");
                return;
            }

            this.listView1.Columns.Clear();
            for (int i = 1; i <= cols; i++)
            {
                this.listView1.Columns.Add("col" + i.ToString());
            }

            var previewcnt = 20;
            this.listView1.Items.Clear();
            var maxrow = Math.Min(previewcnt, en);
            for (int i = sn; i <= maxrow; i++)
            {
                var data0 = sheet.readStr(i - 1, 0);
                var lv = this.listView1.Items.Add(data0);
                for (int j = 1; j < cols; j++)
                {
                    var data1 = sheet.readStr(i - 1, j);
                    lv.SubItems.Add(data1.ToString());
                }
            }
            this.listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
            lbMsg.Text = $"Preview displays up to {previewcnt} items";
        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void fImp_Load(object sender, EventArgs e)
        {

        }

        void AddData(DataSet1.Component_Reel_SIDConvDataTable dt2, string v_101, string v_103, string v_106, string v_108, string v_103_2, ref int cntI, ref int cntE)
        {
            var newdr = dt2.NewComponent_Reel_SIDConvRow();
            if (string.IsNullOrEmpty(v_101) == false) newdr.M101 = v_101;
            if (string.IsNullOrEmpty(v_103) == false) newdr.M103 = v_103;
            if (string.IsNullOrEmpty(v_106) == false) newdr.M106 = v_106;
            if (string.IsNullOrEmpty(v_108) == false) newdr.M108 = v_108;
            if (string.IsNullOrEmpty(v_103_2) == false) newdr.M103_2 = v_103_2;
            dt2.AddComponent_Reel_SIDConvRow(newdr);
            cntI += 1;
        }

        void UpdateData(DataSet1.Component_Reel_SIDConvDataTable dt2,
            List<DataSet1.Component_Reel_SIDConvRow> list,
            string mainValue, string column,
            string v_101, string v_103, string v_106, string v_108, string v_103_2, ref int cntI, ref int cntE)
        {
            //데이터를 업데이트해준다.
            foreach (var item in list)
            {
                //103값이 있는경우 처리해야한다
                if (string.IsNullOrEmpty(mainValue) == false)
                {
                    //값이 비어있다면 기록하고 없다면 추가한다.
                    if (item[column] == null || string.IsNullOrEmpty(item[column].ToString()))
                    {
                        item[column] = mainValue;
                        item.EndEdit();
                        cntE += 1;
                    }
                    else if (item[column].ToString() != mainValue)
                        AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);
                }
            }
        }

        private void tbUpdate_Click(object sender, EventArgs e)
        {
            //자료등록메세지
            var dlg = MessageBox.Show(string.Format("Do you want to register {0} records?", this.numericUpDown2.Value), "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dlg == DialogResult.Yes)
            {
                //먼저 컬럼 목록을 가져온다
                Dictionary<string, int> collist = new Dictionary<string, int>();
                foreach (UserControl1 uc in this.flowLayoutPanel1.Controls)
                {
                    var col = uc.label1.Text;
                    var no = (int)uc.numericUpDown1.Value;
                    if (no == 0) continue;
                    if (collist.Where(t => t.Value == no).Any())
                    {
                        MessageBox.Show(string.Format("Column {0} is already assigned", no));
                        return;
                    }
                    collist.Add(col, no);
                }

                if (collist.Count < 1)
                {
                    MessageBox.Show("No columns have been assigned");
                    return;
                }


                var fn = this.textBox1.Text.Trim();
                var ext = System.IO.Path.GetExtension(fn);
                libxl.Book book;
                if (ext == "xls") book = new libxl.BinBook();
                else book = new libxl.XmlBook();

                //Amkor Technology/windows-242f240302c3e50d6cb1686ba2q4k0o9
                book.setKey("Amkor Technology", "windows-242f240302c3e50d6cb1686ba2q4k0o9");
                book.load(fn);
                var sheet = book.getSheet((int)numericUpDown3.Value);

                var sn = (int)numericUpDown1.Value;
                var en = (int)numericUpDown2.Value;
                this.prb1.Value = 0;
                this.prb1.Maximum = en;
                var cntI = 0;
                var cntSkip = 0;
                var cntD = 0;
                var cntE = 0;
                for (int i = sn; i <= en; i++)
                {
                    this.prb1.Value = i;
                    this.lbMsg.Text = string.Format("{0}/{1} Added:{2},SKIP:{3},Duplicate:{4}", i, en, cntI, cntSkip, cntD);
                    if (i % 10 == 0) Application.DoEvents();

                    Dictionary<string, string> datalist = new Dictionary<string, string>();
                    foreach (var coldata in collist)
                    {
                        var colname = coldata.Key;
                        var colno = coldata.Value;

                        var data0 = sheet.readStr(i - 1, colno - 1);
                        datalist.Add(colname, data0);
                    }

                    //데이터를 다 기록했다 이중 기준값인 SID
                    if (dt is DataSet1.Component_Reel_SIDInfoDataTable)
                    {
                        //sid 열의 값을 취한다.
                        if (datalist.Where(t => t.Key == "SID").Any() == false) continue;
                        var sid = datalist.Where(t => t.Key == "SID").First().Value;

                        var custcode = datalist.Where(t => t.Key == "CustCode").First().Value;
                        if (custcode == null) custcode = string.Empty;
                        else  custcode = custcode.PadLeft(4, '0');

                        var partno = datalist.Where(t => t.Key == "PartNo").First().Value;
                        if (partno == null) partno = string.Empty;


                        partno = partno.Trim();
                        custcode = custcode.Trim();
                        sid = sid.Trim();

                        var tata = new DataSet1TableAdapters.Component_Reel_SIDInfoTableAdapter();

                        //이 sid 값이 있는지 체크한다.
                        var cnt = tata.CheckData(sid, custcode, partno);
                        //var dt2 = dt as DataSet1.Component_Reel_SIDInfoDataTable;
                        //var sidlist = dt2.Where(t => t.SID == sid && t.PartNo == partno && t.CustCode == custcode);
                        if(cnt == 0)
                        {
                            //없다면 추가해준다.
                            //var newdr = dt2.NewComponent_Reel_SIDInfoRow();
                            //newdr.SID = sid;
                            //newdr.PartNo = partno;
                            //newdr.CustCode = custcode;
                            //newdr.Remark = "신규추가" + DateTime.Now.ToShortTimeString();
                            //dt2.AddComponent_Reel_SIDInfoRow(newdr);
                            cntI += 1;

                            tata.Insert(sid, custcode, string.Empty, string.Empty, partno, string.Empty, DateTime.Now.ToString());
                            //Boolean bInsert = false;
                            //foreach (var item in datalist)
                            //{
                            //    if (string.IsNullOrEmpty(item.Value) == false)
                            //    {
                            //        if (item.Key.ToLower() == "custcode")
                            //        {
                            //            var itemvalue = item.Value.ToString();
                            //            itemvalue = itemvalue.PadLeft(4, '0');
                            //            newdr[item.Key] = itemvalue;
                            //        }
                            //        else
                            //        {
                            //            newdr[item.Key] = item.Value;
                            //        }
                            //        if (item.Key.ToUpper() != "SID") bInsert = true;
                            //    }

                            //}
                            //if (bInsert)
                            //{
                            //    newdr.Remark = "신규추가" + DateTime.Now.ToShortTimeString();
                            //    dt2.AddComponent_Reel_SIDInfoRow(newdr);
                            //    cntI += 1;
                            //}
                            //else newdr.Delete();
                        }
                        else
                        {
                            //여러개가 잇다면 모두 처리해준다.
                            //foreach (var dr in sidlist)
                            //{
                            //    Boolean update = false;
                            //    foreach (var item in datalist)
                            //    {
                            //        var itemvalue = item.Value.Trim();
                            //        if (string.IsNullOrEmpty(itemvalue)) continue;
                            //        if (item.Key.ToLower() == "custcode")
                            //        {
                            //            itemvalue = itemvalue.PadLeft(4, '0');
                            //        }
                            //        var curValue = dr[item.Key];
                            //        if (curValue == null)
                            //        {
                            //            dr[item.Key] = item.Value;
                            //            update = true;
                            //        }
                            //        else if (curValue.ToString() != itemvalue)
                            //        {
                            //            dr["remark"] = string.Format("[{2}] {0}->{1}", curValue, itemvalue, item.Key);
                            //            dr[item.Key] = itemvalue;
                            //            update = true;
                            //        }
                            //    }
                            //    if (update) cntSkip += 1;
                            //}
                        }

                    }
                    else if (dt is DataSet1.Component_Reel_SIDConvDataTable)
                    {
                        var dt2 = dt as DataSet1.Component_Reel_SIDConvDataTable;

                        var v_101 = string.Empty;
                        var v_103 = string.Empty;
                        var v_103_2 = string.Empty;
                        var v_106 = string.Empty;
                        var v_108 = string.Empty;

                        var d_101 = datalist.Where(t => t.Key == "M101").FirstOrDefault();
                        var d_103 = datalist.Where(t => t.Key == "M103").FirstOrDefault();
                        var d_106 = datalist.Where(t => t.Key == "M106").FirstOrDefault();
                        var d_108 = datalist.Where(t => t.Key == "M108").FirstOrDefault();
                        var d_103_2 = datalist.Where(t => t.Key == "M103_2").FirstOrDefault();

                        if (d_101.Key != null) v_101 = d_101.Value.Trim();
                        if (d_103.Key != null) v_103 = d_103.Value.Trim();
                        if (d_106.Key != null) v_106 = d_106.Value.Trim();
                        if (d_108.Key != null) v_108 = d_108.Value.Trim();
                        if (d_103_2.Key != null) v_103_2 = d_103_2.Value.Trim();


                        //101값이 있다면?
                        if (string.IsNullOrEmpty(v_101) == false)
                        {
                            var list = dt2.Where(t => t.M101 == v_101).ToList();
                            if (list.Any() == false) AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //값이 없으니 추가 해야 한다
                            else
                            {
                                UpdateData(dt2, list, v_103, "M103", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_106, "M106", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_108, "M108", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103_2, "M103_2", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                            }
                        }

                        //103값이 있다면?
                        if (string.IsNullOrEmpty(v_103) == false)
                        {
                            var list = dt2.Where(t => t.M103 == v_103).ToList();
                            if (list.Any() == false) AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //값이 없으니 추가 해야 한다
                            else
                            {
                                UpdateData(dt2, list, v_101, "M101", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_106, "M106", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_108, "M108", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103_2, "M103_2", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                            }
                        }
                        //106값이 있다면?
                        if (string.IsNullOrEmpty(v_106) == false)
                        {
                            var list = dt2.Where(t => t.M106 == v_106).ToList();
                            if (list.Any() == false) AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //값이 없으니 추가 해야 한다
                            else
                            {
                                UpdateData(dt2, list, v_101, "M101", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103, "M103", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_108, "M108", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103_2, "M103_2", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                            }
                        }
                        //108값이 있다면?
                        if (string.IsNullOrEmpty(v_108) == false)
                        {
                            var list = dt2.Where(t => t.M108 == v_108).ToList();
                            if (list.Any() == false) AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //값이 없으니 추가 해야 한다
                            else
                            {
                                UpdateData(dt2, list, v_101, "M101", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103, "M103", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_106, "M106", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103_2, "M103_2", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                            }
                        }
                        //103_2값이 있다면?
                        if (string.IsNullOrEmpty(v_103_2) == false)
                        {
                            var list = dt2.Where(t => t.M103_2 == v_103_2).ToList();
                            if (list.Any() == false) AddData(dt2, v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //값이 없으니 추가 해야 한다
                            else
                            {
                                UpdateData(dt2, list, v_101, "M101", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_103, "M103", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_106, "M106", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                                UpdateData(dt2, list, v_108, "M108", v_101, v_103, v_106, v_108, v_103_2, ref cntI, ref cntE);    //데이터를 업데이트해준다.
                            }
                        }
                    }

                }
                this.listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
                lbMsg.Text = string.Format("The following amounts of data have been changed\n" +
                    "Added:{0},Duplicate:{1},SKIP:{2}\n" +
                    "Click 'Save' on the main screen to apply changes", cntI, cntD, cntSkip);
                MessageBox.Show(lbMsg.Text);
                if (cntI > 0 || cntD > 0) DialogResult = DialogResult.OK;
            }
        }
    }
}
