using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using UnityEditor;
using VOID.ScriptableObjects.Affiliation;

namespace VOID.Editor.EditorWindow.Affiliation
{
    public class AffiliationEditor : OdinEditorWindow
    {
        [MenuItem("VOID RPG/Affiliation/Affiliation Editor")]
        private static void OpenWindow() => GetWindow<AffiliationEditor>().Show();

        [ShowInInspector]
        [ReadOnly]
        private List<Faction> _factions = new();
        
        [ShowInInspector]
        [HideReferenceObjectPicker]
        [ListDrawerSettings(HideAddButton = true, HideRemoveButton = true, DraggableItems = false)]
        private List<AffiliationEditorConflict> _conflicts = new();

        [Button]
        private void FindFactions()
        {
            _factions = AssetDatabase
                .FindAssets($"t:{nameof(Faction)}", new[] { "Assets/85 - GameData" })
                .Select(AssetDatabase.GUIDToAssetPath)
                .Select(AssetDatabase.LoadAssetAtPath<Faction>)
                .ToList();
        }

        [Button]
        private void FindConflicts()
        {
            if (_factions.IsNullOrEmpty()) FindFactions();

            _factions.ForEach(thisFaction =>
            {
                _factions.ForEach(otherFaction =>
                {
                    CompareAttitudeConflict(thisFaction, otherFaction);
                });
            });
        }

        private void CompareAttitudeConflict(Faction faction1, Faction faction2)
        {
            var attitude1 = faction1.GetAttitudeFor(faction2);
            var attitude2 = faction2.GetAttitudeFor(faction1);
            if (attitude1 != attitude2) AddConflict(faction1, faction2);
        }

        private void AddConflict(Faction faction1, Faction faction2)
        {
            var conflictExists = _conflicts
                .Where(conflict => conflict.faction1 == faction1 || conflict.faction1 == faction2)
                .Any(conflict => conflict.faction2 == faction1 || conflict.faction2 == faction2);
            if (conflictExists) return;
            _conflicts.Add(new AffiliationEditorConflict { faction1 = faction1, faction2 = faction2 });
        }

        [Button]
        private void ResolveEasyConflicts()
        {
            if (_conflicts.IsNullOrEmpty()) FindConflicts();

            _conflicts.ToList().ForEach(conflict =>
            {
                var attitude1 = conflict.faction1.GetAttitudeFor(conflict.faction2);
                var attitude2 = conflict.faction2.GetAttitudeFor(conflict.faction1);
                if (attitude1.HasValue && attitude2.HasValue) return;
                
                if (attitude1.HasValue)
                {
                    conflict.faction1.factionAttitudes[conflict.faction2] = attitude1.Value;
                    conflict.faction2.factionAttitudes[conflict.faction1] = attitude1.Value;
                }
                
                if (attitude2.HasValue)
                {
                    conflict.faction1.factionAttitudes[conflict.faction2] = attitude2.Value;
                    conflict.faction2.factionAttitudes[conflict.faction1] = attitude2.Value;
                }
                
                EditorUtility.SetDirty(conflict.faction1);
                EditorUtility.SetDirty(conflict.faction2);
                AssetDatabase.SaveAssets();
                
                _conflicts.Remove(conflict);
            });
        }
    }
}