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

using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using LFP_Manager.Controls;
using LFP_Manager.Utils;

namespace LFP_Manager.Forms
{
    public delegate void InvDataUpdateEvent(object sendor);
    public delegate void InvDateCmdEvent(int sId, int mode, int flag, ref DeviceInforation wData);
    
    public partial class fmxInventoryConfig : XtraForm
    {
        #region VARIABLES

        CommConfig Config;

        int SystemId = 0;
        int CmdResult = 0;
        DeviceSystemData SystemData;
        DeviceInforation wInvDate;

        public event InvDataUpdateEvent OnUpdate = null;
        public event InvDateCmdEvent OnCommand = null;

        #endregion
        public fmxInventoryConfig()
        {
            InitializeComponent();
        }
        public fmxInventoryConfig(CommConfig aConfig, int sId, ref DeviceSystemData aSystemData)
        {
            InitializeComponent();

            InitData();

            Config = aConfig;
            SystemId = sId;
            SystemData = aSystemData;

            tmrDisplay.Enabled = true;
            tmrCmd.Enabled = true;
        }

        void InitData()
        {
            wInvDate = new DeviceInforation
            {
                pcb_sn = new byte[16]
            };
        }

        #region DISPLAY DATA

        private void DisplayValue()
        {
            // Manufacture Date
            lbMDate.Text = String.Format("Manufacture Date: {0} ({0:X8})", SystemData.Information.ManufactureDate)
                + "\r\n"
                + DisplayManufactureDate(SystemData.Information.ManufactureDate)
                ;

            // Device Serial Number
            byte[] tmp = new byte[SystemData.Information.pcb_sn.Length + 1];
            for (int i = 0; i < SystemData.Information.pcb_sn.Length; i++)
                tmp[i] = SystemData.Information.pcb_sn[i];
            tmp[SystemData.Information.pcb_sn.Length] = 0;

            string strSerial = Encoding.Default.GetString(tmp).Trim('\0');
            lbSerialNo.Text = String.Format("Serial No: {0}", strSerial);
        }

        private string DisplayManufactureDate(UInt32 mDate)
        {
            DateTime dtDate = csUtils.ConvertTimeStampToDateTime(mDate);

            return String.Format("{0:yyyy-MM-dd hh:mm:ss}", dtDate);
        }

        #endregion

        #region TIMER ENVENT
        private void tmrDisplay_Tick(object sender, EventArgs e)
        {
            DisplayValue();
            OnUpdate?.Invoke(this);
        }

        #endregion

        #region PUBLIC FUCTIONS
        public void UpdateData(ref DeviceSystemData aSystemData)
        {
            SystemData = aSystemData;
        }

        #endregion

        #region BUTTON EVENT
        private void btnMDateRead_Click(object sender, EventArgs e)
        {
            OnCommand?.Invoke(SystemId, 900, 0, ref wInvDate);
            OnCommand?.Invoke(SystemId, 901, 0, ref wInvDate);
            OnCommand?.Invoke(SystemId, 902, 0, ref wInvDate);
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
        }
        private void btnInvWrite_Click(object sender, EventArgs e)
        {
            if (nSerialNo.Text.Length == 15)
            {
                csDbUtils.MdDbCreate(Config, nSerialNo.Text);

                if (CheckBmsSerialNo(nSerialNo.Text) == false)
                {
                    byte[] bSN = Encoding.UTF8.GetBytes(nSerialNo.Text);

                    if (wInvDate.pcb_sn == null) wInvDate.pcb_sn = new byte[16];
                    for (int i = 0; i < 16; i++) wInvDate.pcb_sn[i] = 0;
                    for (int i = 0; i < bSN.Length; i++)
                    {
                        wInvDate.pcb_sn[i] = bSN[i];
                    }
                    OnCommand?.Invoke(SystemId, 901, 1, ref wInvDate);
                    OnCommand?.Invoke(SystemId, 902, 1, ref wInvDate);

                    CmdMDateWrite();

                    CmdResult = 1;
                }
                else
                {
                    MessageBox.Show(String.Format("Already used BMS serial number - [{0}]", nSerialNo.Text)
                        , "Warning"
                        , MessageBoxButtons.OK
                        , MessageBoxIcon.Warning
                        );
                }
            }
        }
        #endregion

        #region PROCESSING DATA

        private bool CheckBmsSerialNo(string bSN)
        {
            bool result = false;
            DataTable dtBmsData = new DataTable();
            DataTable dtBmsMatch = new DataTable();
            DataTable dtErrorLog = new DataTable();

            //string sql = String.Format("SELECT * FROM TInventoryData WHERE pcb_sn = {0}", bSN);
            string sql = String.Format("SELECT * FROM TInventoryData");
            dtBmsData = csDbUtils.GetDataTableBySelect(Config, bSN, sql, "TInventoryData");

            if (dtBmsData != null)
            {
                if (dtBmsData.Rows.Count > 1)
                {
                    DataRow[] arrRows = null;
                    arrRows = dtBmsData.Select(String.Format("pcb_sn = '{0}'", bSN));
                    if (arrRows.Length > 0)
                        result = true;
                }
            }

            return result;
        }
        private void CmdMDateWrite()
        {
            UInt32 mTimeStamp = csUtils.CalcKKTimeStamp(DateTime.Now);
            wInvDate.ManufactureDate = mTimeStamp;

            OnCommand?.Invoke(SystemId, 900, 1, ref wInvDate);
        }

        private void CheckResult()
        {
            if (CmdResult == 1)
            {
                bool result = false;

                byte[] a = Encoding.UTF8.GetBytes(nSerialNo.Text);
                byte[] b = SystemData.Information.pcb_sn;

                for (int i = 0; i < a.Length; i++)
                {
                    if (a[i] == b[i]) continue;
                    result = true;
                }

                if ((result == false) && (wInvDate.ManufactureDate == SystemData.Information.ManufactureDate))
                {
                    CmdResult = 0;

                    try
                    {
                        csDbUtils.BmsDataInsert(Config, SystemData, nSerialNo.Text);

                        MessageBox.Show(String.Format("BMS data insert complete - [{0}]", nSerialNo.Text)
                            , "Information"
                            , MessageBoxButtons.OK
                            , MessageBoxIcon.Information
                            );
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format("BMS data insert fail - [{0}] \r\n{1}", nSerialNo.Text, ex.Message)
                            , "Warning"
                            , MessageBoxButtons.OK
                            , MessageBoxIcon.Warning
                            );
                    }
                }
            }
        }
        #endregion

        private void tmrCmd_Tick(object sender, EventArgs e)
        {
            OnCommand?.Invoke(SystemId, 900, 0, ref wInvDate);
            OnCommand?.Invoke(SystemId, 901, 0, ref wInvDate);
            OnCommand?.Invoke(SystemId, 902, 0, ref wInvDate);

            CheckResult();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}