using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Product.ALIS.Interface;
using SystemX.Product.TRA.UIControl;

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

namespace SystemX.Product.TRA.DataManager
{
    public class DMOverview
    {
        public enum eCommand
        {
            PowerON,
            PowerOFF,
            QUERY
        }

        public enum eColList
        {
            TestDate,
            StationName,
            Host,
            Section,
            ProductID,
            Start,
            Final,
            ProductNo,
            TestType,
            ParentNo,
            TestListFileNo,
            TestListVariantNo,
            TestCode,
            FileVersion,
            FileCode,
            StepVersion,
            FirstTestTime,
            FinalTestTime,
            Total,
            OK,
            NG, //NOK,
            TestListCntID
        }

        public enum eColListHide
        {
            TestListCntID,
            RN
        }

        private SqlConnection DBConn { get; set; }

        private SqlConnection ShortTermDBConn { get; set; }

        private SqlConnection LongTermDBConn { get; set; }

        private SqlCommand SQLCmd { get; set; }

        public void SetSqlCommandCancel()
        {
            CTS.Cancel();
        }

        public bool GetSqlCommandCancelState()
        {
            return CTS.IsCancellationRequested;
        }


        public string strOverviewUseQuery;

        eOverviewModelNameInfo GetSelectInfo;

        CancellationTokenSource CTS;

        CancellationToken CT;

        public DMOverview(eSelectDataView SelectView, eOverviewModelNameInfo SelectInfo, IDataBaseController getDBController)
        {
            GetSelectInfo = SelectInfo;

            DBConn = getDBController.GetMainConn();

            if (SelectView == eSelectDataView.DataDocumentViewC1)
            {
                ShortTermDBConn = getDBController.GetShortTermConn1();

                LongTermDBConn = getDBController.GetLongTermConn1();
            }
            else if (SelectView == eSelectDataView.DataDocumentViewC2)
            {
                ShortTermDBConn = getDBController.GetShortTermConn2();

                LongTermDBConn = getDBController.GetLongTermConn2();
            }

            strOverviewUseQuery = string.Empty;

            CTS = new CancellationTokenSource();
            CT = CTS.Token;
        }

        public async Task<DataTable> GetDataView(DateTime dtStart, DateTime dtEnd, OverviewSearchOption inputOption, bool bUseMainConn = false, string strTestQuery = "")
        {
            DataTable dtResult = new DataTable();

            string strGetUseQuery = string.Empty;

            CTS = new CancellationTokenSource();
            CT = CTS.Token;

            //For Test
            /*
            try
            {
                await Task.Delay(5000, CT);
            }
            catch
            {
            }
            */

            Tuple<DataTable, string> dtRawInfo = await GetRawResult(dtStart, dtEnd, inputOption, bUseMainConn, strTestQuery);

            strOverviewUseQuery = dtRawInfo.Item2;

            return dtRawInfo.Item1;
        }

        private async Task<Tuple<DataTable, string>> GetRawResult(DateTime dtStart, DateTime dtEnd, OverviewSearchOption inputOption, bool bUseMainConn = false, string strTestQuery = "")
        {
            DataTable dtResult = new DataTable();

            bool bFullScanOn = false;

            string strQuery = string.Empty;
            //string strSubQuery = string.Empty;

            DateTime dtNow = DateTime.Now;

            int nDiffMonth = 12 * (dtNow.Year - dtStart.Year) + (dtNow.Month - dtStart.Month);
            bool bScanLongTermUse = nDiffMonth > 3 ? true : false;

            string strGetSendQuery = string.Empty;

            /*
            strSubQuery = $"SELECT Y.No, Y.GroupName, Y.ModelName, Y.Comment FROM [CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) " +
                        $"LEFT JOIN[CPXV2].[dbo].[PROD_Group] AS Y WITH(NOLOCK) ON Y.No = X.GroupNo " +
                        $"WHERE X.No = ; ";

            using (SqlCommand cmd = new SqlCommand(, DBConn))
            {

            }
            */

            strQuery += $"SELECT * FROM (";
            strQuery += $"SELECT ";
            strQuery += $"CAST({DMCommon.SummaryLogTable}.[TestDT] AS DATE) AS {eColList.TestDate.ToString()},";

            if (inputOption.DisplayByStation)
            {
                strQuery += $"{DMCommon.SummaryLogTable}.[StationName] AS {eColList.StationName.ToString()},";
                strQuery += $"{DMCommon.SummaryLogTable}.[HostID] AS {eColList.Host.ToString()},";
                strQuery += $"{DMCommon.SummaryLogTable}.[Section] AS {eColList.Section.ToString()},";
            }
            //
            strQuery += $"Y.ModelName,";

            strQuery += $"{DMCommon.SummaryLogTable}.[TestType] AS {eColList.TestType.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[ProdNo_C] AS {eColList.ProductNo.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[Testcode] AS {eColList.TestCode.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[ProdNo_P] AS {eColList.ParentNo.ToString()},";

            if (inputOption.ProductID.Length > 0)
                strQuery += $"{DMCommon.SummaryLogTable}.[ProductID] as {eColList.ProductID.ToString()},";

            strQuery += $"{DMCommon.SummaryLogTable}.[TestListFileNo] AS {eColList.TestListFileNo.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[TestListVariantNo] AS {eColList.TestListVariantNo.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[ProdCode] AS {eColList.FileCode.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[Version] AS {eColList.FileVersion.ToString()},";
            strQuery += $"{DMCommon.SummaryLogTable}.[StepVersion] AS {eColList.StepVersion.ToString()},";
            strQuery += $"CONVERT(CHAR(8), MIN({DMCommon.SummaryLogTable}.[TestDT]), 108) AS {eColList.FirstTestTime.ToString()},";
            strQuery += $"CONVERT(CHAR(8), MAX({DMCommon.SummaryLogTable}.[TestDT]), 108) AS {eColList.FinalTestTime.ToString()},";
            strQuery += $"COUNT({DMCommon.SummaryLogTable}.[Result]) AS {eColList.Total.ToString()},";
            strQuery += $"COUNT(CASE WHEN {DMCommon.SummaryLogTable}.[Result] = 'OK' THEN 1 END) AS {eColList.OK.ToString()},";
            strQuery += $"COUNT(CASE WHEN {DMCommon.SummaryLogTable}.[Result] != 'OK' THEN 1 END) AS {eColList.NG.ToString()},";

            if (inputOption.DisplayByStation)
            {
                strQuery += $"ROW_NUMBER() OVER(PARTITION BY {DMCommon.SummaryLogTable}.[HostID], {DMCommon.SummaryLogTable}.[Section] ORDER BY CONVERT(CHAR(23), MAX({DMCommon.SummaryLogTable}.[TestDT]), 121) DESC) AS RN,";

                strQuery += $"{DMCommon.SummaryLogTable}.[TestListCntID]";
            }
            else
            {
                //strQuery += $"ROW_NUMBER() OVER(PARTITION BY {DMCommon.SummaryLogTable}.[ProdNo_C], {DMCommon.SummaryLogTable}.[ProdNo_P] ORDER BY CONVERT(CHAR(23), MAX({DMCommon.SummaryLogTable}.[TestDT]), 121) DESC) AS RN,";
                strQuery += $"ROW_NUMBER() OVER(PARTITION BY {DMCommon.SummaryLogTable}.[ProdNo_C], {DMCommon.SummaryLogTable}.[Testcode] ORDER BY CONVERT(CHAR(23), MAX({DMCommon.SummaryLogTable}.[TestDT]), 121) DESC) AS RN,";
                //strQuery += $"ROW_NUMBER() OVER(PARTITION BY {DMCommon.SummaryLogTable}.[ProdNo_C] ORDER BY CONVERT(CHAR(23), MAX({DMCommon.SummaryLogTable}.[TestDT]), 121) DESC) AS RN,";

                strQuery = strQuery.Remove(strQuery.Length - 1, 1);
            }

            strQuery += " ";

            strQuery += $"FROM {DMCommon.SummaryLogTable} ";
            strQuery += $"WITH(NOLOCK) ";

            //strQuery += $"LEFT JOIN [CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) ON X.No = CONVERT(NVARCHAR, {DMCommon.SummaryLogTable}.[TestListVariantNo]) ";
            
            switch(GetSelectInfo)
            {
                case eOverviewModelNameInfo.L:
                    strQuery += $"LEFT JOIN [CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) ON X.No = {DMCommon.SummaryLogTable}.[TestListVariantNo] ";
                    strQuery += $"LEFT JOIN [CPXV2].[dbo].[PROD_Group] AS Y WITH(NOLOCK) ON Y.No = X.GroupNo ";
                    break;
                case eOverviewModelNameInfo.P1:
                    strQuery += $"LEFT JOIN [P1].[CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) ON X.No = {DMCommon.SummaryLogTable}.[TestListVariantNo] ";
                    strQuery += $"LEFT JOIN [P1].[CPXV2].[dbo].[PROD_Group] AS Y WITH(NOLOCK) ON Y.No = X.GroupNo ";
                    break;
                case eOverviewModelNameInfo.P2:
                    strQuery += $"LEFT JOIN [P2].[CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) ON X.No = {DMCommon.SummaryLogTable}.[TestListVariantNo] ";
                    strQuery += $"LEFT JOIN [P2].[CPXV2].[dbo].[PROD_Group] AS Y WITH(NOLOCK) ON Y.No = X.GroupNo ";
                    break;
            }
            /*
            strQuery += $"LEFT JOIN [CPXV2].[dbo].[PROD_Variant] AS X WITH(NOLOCK) ON X.No = {DMCommon.SummaryLogTable}.[TestListVariantNo] ";
            strQuery += $"LEFT JOIN [CPXV2].[dbo].[PROD_Group] AS Y WITH(NOLOCK) ON Y.No = X.GroupNo ";
            */

            strQuery += $"WHERE ";

            if (inputOption.ProductID.Length > 0 && inputOption.FullScanData)
            {
                bFullScanOn = true;
            }
            else
                strQuery += $"TestDT >= '{dtStart.ToString("yyyy-MM-dd HH:mm:ss")}' AND TestDT <= '{dtEnd.ToString("yyyy-MM-dd HH:mm:ss")}' AND ";

            strQuery += $"ProdNo_C NOT IN('PowerON', 'PowerOFF', 'QUERY') AND ";
            strQuery += $"ProductID NOT IN('PowerON', 'PowerOFF', 'QUERY') ";

            if (inputOption.ProductID.Length > 0)
            {
                strQuery += $"AND ProductID = '{inputOption.ProductID}' ";
            }
           
            strQuery += $"GROUP BY ";

            strQuery += $"CAST({DMCommon.SummaryLogTable}.TestDT AS DATE),";
            //
            strQuery += $"Y.ModelName,";

            if (inputOption.DisplayByStation)
            {
                strQuery += $"{DMCommon.SummaryLogTable}.StationName,";
                strQuery += $"{DMCommon.SummaryLogTable}.HostID,";
                strQuery += $"{DMCommon.SummaryLogTable}.Section,";
                strQuery += $"{DMCommon.SummaryLogTable}.TestListCntID,";
            }

            if (inputOption.ProductID.Length > 0)
                strQuery += $"{DMCommon.SummaryLogTable}.ProductID,";

            strQuery += $"{DMCommon.SummaryLogTable}.TestType,";
            strQuery += $"{DMCommon.SummaryLogTable}.ProdNo_C,";
            strQuery += $"{DMCommon.SummaryLogTable}.Testcode,";
            strQuery += $"{DMCommon.SummaryLogTable}.[TestListFileNo],";
            strQuery += $"{DMCommon.SummaryLogTable}.[TestListVariantNo],";
            strQuery += $"{DMCommon.SummaryLogTable}.ProdNo_P,";
            strQuery += $"{DMCommon.SummaryLogTable}.ProdCode,";
            strQuery += $"{DMCommon.SummaryLogTable}.Version,";
            strQuery += $"{DMCommon.SummaryLogTable}.StepVersion";
            strQuery += " ";
            strQuery += ") AS X WHERE X.RN = 1 ";

            if (inputOption.DisplayByStation)
            {
                strQuery += "ORDER BY Host, Section ASC;";
                //strQuery += "ORDER BY Host, Section DESC;";
            }
            else
            {
                strQuery += "ORDER BY ProductNo, ParentNo ASC;";
                //strQuery += ";";
            }

            if (strTestQuery.Length > 0)
                strQuery = strTestQuery;

            strGetSendQuery = strQuery;

            if (bUseMainConn)
            {
                SQLCmd = new SqlCommand(strQuery, DBConn);
            }
            else
            {
                if (bScanLongTermUse)
                    SQLCmd = new SqlCommand(strQuery, LongTermDBConn);
                else
                    SQLCmd = new SqlCommand(strQuery, ShortTermDBConn);
            }

            if(bFullScanOn)
                SQLCmd.CommandTimeout = DMCommon.nFullScanTime;
            else
                SQLCmd.CommandTimeout = DMCommon.nDefaultScanTime;

            DbDataReader dtReader = null;

            try
            {
                dtReader = await SQLCmd.ExecuteReaderAsync(CT);
            }
            catch
            {
                if (dtReader != null)
                {
                    dtReader.Close();
                    dtReader = null;
                }
            }
            finally
            {
                if (dtReader != null)
                {
                    dtResult.Load(dtReader);

                    dtReader.Close();
                }
            }

            return new Tuple<DataTable, string>(dtResult, strGetSendQuery);
        }
    }
}
