using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using KGIS.Framework.Utils.Helper;
using Kingo.Plugin.EngineEditor.helper;
using Kingo.Plugin.EngineEditor.Model;
using Kingo.PluginServiceInterface;
using KUI.Windows;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Kingo.Plugin.EngineEditor.Views.BoundaryFitting
{
    /// 
    /// UCBoundaryFittingNew.xaml 的交互逻辑
    /// 
    public partial class UCBoundaryFittingNew : BaseWindow
    {
        private IHookHelper m_hookHelper;//获取地图控件和主窗体
        private Dictionary keys { get; set; }
        private EngineEditorClass _engineEdit = new EngineEditorClass();
        private IFeatureLayer SelectFeatureLayer = null;
        public UCBoundaryFittingNew(object Helpers, EngineEditorClass m_engineEdit)
        {
            InitializeComponent();
            try
            {
                if (this.m_hookHelper == null)
                    this.m_hookHelper = Helpers as IHookHelper;
                //获取当前工程中的全部图层
                List featureLayers = MapsManager.Instance.MapService.GetAllVisibleLayerInMap();
                if (featureLayers != null && featureLayers.Count > 0)
                {
                    keys = new Dictionary();
                    foreach (IFeatureLayer iFeatureLayer in featureLayers)
                    {
                        if (!keys.ContainsKey(iFeatureLayer.Name))
                            keys.Add(iFeatureLayer.Name, iFeatureLayer);
                    }
                    targetName.ItemsSource = keys.Keys;
                    int index = keys.Keys.ToList().IndexOf("基础_地类图斑");
                    if (index >= 0)
                    {
                        targetName.SelectedIndex = index;
                    }
                }
                _engineEdit = m_engineEdit;
            }
            catch (Exception ex)
            {
                LogAPI.Debug("UCBoundaryFitting异常:" + ex.Message);
                LogAPI.Debug("UCBoundaryFitting异常:" + ex.StackTrace);
                MessageHelper.ShowError("初始化边界修复界面异常" + ex.Message);
            }
        }
        #region 目标图层切换事件
        private void targetName_SelectionChanged(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                if (keys != null)
                {
                    IFeatureLayer featureLayer = keys[targetName.SelectedItem.ToTrim()];
                    if (featureLayer == null) return;
                    SelectFeatureLayer = featureLayer;
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug("targetName_SelectionChanged异常:" + ex.Message);
                LogAPI.Debug("targetName_SelectionChanged异常:" + ex.StackTrace);
            }
        }
        #endregion
        #region 关闭窗体事件
        private void BaseWindow_Closed(object sender, EventArgs e)
        {
            try
            {
                this.Close();
            }
            catch (Exception ex)
            {
                LogAPI.Debug("BaseWindow_Closed异常:" + ex.Message);
                LogAPI.Debug("BaseWindow_Closed异常:" + ex.StackTrace);
            }
        }
        #endregion
        private void btnCancel1_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                this.Close();
            }
            catch (Exception ex)
            {
                LogAPI.Debug("btnCancel1_Click异常:" + ex.Message);
                LogAPI.Debug("btnCancel1_Click异常:" + ex.StackTrace);
            }
        }
        private void btnOK_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                double disValue = 1.0;
                if (!double.TryParse(AttributeValue.Text, out disValue) || disValue <= 0 || disValue > 10)
                {
                    MessageHelper.ShowTips("容差输入不正确.");
                    return;
                }
                if (_engineEdit.EditState != esriEngineEditState.esriEngineStateEditing)
                {
                    MessageHelper.ShowTips("请先开启编辑.");
                    return;
                }
                if (this.SelectFeatureLayer == null)
                {
                    MessageHelper.ShowTips("请选择需要边界套合的参考图层.");
                    return;
                }
                IFeatureLayer dltbbgLayer = MapsManager.Instance.MapService.GetFeatureLayerByName("DLTBBG");
                if (dltbbgLayer == null)
                {
                    MessageHelper.ShowTips("未获取到单图斑地类图斑更新层!");
                    return;
                }
                IFeatureLayer TargetLayer = (_engineEdit as EngineEditorClass).TargetLayer as IFeatureLayer;
                if (TargetLayer == null || TargetLayer.FeatureClass == null || TargetLayer.FeatureClass.FeatureCount(null) == 0)
                {
                    MessageHelper.ShowTips("请选择正确的参考图层.");
                    return;
                }
                int indexBSM = this.SelectFeatureLayer.FeatureClass.Fields.FindField("BSM");
                int indexTBBSM = this.SelectFeatureLayer.FeatureClass.Fields.FindField("TBBSM");
                int indexDTB_TBBSM = TargetLayer.FeatureClass.Fields.FindField("TBBSM");
                IEnumFeature enumFeature = m_hookHelper.FocusMap.FeatureSelection as IEnumFeature;
                enumFeature.Reset();
                IFeature feature = enumFeature.Next();
                if (feature == null)
                {
                    MessageHelper.ShowTips("请选择要修复的图斑.");
                    return;
                }
                this.ShowLoading("正在进行边界修复......", 0, 0);
                Dictionary> xfDic = new Dictionary>();
                #region 分组统计选中子地块所在任务包及该TBBSM下其余子地块
                while (feature != null)
                {
                    int tbbsmIndex = feature.Fields.FindField("tbbsm");
                    int bidIndex = feature.Fields.FindField("packageid");
                    if (tbbsmIndex < 0 || bidIndex < 0)
                    {
                        continue;
                    }
                    string tbbsm = feature.get_Value(tbbsmIndex).ToString();
                    string bid = feature.get_Value(bidIndex).ToString();
                    if (xfDic.ContainsKey(bid))
                    {
                        xfDic[bid].Add(tbbsm);
                    }
                    else
                    {
                        xfDic.Add(bid, new List() { tbbsm });
                    }
                    feature = enumFeature.Next();
                }
                #endregion
                List _features = null;
                ISpatialFilter spatialFilter = null;
                IFeatureCursor cursor = null;
                List repairs = new List();
                List tbbsmList = new List();
                #region 构造边界修复数据
                foreach (string bid in xfDic.Keys)
                {
                    tbbsmList = xfDic[bid].Distinct().ToList();
                    string where = string.Join(",", tbbsmList.Select(x => $"'{x}'"));
                    spatialFilter = new SpatialFilterClass()
                    {
                        WhereClause = $"packageid = '{bid}' and tbbsm in ({where})"
                    };
                    cursor = dltbbgLayer.Search(spatialFilter, true);
                    while ((feature = cursor.NextFeature()) != null)
                    {
                        try
                        {
                            int bsmIndex = feature.Fields.FindField("bsm");
                            string bsm = feature.get_Value(bsmIndex).ToString();
                            RepairEntity repairEntity = new RepairEntity()
                            {
                                Geometry = feature.ShapeCopy,
                                ListReference = new List(),
                                Distance = disValue,
                                JCBH = bsm,
                                PackageId = bid,
                                OID = feature.OID
                            };
                            _features = FeatureAPI.Identify(feature.ShapeCopy, SelectFeatureLayer);
                            if (_features == null || _features.Count < 1)
                            {
                                this.CloseLoading();
                                System.Threading.Thread.Sleep(1000);
                                MessageHelper.ShowTips($"边界修复提示:标识码为【{bsm}】地块未获取到参考图层要素!跳过当前图斑。");
                                continue;
                            }
                            foreach (IFeature jcfeature in _features)
                            {
                                if (indexTBBSM > -1 && indexDTB_TBBSM > -1 && jcfeature.get_Value(indexTBBSM).ToString().Equals(feature.get_Value(indexDTB_TBBSM).ToString()))
                                {
                                    continue;
                                }
                                repairEntity.ListReference.Add(new ReferenceEntity()
                                {
                                    BSM = indexBSM > -1 ? jcfeature.Value[indexBSM].ToString().Trim() : "",
                                    RefGeometry = jcfeature.ShapeCopy,
                                    oid = jcfeature.OID
                                });
                            }
                            repairs.Add(repairEntity);
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                }
                #endregion
                List UnionList = new List();
                _engineEdit.StartOperation();
                BoundaryRepairHelper.Execute(repairs, UnionList);
                List updRes = repairs.Where(x => !x.JCBH.Contains("NMK") && !x.JCBH.Contains("_DELETE")).ToList();
                List delRes = repairs.Where(x => x.JCBH.Contains("_DELETE")).ToList();
                #region 删除要素
                List oidList = new List();
                //string queryBsms = string.Join(",", delRes.Select(x => $"'{x.JCBH.Replace("_DELETE", "")}'"));
                //string queryBids = string.Join(",", delRes.Select(x => $"'{x.PackageId}'"));
                //spatialFilter = new SpatialFilterClass()
                //{
                //    WhereClause = $"packageid in ({queryBids}) and bsm in ({queryBsms})"
                //};
                //cursor = dltbbgLayer.FeatureClass.Search(spatialFilter, true);
                //while ((feature = cursor.NextFeature()) != null)
                //{
                //    oidList.Add(feature.OID);
                //}
                foreach (RepairEntity item in delRes)
                {
                    oidList.Add(item.OID);
                }
                if (UnionList.Count > 0)
                {
                    oidList.AddRange(UnionList);
                }
                if (oidList.Count > 0)
                {
                    foreach (int oid in oidList)
                    {
                        feature = dltbbgLayer.FeatureClass.GetFeature(oid);
                        if (feature != null)
                        {
                            feature.Delete();
                        }
                    }
                }
                #endregion
                #region 修改要素
                Dictionary oidDic = new Dictionary();
                //queryBsms = string.Join(",", updRes.Select(x => $"'{x.JCBH}'"));
                //queryBids = string.Join(",", updRes.Select(x => $"'{x.PackageId}'"));
                //spatialFilter = new SpatialFilterClass()
                //{
                //    WhereClause = $"packageid in ({queryBids}) and bsm in ({queryBsms})"
                //};
                //cursor = dltbbgLayer.FeatureClass.Search(spatialFilter, true);
                //while ((feature = cursor.NextFeature()) != null)
                //{
                //    oidDic.Add(feature.OID, feature.get_Value(feature.Fields.FindField("bsm")).ToString());
                //}
                foreach (RepairEntity item in updRes)
                {
                    oidDic.Add(item.OID, item.JCBH);
                }
                foreach (int oid in oidDic.Keys)
                {
                    feature = dltbbgLayer.FeatureClass.GetFeature(oid);
                    if (feature == null)
                    {
                        continue;
                    }
                    string bsm = oidDic[oid];
                    RepairEntity repair = repairs.FirstOrDefault(x => x.JCBH == bsm);
                    if (repair == null)
                    {
                        continue;
                    }
                    bool isConvert = repair.Geometry == null || repair.Geometry.IsEmpty;
                    bool isContinue = string.IsNullOrWhiteSpace(repair.WKT);
                    if (isConvert && isContinue)
                    {
                        continue;
                    }
                    feature.Shape = isConvert ? GeometryConvertHelper.ConvertWKTToIGeometry(repair.WKT) : repair.Geometry;
                    feature.Store();
                }
                #endregion
                m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewBackground, null, m_hookHelper.ActiveView.Extent);
                _engineEdit.StopOperation("边界修复");
                MessageHelper.ShowTips("修复完成.");
                this.CloseLoading();
                Close();
            }
            catch (Exception ex)
            {
                _engineEdit.AbortOperation();
                this.CloseLoading();
                LogAPI.Debug("btnOK_Click异常:" + ex.Message);
                LogAPI.Debug("btnOK_Click异常:" + ex.StackTrace);
                MessageHelper.ShowError("边界修复异常:" + ex.Message);
            }
        }
        #region 边界套合后图形判断是否有曲线,有则转折线
        private IGeometry IsCurve(IGeometry geo)
        {
            if (geo != null && !geo.IsEmpty && GeometryContainsCurves(geo))
            {
                FeatureAPI.ArcToPolyline(ref geo);
            }
            return geo;
        }
        #endregion
        /// 
        /// 判断传入图新是否包含曲线
        /// 
        /// 
        /// 
        public static bool GeometryContainsCurves(IGeometry geometry)
        {
            if (geometry == null || geometry.IsEmpty)
            {
                throw new Exception("图形不能为null或者无效图形");
            }
            try
            {
                if (geometry is IGeometryCollection geometryCollection)
                {
                    for (int i = 0; i < geometryCollection.GeometryCount; i++)
                    {
                        IGeometry part = geometryCollection.get_Geometry(i);
                        if (part is ISegmentCollection segmentCollection)
                        {
                            for (int j = 0; j < segmentCollection.SegmentCount; j++)
                            {
                                ISegment segment = segmentCollection.get_Segment(j);
                                if (segment is ICurve)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}