using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.AE.Enum;
using KGIS.Framework.AE.ExtensionMethod;
using KGIS.Framework.AE.GPHelper;
using KGIS.Framework.DBOperator;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using KGIS.Framework.Utils.Helper;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Kingo.PluginServiceInterface.Helper
{
    /// 
    /// 在线建库软件地类图斑变更层检查
    /// 
    public static class BGTBDataCheckHelper
    {
        #region 属性检查
        /// 
        /// 地类图斑变更层值域规范性和逻辑一致性检查检查
        /// 
        /// 
        public static List CheckAttribute(IFeature feature, IFeatureClass featureClass, string code)
        {
            List allResultList =new List();
            IRDBHelper rdbHelper = null;
            try
            {
                string dbPrjPath = System.IO.Path.GetDirectoryName((MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo).GetProjFilePath()) + @"\BGTJ.sqlite";
                rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbPrjPath, DatabaseType.SQLite);
                int bsmIdx = featureClass.FindField("BSM");
                if (bsmIdx != -1)
                {
                    string bsm = feature.Value[bsmIdx].ToTrim();
                    if (string.IsNullOrEmpty(bsm))
                        BSMHelper.UpdateBSM(MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo, "DLTBBG", featureClass, rdbHelper, false);
                }
                BSMHelper.CopyTable(rdbHelper, dbPrjPath, "DLTBBG", featureClass);
                string Sqlwhere = " where ( RuleType = '值域规范性' or RuleType = '逻辑一致性' ) and BGLayerName = 'DLTBBG_地类图斑变更' ";
                DataTable dataTable = rdbHelper.ExecuteDatatable("tab", $" SELECT * from CheckingRule {Sqlwhere} ", true);
                if (dataTable != null && dataTable.Rows.Count != 0)
                {
                    List valueRangeList = CheckStandard(dataTable, dbPrjPath, featureClass, feature.OID, code);
                    if (valueRangeList.Count > 0)
                        allResultList.AddRange(valueRangeList);
                }
                return allResultList;
            }
            catch (Exception ex)
            {
                LogAPI.Debug("值域规范性检查时发生异常:" + ex.Message);
                LogAPI.Debug("值域规范性检查时发生异常:" + ex.StackTrace);
                MessageHelper.ShowError("值域规范性检查时发生异常,详情请查看系统日志!");
                return allResultList;
            }
            finally
            {
                if (rdbHelper != null && rdbHelper.State != ConnectionState.Closed)
                    rdbHelper.DisConnect();
            }
        }
        private static List CheckStandard(DataTable dataTable, string dbPrjPath, IFeatureClass featureClass, int OID, string code)
        {
            List sqlList = new List();
            IRDBHelper errdbHelper = null;
            IFeatureCursor cursur = null;
            IFeature f = null;
            try
            {
                var ImplementSQL = string.Empty;
                var RuleCode = string.Empty;
                var RuleType = string.Empty;
                DataTable dt = null;
                string sqlStr = null;
                foreach (DataRow row in dataTable.Rows)
                {
                    ImplementSQL = row["ImplementSQL"].ToTrim();//执行语句
                    RuleCode = row["RuleCode"].ToTrim();//规则编码
                    RuleType = row["RuleType"].ToTrim();//规则类别
                    try
                    {
                        #region 源代码
                        if (string.IsNullOrEmpty(ImplementSQL) || !ImplementSQL.ToLower().Contains("select")) continue;
                        errdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbPrjPath, DatabaseType.SQLite);
                        dt = errdbHelper.ExecuteDatatable("tab", string.Format(ImplementSQL, "DLTBBG", "地类图斑变更", RuleCode, RuleType, code), true);
                        if (dt != null && dt.Rows.Count > 0)
                        {
                            foreach (DataRow item in dt.Rows)
                            {
                                if (dt.Columns.Contains("MC"))
                                {
                                    if (string.IsNullOrEmpty(item["MC"].ToString())) continue;
                                    if (Regex.IsMatch(item["MC"].ToString(), @"^[0-9]+$")
                                        || Regex.IsMatch(item["MC"].ToString().Substring(0, 1), @"^[A-Za-z]+$")
                                        || Regex.IsMatch(item["MC"].ToString(), "[^0-9a-zA-Z\u4e00-\u9fa5-_()()、]")
                                        )
                                    {
                                        sqlStr = $" OBJECTID = {OID}  and ";
                                        if (ImplementSQL.Contains("ZLDWMC"))
                                            sqlStr += $" ZLDWMC = '{item["MC"]}' ";
                                        else if (ImplementSQL.Contains("QSDWMC"))
                                            sqlStr += $" QSDWMC = '{item["MC"]}' ";
                                        sqlStr = sqlStr.TrimEnd("and".ToCharArray());
                                        cursur = featureClass.Search(new QueryFilterClass() { WhereClause = sqlStr }, true);
                                        while ((f = cursur.NextFeature()) != null)
                                        {
                                            sqlList.Add(string.Format("(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,ErrorDesc) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}');", f.OID.ToString(), f.Value[f.Fields.FindField("BSM")], item["ErrorLayer"], item["ErrorCode"], item["ErrorName"], item["RuleType"], f.Shape.ToJson(), item["MC"]));
                                        }
                                    }
                                    continue;
                                }
                                sqlStr = $" OBJECTID = {OID}  and ";
                                if (item["BSM"] == null || string.IsNullOrEmpty(item["BSM"].ToString()))
                                    sqlStr += $" (BSM is null or BSM = '' or BSM = ' ') ";
                                else if (ImplementSQL.Contains("BZ字段不允许填写字段值"))
                                    sqlStr += $" BZ = '{item["BZ"]}' ";
                                else
                                    sqlStr += $" BSM = '{item["BSM"]}' ";
                                sqlStr = sqlStr.TrimEnd("and".ToCharArray());
                                cursur = featureClass.Search(new QueryFilterClass() { WhereClause = sqlStr }, true);
                                string CheckFeatureClassName = featureClass.AliasName;
                                while ((f = cursur.NextFeature()) != null)
                                {
                                    sqlList.Add(string.Format("(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}');", f.OID, f.Value[f.Fields.FindField("BSM")], item["ErrorLayer"], item["ErrorCode"], item["ErrorName"], item["RuleType"]));
                                }
                            }
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        LogAPI.Debug($"错误代码【{RuleCode}】对应的查询语句错误:[{ex.Message}]");
                        continue;
                    }
                }
                return sqlList;
            }
            catch (Exception ex)
            {
                LogAPI.Debug("属性规范性检查发生异常:" + ex.Message);
                LogAPI.Debug("属性规范性检查发生异常:" + ex.StackTrace);
                return sqlList;
            }
            finally
            {
                if (errdbHelper != null && errdbHelper.State != ConnectionState.Closed)
                    errdbHelper.DisConnect();
                if (cursur != null)
                    Marshal.ReleaseComObject(cursur);
                if (f != null)
                    Marshal.ReleaseComObject(f);
            }
        }
        #endregion
        #region 重叠
        /// 
        /// 自身重叠检查
        /// 
        /// 
        public static bool CheckTopology(IFeatureClass featureClass, IFeature feature)
        {
            try
            {
                bool isShowTips = false;
                IGeometry geometry = feature.ShapeCopy;
                List topologyFeatures = FeatureAPI.Identify2(geometry, new FeatureLayer() { FeatureClass = featureClass });
                if (topologyFeatures != null && topologyFeatures.Count > 0)
                {
                    foreach (IFeature topologyFeature in topologyFeatures)
                    {
                        if (feature.OID == topologyFeature.OID) continue;
                        isShowTips = true;
                        break;
                    }
                    return isShowTips;
                }
                return isShowTips;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// 
        /// 重叠修复(第一种情况,删除原来图层数据相交部分)
        /// 
        /// 
        public static List RepairTopology(IFeatureClass featureClass, IFeature feature)
        {
            List geometries = new List();
            try
            {
                IGeometry geometry = feature.ShapeCopy;
                List topologyFeatures = FeatureAPI.Identify2(geometry, new FeatureLayer() { FeatureClass = featureClass });
                if (topologyFeatures != null && topologyFeatures.Count > 0)
                {
                    foreach (IFeature topologyFeature in topologyFeatures)
                    {
                        if (feature.OID == topologyFeature.OID) continue;
                        IGeometry eraseGeometry = FeatureAPI.Difference(topologyFeature.ShapeCopy, geometry);
                        geometries.Add(eraseGeometry);
                    }
                }
                return geometries;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// 
        /// 重叠修复(第二种情况,删除当前变更数据相交部分)
        /// 
        /// 
        public static IGeometry RepairTopology2(IFeatureClass featureClass, IFeature feature, out List geometries)
        {
            IGeometry geometry = feature.ShapeCopy;
            geometries = new List();
            try
            {
                List topologyFeatures = FeatureAPI.Identify2(geometry, new FeatureLayer() { FeatureClass = featureClass });
                if (topologyFeatures != null && topologyFeatures.Count > 0)
                {
                    IGeometry unionGeometry = null;
                    foreach (IFeature topologyFeature in topologyFeatures)
                    {
                        if (feature.OID == topologyFeature.OID) continue;
                        geometries.Add(topologyFeature.ShapeCopy);
                        if (unionGeometry == null) 
                            unionGeometry = topologyFeature.ShapeCopy;
                        else 
                            unionGeometry = FeatureAPI.Union(unionGeometry, topologyFeature.ShapeCopy);
                    }
                    if (unionGeometry != null)
                    {
                        IGeometry eraseGeometry = FeatureAPI.Difference(geometry, unionGeometry);
                        return eraseGeometry;
                    }
                }
                return geometry;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}