using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using SystemX.Product.TRA.DataManager;
using DevExpress.Utils;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraPrinting;
using SystemX.Product.ALIS.Interface;

using static SystemX.Product.CP.TRA.MainForm;
using static SystemX.Product.CP.TRA.Commons;

namespace SystemX.Product.TRA.UIControl
{
    public partial class UcTRATestHistHost : UcTRABaseView
    {
        public enum eColHide
        {
            TestListFileNo,
            TestListVariantNo,
            LogNo,
            LogCount,
            AccessStart,
            AccessEnd,
            TestListFileName
        }

        DMTestHistory DataManager { get; set; }
        TestHistorySearchOption Option { get; set; }
        SelectedDataCollection SelectedData { get; set; }

        private bool bSelectedTime_DaySearched = false;

        public DataTable DataResult { get; private set; }

        public delegate void evtDataDetailViewHandler(DetailTestDataCollection data);
        public event evtDataDetailViewHandler OnDetailSelect;

        private IChildController refChildInterface;

        int nCurrentRowSelected = int.MaxValue;

        private bool bSearchVisibleOption = false;

        private string GridViewGetActiveFilterText;

        public UcTRATestHistHost(IChildController getChildControl, bool bSearchOptionVisible = false, bool bSelectTime_Day = false)
        {
            ContentsType = eContents.TestHistory;

            refChildInterface = getChildControl;

            this.ContextMenuStrip = base.contextMenuStripTest;

            this.ContextMenuStrip.ItemClicked += contextMenuStrip_ItemClicked;

            SetMenuEnabled(ContentsType);

            bSelectedTime_DaySearched = bSelectTime_Day;

            InitializeComponent();

            gridViewMain.RowClick += gridViewMain_Click;

            bSearchVisibleOption = bSearchOptionVisible;
        }

        ~UcTRATestHistHost()
        {
            this.ContextMenuStrip.ItemClicked -= contextMenuStrip_ItemClicked;
        }

        private void contextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripItem tsp = e.ClickedItem;

            int nTag = Convert.ToInt32(tsp.Tag);

            switch (nTag)
            {
                case 0:
                    refChildInterface.SetOverview();
                    break;
                case 1:
                    break;
                case 2:
                    refChildInterface.SetSummaryView();
                    break;
                case 3:
                    SetDetailDataView();
                    break;
                case 4:
                    break;
                case 8:
                    refChildInterface.SetDetailOverview();
                    break;
            }
        }

        public void SetSQLConnection(eSelectDataView SelectView, IDataBaseController getDBController)
        {
            DataManager = new DMTestHistory(SelectView, getDBController);
        }

        public void ViewData(SelectedDataCollection data)
        {
            if (data == null)
                return;

            SelectedData = data;

            DataTable dtResult = null;
            DataTable dtMergeResult = new DataTable();

            if (SelectedData.GetCountRequestID() > 1)
            {
                int nCnt = SelectedData.GetCountRequestID();
                for (int i = 0; i < nCnt; i++)
                {
                    dtResult = DataManager.SearchTestHistory(data, Option, i);

                    dtMergeResult.Merge(dtResult);
                }
            }
            else
            {
                dtResult = DataManager.SearchTestHistory(data, Option);

                dtMergeResult.Merge(dtResult);
            }

            DataColumn dcVal = dtMergeResult.Columns.Add("No.", typeof(int));

            DisplayResultTable(dtMergeResult);
            DisplayResultSummary(dtMergeResult);
        }

        void DisplayResultSummary(DataTable dtResult)
        {
            int nOKTestCount = (from drData in dtResult.AsEnumerable()
                                where drData[DMTestHistory.eColList.TestResult.ToString()].ToString() == "OK"
                                select drData).Count();
            int nNGTestCount = (from drData in dtResult.AsEnumerable()
                                where drData[DMTestHistory.eColList.TestResult.ToString()].ToString() == "NG"
                                select drData).Count();
            List<int> vnTestTime = (from drData in dtResult.AsEnumerable()
                                            where drData[DMTestHistory.eColList.TestResult.ToString()].ToString() == "OK"
                                                || drData[DMTestHistory.eColList.TestResult.ToString()].ToString() == "NG"
                                            let nTime = Convert.ToInt32(drData[DMTestHistory.eColList.Duration.ToString()].ToString())
                                            select nTime).ToList();

            double dRatio = (((double)(nOKTestCount * 100)) / (nOKTestCount + nNGTestCount));
            labelControlTestResult.Text = $"{nOKTestCount + nNGTestCount} (OK: {nOKTestCount}/NG: {nNGTestCount}) - Ratio: {dRatio.ToString(".##")}%";

            

            labelControlTestTime.Text = vnTestTime.Count > 0 ? 
                $"Average = {(vnTestTime.Average()/1000).ToString(".##")}s, Min = {(((double)vnTestTime.Min()) / 1000).ToString(".##")}s, Max = {(((double)vnTestTime.Max()) / 1000).ToString(".##")}s" :
                $"Average = -, Min = -, Max = -";
        }

        void DisplayResultTable(DataTable dtResult)
        {
            DataResult = dtResult;

            GridViewGetActiveFilterText = gridViewMain.ActiveFilterString;

            gridControlMain.BeginInit();

            gridControlMain.DataSource = dtResult;

            gridControlMain.Update();
            gridControlMain.RefreshDataSource();
            gridControlMain.ForceInitialize();
            gridViewMain.PopulateColumns(dtResult);

            foreach (string strColName in Enum.GetNames(typeof(eColHide)))
                gridViewMain.Columns[strColName].Visible = false;

            gridControlMain.EndInit();
            gridViewMain.BeginUpdate();

            int nRowNoIdx = 0;

            for (int i = 0; i < gridViewMain.RowCount; i++)
            {
                DataRowView drvRow = gridViewMain.GetRow(i) as DataRowView;
                string strResult = drvRow[DMTestHistory.eColList.TestResult.ToString()].ToString();

                if (strResult == "NG" || strResult == "OK" || strResult == "STOP")
                {
                    nRowNoIdx++;

                    drvRow["No."] = nRowNoIdx;
                }
                else
                    drvRow["No."] = -1;
            }

            gridViewMain.Columns["No."].VisibleIndex = 0;
            gridViewMain.OptionsView.AllowCellMerge = true;
            gridViewMain.Columns[DMTestHistory.eColList.TestlistReqID.ToString()].OptionsColumn.AllowMerge = DefaultBoolean.True;

            gridViewMain.BestFitColumns();
            gridViewMain.EndUpdate();

            gridViewMain.ActiveFilterString = GridViewGetActiveFilterText;
              
        }

        public DetailTestDataCollection GetSearchInfo(DataRow dtRow)
        {
            DetailTestDataCollection drDetail = new DetailTestDataCollection();

            //drDetail.TestID = dtRow[DMTestHistory.eColList.TestID.ToString()].ToString();
            drDetail.StartTime = DateTime.Parse(dtRow[DMTestHistory.eColList.TestDateTime.ToString()].ToString());

            string strGetLogNo = dtRow[DMTestHistory.eColList.LogNo.ToString()].ToString();
            if (strGetLogNo.Length > 0)
                drDetail.LogNo = Convert.ToUInt64(dtRow[DMTestHistory.eColList.LogNo.ToString()]);
            else
                drDetail.LogNo = ulong.MinValue;

            drDetail.LogCount = Convert.ToInt32(dtRow[DMTestHistory.eColList.LogCount.ToString()]);
            drDetail.AccessStart = Convert.ToUInt64(dtRow[DMTestHistory.eColList.AccessStart.ToString()]);
            drDetail.AccessEnd = Convert.ToUInt64(dtRow[DMTestHistory.eColList.AccessEnd.ToString()]);
            drDetail.Duration =  Convert.ToInt64(dtRow[DMTestHistory.eColList.Duration.ToString()]);
            drDetail.StationName = dtRow[DMTestHistory.eColList.StationName.ToString()].ToString();
            drDetail.HostID = dtRow[DMTestHistory.eColList.Host.ToString()].ToString();
            drDetail.SectionID = dtRow[DMTestHistory.eColList.Section.ToString()].ToString();
            drDetail.TestType = dtRow[DMTestHistory.eColList.TestType.ToString()].ToString();
            drDetail.ProductID = dtRow[DMTestHistory.eColList.ProductID.ToString()].ToString();
            drDetail.ProductNo = dtRow[DMTestHistory.eColList.ProductNo.ToString()].ToString();
            drDetail.TestCode = dtRow[DMTestHistory.eColList.TestCode.ToString()].ToString();
            drDetail.ParentNo = dtRow[DMTestHistory.eColList.ParentNo.ToString()].ToString();
            drDetail.FileCode = dtRow[DMTestHistory.eColList.FileCode.ToString()].ToString();
            drDetail.FileVersion = dtRow[DMTestHistory.eColList.FileVersion.ToString()].ToString();
            drDetail.TestlistFileName = dtRow[DMTestHistory.eColList.TestlistFileName.ToString()].ToString();
            drDetail.TestListFileNo = dtRow[DMTestHistory.eColList.TestListFileNo.ToString()].ToString();
            drDetail.TestListVariantNo = dtRow[DMTestHistory.eColList.TestListVariantNo.ToString()].ToString();
            drDetail.StepVersion = dtRow[DMTestHistory.eColList.StepVersion.ToString()].ToString();
            drDetail.TestRequestID = dtRow[DMTestHistory.eColList.TestlistReqID.ToString()].ToString();
            drDetail.TestResult = dtRow[DMTestHistory.eColList.TestResult.ToString()].ToString();

            return drDetail;
        }

        private void UcTRATestHistHost_Load(object sender, EventArgs e)
        {
            Option = new TestHistorySearchOption();

            FrmOptionStationSearch dlgSearch = new FrmOptionStationSearch(bSearchVisibleOption, bSelectedTime_DaySearched);

            if (bSearchVisibleOption)
            {
                dlgSearch.ShowDialog();

                if (dlgSearch.DialogResult == DialogResult.OK)
                    Option = dlgSearch.GetSelectedResult();
            }
            else
                Option = dlgSearch.GetSelectedResult();
        }

        private void SetDetailDataView()
        {
            if(nCurrentRowSelected != int.MaxValue)
            {
                var dvRow = gridViewMain.GetRow(nCurrentRowSelected);
                DataRow dtRow = (dvRow as DataRowView).Row;
                DetailTestDataCollection drDetail = GetSearchInfo(dtRow);

                OnDetailSelect(drDetail);
            }
        }
        private void gridViewMain_Click(object sender, EventArgs e)
        {
            DXMouseEventArgs ea = e as DXMouseEventArgs;
            GridView view = sender as GridView;

            GridHitInfo info = view.CalcHitInfo(ea.Location);

            if (info.InRow || info.InRowCell)
                nCurrentRowSelected = info.RowHandle;
            else
                nCurrentRowSelected = int.MaxValue;
        }

        private void gridViewMain_DoubleClick(object sender, EventArgs e)
        {
            DXMouseEventArgs ea = e as DXMouseEventArgs;
            GridView view = sender as GridView;
            GridHitInfo info = view.CalcHitInfo(ea.Location);

            if (info.InRow || info.InRowCell)
            {
                int nRow = int.MinValue;
                nRow = info.RowHandle;

                if (nRow < 0)
                    return;

                var dvRow = view.GetRow(nRow);
                DataRow dtRow = (dvRow as DataRowView).Row;
                DetailTestDataCollection drDetail = GetSearchInfo(dtRow);

                OnDetailSelect(drDetail);
            }
        }

        public List<DetailTestDataCollection> GetResultContents()
        {
            List<DetailTestDataCollection> vDetailData = new List<DetailTestDataCollection>();
            GridView view = gridViewMain as GridView;

            for(int i=0; i<view.RowCount; i++)
            {
                DataRow dtRow = (view.GetRow(i) as DataRowView).Row;
                DetailTestDataCollection dtContent = GetSearchInfo(dtRow);

                vDetailData.Add(dtContent);
            }

            return vDetailData;
        }
        
        public string CreateExportFileName()
        {
            string strFileName = $"{this.ContentsType.ToString()}_{SelectedData.ProductNo}_{SelectedData.TestCode}_{SelectedData.StationName}";

            strFileName += $"_{SelectedData.StartTime.ToString("yyyyMMddHHmmss")}-{SelectedData.EndTime.ToString("yyyyMMddHHmmss")}";

            return strFileName;
        }

        public override void ExportData()
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();

            if (dlg.ShowDialog() == DialogResult.OK)
            {

                string strFileName = CreateExportFileName();
                string strExpPath = dlg.SelectedPath + "\\" + strFileName;
                XlsxExportOptionsEx option = new XlsxExportOptionsEx();
                string strFile = strExpPath + ".xlsx";

                option.ShowGridLines = true;
                option.ExportType = DevExpress.Export.ExportType.WYSIWYG;
                option.ExportMode = XlsxExportMode.SingleFile;
                option.SheetName = "Test History";
                gridControlMain.ExportToXlsx(strFile, option);
                
            }
        }

        private void gridViewMain_CellMerge(object sender, CellMergeEventArgs e)
        {
            if (e.Column.FieldName == DMTestHistory.eColList.TestlistReqID.ToString())
            {
                GridView view = sender as GridView;
                string val1 = view.GetRowCellValue(e.RowHandle1, e.Column).ToString();
                string val2 = view.GetRowCellValue(e.RowHandle2, e.Column).ToString();
                e.Merge = val1 == val2;
                e.Handled = true;
            }
            else
            {
                e.Merge = false;
                e.Handled = true;
            }                    
        }

        private void gridViewMain_RowStyle(object sender, RowStyleEventArgs e)
        {
            GridView view = sender as GridView;
            if (view.FocusedRowHandle == e.RowHandle)
            {
                GridViewInfo viewInfo = gridViewMain.GetViewInfo() as GridViewInfo;
                e.Appearance.Assign(viewInfo.PaintAppearance.FocusedRow);
                e.HighPriority = true;
            }
        }
    }
}
