﻿using System;
using System.Runtime.CompilerServices;
using System.Text;
using JLGames.RocketDriver.Actions.Utils;
using JLGames.RocketDriver.CSharp.Event;
using JLGames.RocketDriver.Games.RpgMaterial;
using JLGames.RocketDriver.Games.RpgMaterial.Common;
using JLGames.RocketDriver.Games.RpgMaterial.Service;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service;
using UnityEngine;
using UnityEngine.UI;

namespace JLGames.RocketDriver.Samples.RpgMaterialDemo.UI.GM
{
    public class GmPanelMateriaTrigger : MonoBehaviour
    {
        [Serializable]
        public class TestCase
        {
            public int Type;
            public int Id;
            public bool Post;
            public int Times = -1;
            public Trigger.TrackingType TkType;
            public Trigger.CompareType CpType;
            public int CpValue;
            [NonSerialized] public int TriggerId = -1;

            public TestCase Clone()
            {
                return new TestCase {Type = Type, Id = Id, Post = Post, Times = Times, TkType = TkType, CpType = CpType, CpValue = CpValue};
            }

            public override string ToString()
            {
                return $"{TriggerId}:{TkType}_{Post}_{Times}:{Type}_{Id}_{CpType}_{CpValue}";
            }
        }

        [SerializeField] private Text m_MaterialTrigger;

        [SerializeField] private TestCase[] m_TestCases =
        {
            new TestCase {Type = 1, Id = 1001, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Equal, CpValue = 1001}, //Test Succ
            new TestCase {Type = 1, Id = 1002, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.NotEqual, CpValue = 1001}, //Test Succ

            new TestCase {Type = 2, Id = 2001, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Equal, CpValue = 2001}, //Test Succ
            new TestCase {Type = 2, Id = 2002, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.NotEqual, CpValue = 2002}, //Test Succ
            new TestCase {Type = 2, Id = 2003, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Greater, CpValue = 2003}, //Test Succ
            new TestCase {Type = 2, Id = 2004, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Less, CpValue = 2004}, //Test Succ
            new TestCase {Type = 2, Id = 2005, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.GreaterEqual, CpValue = 2005}, //Test Succ
            new TestCase {Type = 2, Id = 2006, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.LessEqual, CpValue = 2006}, //Test Succ
            new TestCase {Type = 3, Id = 3001, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Equal, CpValue = 3001}, //Test Succ
            new TestCase {Type = 3, Id = 3002, TkType = Trigger.TrackingType.Value, CpType = Trigger.CompareType.Equal, CpValue = 3002}, //Test Succ

            new TestCase {Type = 2, Id = 2007, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.Equal, CpValue = 101}, //Test Succ
            new TestCase {Type = 2, Id = 2008, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.NotEqual, CpValue = 102}, //Test Succ
            new TestCase {Type = 2, Id = 2009, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.Greater, CpValue = 103}, //Test Succ
            new TestCase {Type = 2, Id = 2010, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.Less, CpValue = 104}, //Test Succ
            new TestCase {Type = 2, Id = 2011, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.GreaterEqual, CpValue = 105}, //Test Succ
            new TestCase {Type = 2, Id = 2012, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.LessEqual, CpValue = 106}, //Test Succ
            new TestCase {Type = 3, Id = 3003, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.Equal, CpValue = 107}, //Test Succ
            new TestCase {Type = 3, Id = 3004, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.Equal, CpValue = 108}, //Test Succ
            new TestCase {Type = 3, Id = 3005, TkType = Trigger.TrackingType.Offset, CpType = Trigger.CompareType.NotEqual, CpValue = 109}, //Test Succ
        };

        private readonly StringBuilder m_SbTrigger = new StringBuilder();

        private void Awake()
        {
            var arr = new TestCase[m_TestCases.Length * 2];
            for (var index = 0; index < m_TestCases.Length; index++)
            {
                var newIndex = index * 2;
                arr[newIndex] = m_TestCases[index];
                var clone = m_TestCases[index].Clone();
                clone.Post = true;
                clone.Times = 2;
                arr[newIndex + 1] = clone;
            }

            m_TestCases = arr;
        }

        private void OnEnable()
        {
            foreach (var testCase in m_TestCases)
            {
                var service = ServiceCenter.GetMaterialService(testCase.Type);
                var triggerId = service.RegisterTrigger(testCase.TkType, testCase.Type, testCase.Id, testCase.CpType, testCase.CpValue
                    , TriggerInvoker, testCase.Post, testCase.Times);
                if (-1 != triggerId)
                {
                    testCase.TriggerId = triggerId;
                }
            }
        }

        private void OnDisable()
        {
            foreach (var testCase in m_TestCases)
            {
                var service = ServiceCenter.GetMaterialService(testCase.Type);
                if (-1 != testCase.TriggerId)
                {
                    service.UnregisterTrigger(testCase.TriggerId);
                }
            }
        }

        private void TriggerInvoker(ITriggerEntity trigger, UserNotifyData data)
        {
            var testCase = FindCaseFromTrigger(trigger.TriggerId);
            m_SbTrigger.Insert(0, $"{testCase}|{data}\n");
            m_MaterialTrigger.text = m_SbTrigger.ToString();
        }

        private TestCase FindCaseFromTrigger(int triggerId)
        {
            return Array.Find(m_TestCases, (tCase => tCase.TriggerId == triggerId));
        }

        public void OnClickClearTriggerLog()
        {
            m_SbTrigger.Clear();
            m_MaterialTrigger.text = "";
        }
    }
}