using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geodatabase;
using KGIS.Framework.DBOperator;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using System;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices;
namespace Kingo.PluginServiceInterface.Helper
{
    public static class BSMHelper
    {
        /// 
        /// 补充更新传入图层的标识码,只操作标识码为空或者重复的图斑
        /// 
        public static void UpdateBSM(ProjectInfo projectInfo, string layerName, IFeatureClass featureClass, IRDBHelper rdbHelper = null, bool isNeedDisConn = true)
        {
            IFeatureCursor pCursor = null;
            IFeature f = null;
            try
            {
                if (projectInfo == null || string.IsNullOrEmpty(projectInfo.CODE)) return;
                string bsmLeftStr = "";
                if (featureClass == null) return;
                int bsmIdx = featureClass.FindField("BSM");
                if (bsmIdx == -1) return;
                int xh = 0;
                if (featureClass.FeatureCount(null) != 0)
                {
                    string MaxBSM = GetMaxBSM(featureClass);
                    if (!string.IsNullOrEmpty(MaxBSM) && MaxBSM.Length == 18)
                    {
                        int xh2 = Convert.ToInt32(MaxBSM.Substring(10));
                        bsmLeftStr = MaxBSM.Substring(0, 10);
                        if (xh < xh2)
                            xh = xh2;
                    }
                    else
                        bsmLeftStr = projectInfo.CODE + GetBsmCode(layerName);
                }
                else
                {
                    bsmLeftStr = projectInfo.CODE + GetBsmCode(layerName);
                }
                IQueryFilter queryFilter = new QueryFilterClass() { WhereClause = "BSM is null or BSM = '' or BSM = ' ' " };
                string dbPrjPath = System.IO.Path.GetDirectoryName(projectInfo.GetProjFilePath()) + @"\BGTJ.sqlite";
                if (rdbHelper == null)
                {
                    rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbPrjPath, DatabaseType.SQLite);
                }
                CopyTable(rdbHelper, dbPrjPath, layerName, featureClass);
                string strSql = $"select BSM from {(featureClass as IDataset).Name} GROUP BY BSM HAVING COUNT(BSM) > 1";
                DataTable ChangeDT = rdbHelper?.ExecuteDatatable("BSMRepeat", strSql, true);
                if (ChangeDT != null)
                {
                    string BSMs = "";
                    foreach (DataRow dr in ChangeDT.Rows)
                    {
                        BSMs += $"'{dr["BSM"].ToTrim()}',";
                    }
                    queryFilter = new QueryFilterClass() { WhereClause = $" BSM IN({BSMs.Trim(',')}) OR BSM IS NULL OR BSM = '' OR BSM = ' '" };
                    if (BSMs.Length < 18)
                        queryFilter.WhereClause = $" BSM IS NULL OR BSM = '' OR BSM = ' ' ";
                }
                pCursor = featureClass.Search(queryFilter, true);
                while ((f = pCursor.NextFeature()) != null)
                {
                    xh++;
                    string newbsm = bsmLeftStr + xh.ToString().PadLeft(8, '0');
                    f.Value[bsmIdx] = newbsm;
                    f.Store();
                }
                pCursor.Flush();
            }
            catch (Exception ex)
            {
                LogAPI.Debug($"{layerName}标识码维护失败:" + ex.Message);
                LogAPI.Debug($"{layerName}标识码维护失败:" + ex.StackTrace);
            }
            finally
            {
                if (pCursor != null)
                    Marshal.ReleaseComObject(pCursor);
                if (f != null)
                    Marshal.ReleaseComObject(f);
                if (isNeedDisConn)
                {
                    if (rdbHelper != null && rdbHelper.State != ConnectionState.Closed)
                        rdbHelper.DisConnect();
                }
            }
        }
        /// 
        /// 补充更新传入图层的标识码,全部重新编排
        /// 
        public static void UpdateAllBSM(ProjectInfo projectInfo, string layerName, IFeatureClass featureClass)
        {
            IFeatureCursor pCursor = null;
            IFeature f = null;
            try
            {
                if (projectInfo == null || string.IsNullOrEmpty(projectInfo.CODE)) return;
                string bsmLeftStr = "";
                if (featureClass == null) return;
                int bsmIdx = featureClass.FindField("BSM");
                if (bsmIdx == -1) return;
                int xh = 0;
                if (featureClass.FeatureCount(null) != 0)
                {
                    string MaxBSM = GetMaxBSM(featureClass);
                    if (!string.IsNullOrEmpty(MaxBSM) && MaxBSM.Length == 18)
                    {
                        int xh2 = Convert.ToInt32(MaxBSM.Substring(10));
                        bsmLeftStr = MaxBSM.Substring(0, 10);
                        if (xh < xh2)
                            xh = xh2;
                    }
                    else
                        bsmLeftStr = projectInfo.CODE + GetBsmCode(layerName);
                }
                else
                {
                    bsmLeftStr = projectInfo.CODE + GetBsmCode(layerName);
                }
                pCursor = featureClass.Search(null, true);
                while ((f = pCursor.NextFeature()) != null)
                {
                    xh++;
                    string newbsm = bsmLeftStr + xh.ToString().PadLeft(8, '0');
                    f.Value[bsmIdx] = newbsm;
                    f.Store();
                }
                pCursor.Flush();
            }
            catch (Exception ex)
            {
                LogAPI.Debug($"{layerName}标识码维护失败:" + ex.Message);
                LogAPI.Debug($"{layerName}标识码维护失败:" + ex.StackTrace);
            }
            finally
            {
                if (pCursor != null)
                    Marshal.ReleaseComObject(pCursor);
                if (f != null)
                    Marshal.ReleaseComObject(f);
            }
        }
        /// 
        /// 获取每个图层的图层标识码的四位特殊编号
        /// 
        public static string GetBsmCode(string layerName)
        {
            string bsmLeftStr = string.Empty;
            switch (layerName)
            {
                case "DLTBBG":
                    bsmLeftStr = "2110";
                    break;
                case "DLTBGX":
                    bsmLeftStr = "2110";
                    break;
                case "DLTBGXGC":
                    bsmLeftStr = "2111";
                    break;
                case "CZCDYDGX":
                    bsmLeftStr = "2931";
                    break;
                case "CZCDYDGXGC":
                    bsmLeftStr = "2932";
                    break;
                case "XZQGX":
                    bsmLeftStr = "1210";
                    break;
                case "XZQGXGC":
                    bsmLeftStr = "1211";
                    break;
                case "CJDCQGX":
                    bsmLeftStr = "1240";
                    break;
                case "CJDCQGXGC":
                    bsmLeftStr = "1241";
                    break;
                case "CJDCQJXGX":
                    bsmLeftStr = "1250";
                    break;
                case "XZQJXGX":
                    bsmLeftStr = "1220";
                    break;
                case "TTQGX":
                    bsmLeftStr = "2981";
                    break;
                case "GDDBGX":
                    bsmLeftStr = "2941";
                    break;
                case "PDTGX":
                    bsmLeftStr = "1330";
                    break;
                case "GCHZZGX":
                    bsmLeftStr = "29C1";
                    break;
                case "GFBQGX":
                    bsmLeftStr = "2971";
                    break;
                case "CCWJQGX":
                    bsmLeftStr = "2991";
                    break;
                case "LMFWGX":
                    bsmLeftStr = "29A1";
                    break;
                default:
                    break;
            }
            return bsmLeftStr;
        }
        #region 获取图层中的最大标识码
        /// 
        /// 获取图层中的最大标识码
        /// 
        public static string GetMaxBSM(IFeatureClass fc)
        {
            string BSM = string.Empty;
            int BSMIndex = fc.FindField("BSM");
            if (BSMIndex == -1) return BSM;
            ITable table = (ITable)fc;
            ITableSort tableSort = new TableSortClass();
            tableSort.Table = table;
            tableSort.Fields = "BSM";
            tableSort.set_Ascending("BSM", false);
            tableSort.Sort(null);
            ICursor cursor = tableSort.Rows;
            IRow row = cursor.NextRow();
            if (row != null)
            {
                int maxBSM = 0;
                int currBSM = 0;
                string BSMStr = row.Value[BSMIndex].ToString();
                if (BSMStr.Length != 18) return BSM;
                string subBSMStr = BSMStr.Substring(9);
                try
                {
                    currBSM = Convert.ToInt32(subBSMStr);
                }
                catch (Exception)
                {
                    return BSM;
                }
                if (currBSM > maxBSM) maxBSM = currBSM;
                if (BSMStr.Length != 18) return BSM;
                string maxStr = maxBSM.ToString();
                int zeroNum = 9 - maxStr.Length;
                for (int i = 0; i < zeroNum; i++)
                {
                    maxStr = 0 + maxStr;
                }
                BSM = BSMStr.Substring(0, 9) + maxStr;
            }
            return BSM;
        }
        /// 
        /// 获取图层中的最大标识码
        /// 
        public static string GetMaxBSM(List fcList)
        {
            int xh = 0;
            string MaxBSM = "";
            string leftStr = string.Empty;
            foreach (var fc in fcList)
            {
                string BSM = string.Empty;
                int BSMIndex = fc.FindField("BSM");
                if (BSMIndex == -1) return BSM;
                ITable table = (ITable)fc;
                // 创建一个ITableSort接口对象
                ITableSort tableSort = new TableSortClass();
                tableSort.Table = table;
                tableSort.QueryFilter = new QueryFilterClass() { WhereClause = $"BSM like '{(MapsManager.Instance.CurrProjectInfo as ProjectInfo).CODE}%'" };
                if (System.IO.Path.GetExtension((fc as FeatureClass).Workspace.PathName).ToLower().Contains(".mdb"))
                    tableSort.QueryFilter = new QueryFilterClass() { WhereClause = $"BSM like '{(MapsManager.Instance.CurrProjectInfo as ProjectInfo).CODE}*'" };
                tableSort.Fields = "BSM";
                tableSort.set_Ascending("BSM", false);
                tableSort.Sort(null);
                ICursor cursor = tableSort.Rows;
                IRow row = cursor.NextRow();
                if (row != null)
                {
                    int maxBSM = 0;
                    int currBSM = 0;
                    string BSMStr = row.Value[BSMIndex].ToString();
                    if (BSMStr.Length != 18) return BSM;
                    string subBSMStr = BSMStr.Substring(9);
                    try
                    {
                        currBSM = Convert.ToInt32(subBSMStr);
                    }
                    catch (Exception)
                    {
                        return BSM;
                    }
                    if (currBSM > maxBSM) maxBSM = currBSM;
                    if (BSMStr.Length != 18) return BSM;
                    string maxStr = maxBSM.ToString();
                    int zeroNum = 9 - maxStr.Length;
                    for (int i = 0; i < zeroNum; i++)
                    {
                        maxStr = 0 + maxStr;
                    }
                    BSM = BSMStr.Substring(0, 9) + maxStr;
                }
                if (BSM.Length != 18)
                    continue;
                int xh2 = Convert.ToInt32(BSM.Substring(10));
                leftStr = BSM.Substring(0, 10);
                if (xh < xh2)
                {
                    xh = xh2;
                    MaxBSM = BSM;
                }
            }
            return MaxBSM;
        }
        /// 
        /// 获取图层中的最大标识码
        /// 
        public static string GetMaxBSM(List fcList, string strCode)
        {
            int xh = 0;
            string MaxBSM = "";
            string leftStr = string.Empty;
            foreach (var fc in fcList)
            {
                string BSM = string.Empty;
                int BSMIndex = fc.FindField("BSM");
                if (BSMIndex == -1) return BSM;
                ITable table = (ITable)fc;
                // 创建一个ITableSort接口对象
                ITableSort tableSort = new TableSortClass();
                tableSort.Table = table;
                tableSort.QueryFilter = new QueryFilterClass() { WhereClause = $"BSM like '{strCode}%'" };
                if (System.IO.Path.GetExtension((fc as FeatureClass).Workspace.PathName).ToLower().Contains(".mdb"))
                    tableSort.QueryFilter = new QueryFilterClass() { WhereClause = $"BSM like '{strCode}*'" };
                tableSort.Fields = "BSM";
                tableSort.set_Ascending("BSM", false);
                tableSort.Sort(null);
                ICursor cursor = tableSort.Rows;
                IRow row = cursor.NextRow();
                if (row != null)
                {
                    int maxBSM = 0;
                    int currBSM = 0;
                    string BSMStr = row.Value[BSMIndex].ToString();
                    if (BSMStr.Length != 18) return BSM;
                    string subBSMStr = BSMStr.Substring(9);
                    try
                    {
                        currBSM = Convert.ToInt32(subBSMStr);
                    }
                    catch (Exception)
                    {
                        return BSM;
                    }
                    if (currBSM > maxBSM) maxBSM = currBSM;
                    if (BSMStr.Length != 18) return BSM;
                    string maxStr = maxBSM.ToString();
                    int zeroNum = 9 - maxStr.Length;
                    for (int i = 0; i < zeroNum; i++)
                    {
                        maxStr = 0 + maxStr;
                    }
                    BSM = BSMStr.Substring(0, 9) + maxStr;
                }
                if (BSM.Length != 18)
                    continue;
                int xh2 = Convert.ToInt32(BSM.Substring(10));
                leftStr = BSM.Substring(0, 10);
                if (xh < xh2)
                {
                    xh = xh2;
                    MaxBSM = BSM;
                }
            }
            return MaxBSM;
        }
        #endregion
        #region 获取最新完整标识码
        /// 
        /// 获取最新完整标识码
        /// 
        public static string GetNewBSM(List fcList, string prjCode, string layerCode)
        {
            string result = string.Empty;
            int xh = 0;
            string leftStr = string.Empty;
            foreach (var item in fcList)
            {
                string MaxBSM = GetMaxBSM(item);
                if (MaxBSM.Length != 18)
                    continue;
                int xh2 = Convert.ToInt32(MaxBSM.Substring(10));
                leftStr = MaxBSM.Substring(0, 10);
                if (xh < xh2)
                    xh = xh2;
            }
            xh++;
            if (string.IsNullOrWhiteSpace(leftStr))
                leftStr = prjCode + layerCode;
            result = leftStr + xh.ToString().PadLeft(8, '0');
            return result;
        }
        #endregion
        public static void CopyTable(IRDBHelper rdbHelper, string dbPrjPath, string layerName, IFeatureClass featureClass)
        {
            IWorkspaceFactory pOutWorkFactory = new SqlWorkspaceFactoryClass();
            try
            {
                if (rdbHelper == null) rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbPrjPath, DatabaseType.SQLite);
                IWorkspace pOutWork = pOutWorkFactory.OpenFromFile(dbPrjPath, 0);
                rdbHelper.ExecuteSQL($" Drop Table {layerName}");
                TableToTable((featureClass as FeatureClass).Workspace as IFeatureWorkspace, pOutWork, layerName);
            }
            catch (Exception ex)
            {
                LogAPI.Debug(ex);
                return;
            }
        }
        public static bool TableToTable(IFeatureWorkspace pInWork, IWorkspace pOutWork, string tableName, IQueryFilter queryFilter = null)
        {
            try
            {
                if (pInWork == null || pOutWork == null || string.IsNullOrEmpty(tableName)) return false;
                if (pInWork is IWorkspace2 workspace2)
                {
                    if (!workspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, tableName))
                    {
                        return false;
                    }
                }
                ITable pInTable = pInWork.OpenTable(tableName);
                if (pInTable == null) return false;
                IDataset pIndataset = (IDataset)pInTable;
                IDatasetName pInDatasetName = (IDatasetName)pIndataset.FullName;
                IEnumDataset enumDataset = pOutWork.get_Datasets(esriDatasetType.esriDTTable);
                IDataset dataset;
                enumDataset.Reset();
                while ((dataset = enumDataset.Next()) != null)
                {
                    string[] names = dataset.Name.Split('.');
                    if (string.Equals(names[names.Length - 1], tableName, StringComparison.CurrentCultureIgnoreCase))
                    {
                        dataset.Delete();
                        break;
                    }
                }
                IDataset pOutDataset = (IDataset)pOutWork;
                IDatasetName pOutDatasetName = new TableNameClass();
                pOutDatasetName.WorkspaceName = (IWorkspaceName)pOutDataset.FullName;
                pOutDatasetName.Name = tableName;
                IFieldChecker fieldChecker = new FieldCheckerClass();
                IFields targetFeatureClassFields = pInTable.Fields;
                IFields sourceFeatureClassFields = pInTable.Fields;
                IEnumFieldError enumFieldError;
                fieldChecker.InputWorkspace = pInWork as IWorkspace;
                fieldChecker.ValidateWorkspace = pOutWork;
                fieldChecker.Validate(sourceFeatureClassFields, out enumFieldError, out targetFeatureClassFields);
                IFeatureDataConverter one2another = new FeatureDataConverterClass();
                try
                {
                    one2another.ConvertTable(pInDatasetName, queryFilter, pOutDatasetName, targetFeatureClassFields, "", 1000, 0);
                }
                finally
                {
                    Marshal.ReleaseComObject(one2another);
                }
                return true;
            }
            catch (Exception ex)
            {
                LogAPI.Debug(ex);
                throw ex;
            }
        }
    }
}