using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Extensions;
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using ArcGIS.Desktop.KnowledgeGraph;

namespace DataExplorationWithSpatialClauses
{
	internal class CreateSpatialFiltersForAllFireZone : Button
	{
        protected override void OnClick()
        {
            //Get the map
            var map = MapView.Active?.Map;
            if (map == null) return;
            //Get all the feature layers in the map
            var layers = map.GetLayersAsFlattenedList().OfType<FeatureLayer>();
            //This is the Fire Zone layer which is used to create the spatial filter - Our "cookie cutter".
            var fireZoneSpatialDefLyr = layers.FirstOrDefault(f => f.Name == "Los Angeles fires perimeter 2025");
            if (fireZoneSpatialDefLyr == null) return;
            //This is the LA County parcels layer to which we will apply the spatial filter to.
            var laCountyParcelsLyr = layers.FirstOrDefault(f => f.Name == "Los Angeles county parcels");
            if (laCountyParcelsLyr == null) return;
            //This is the Fire Damage Inspection layer to which we will apply the spatial filter to.
            var fireDamageInspectionLyr = layers.FirstOrDefault(f => f.Name == "Fire Damage Inspection");
            if (fireDamageInspectionLyr == null) return;
            
            try
            {
                QueuedTask.Run(() => {
                    //Get the feature class of the spatial definition layer
                    var fireZoneFeatureClass = fireZoneSpatialDefLyr.GetFeatureClass();
                    //Iterate through each feature in the fire zone layer to get its geometry and create a spatial filter for it
                    using (var rowCursor = fireZoneFeatureClass.Search())
                    {
                        while (rowCursor.MoveNext())
                        {
                            using (var firePolyfeature = rowCursor.Current as ArcGIS.Core.Data.Feature)
                            {
                                //Use this to get the feature outline for the spatial filter.
                                var fireZoneGeom = firePolyfeature.GetShape();
                                var fireZoneName = rowCursor.Current["Fire Name"];
                                //Create the definition query
                                DefinitionQuery definitionQuery = new DefinitionQuery
                                {
                                    //optional to add a where clause along with the spatial filter
                                    //WhereClause = "UseType = 'Residential'" //Residential parcels,
                                    //Get the Name field and use that as the Definition Query name
                                    Name = $"{fireZoneName}"
                                };
                                //Setting the spatial filter to the Definition Query
                                if (definitionQuery.CanSetFilterGeometry(fireZoneGeom))
                                {
                                    definitionQuery.SetFilterGeometry(fireZoneGeom);
                                }
                                //Apply the definition query to the LA County parcels layer
                                laCountyParcelsLyr.InsertDefinitionQuery(definitionQuery);
                                //Apply the definition query to the Fire Damage Inspection layer
                                fireDamageInspectionLyr.InsertDefinitionQuery(definitionQuery);
                                //update FireGeometryDictionary with the fire zone name and geometry for later use
                                if (!Module1.FireGeometryDictionary.ContainsKey(fireZoneName.ToString()))
                                {
                                    Module1.FireGeometryDictionary.Add(fireZoneName.ToString(), fireZoneGeom);
                                }
                            }
                        }
                    }                   
                });
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error querying feature layer: {ex.Message}");
            }
        }
	}
}
