using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Net.Eagle0.Eagle.Common;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace eagle {
    public class ChronicleCanvasController : MonoBehaviour, IClientTextListener {
        public TMP_Text titleText;
        public TMP_Text dateText;
        public TMP_Text contentText;
        public Button previousButton;
        public Button nextButton;

        private Date _lastDismissedDate;

        private int _currentIndex = 0;

        private List<ChronicleEntry> _entries = new();

        private ChronicleEntry CurrentEntry => _entries[_currentIndex];

        public void OnTextUpdate(string text, bool completed) { SetUp(); }

        public string TextId() { return CurrentEntry.GeneratedTextId; }

        private void OnEnable() {
            ClientTextProvider.Provider.AddListener(this);
            SetUp();
        }

        private void OnDisable() { ClientTextProvider.Provider.RemoveListener(this); }

        private void ScrollToTop() {
            contentText.GetComponentInParent<ScrollRect>(includeInactive: true).normalizedPosition =
                    new Vector2(0, 1);
        }

        public IList<ChronicleEntry> Entries {
            get => _entries;
            set {
                _entries = value != null ? value.ToList() : new List<ChronicleEntry>();

                if (_entries.Count == 0) return;

                if (!gameObject.activeSelf) {
                    _currentIndex = _entries.Count - 1;

                    ScrollToTop();
                }

                SetUp();
                if (_entries.Count > 1 && !_entries.Last().Date.Equals(_lastDismissedDate)) {
                    gameObject.SetActive(true);
                }
            }
        }

        private const string TitleSplitPattern = @"\n\s*=====\s*\n";
        private void SetUp() {
            previousButton.interactable = _currentIndex > 0;
            nextButton.interactable = _currentIndex < _entries.Count - 1;

            var currentTextEntry =
                    ClientTextProvider.Provider.GetTextEntry(CurrentEntry.GeneratedTextId);
            var currentEntryText = currentTextEntry == null ? "" : currentTextEntry.Text;

            dateText.text = DisplayNames.DateString(CurrentEntry.Date);

            var patternLocation = Regex.Match(currentEntryText, TitleSplitPattern);

            if (patternLocation.Success) {
                titleText.text = currentEntryText.Substring(0, patternLocation.Index).Trim();
                contentText.text =
                        currentEntryText.Substring(patternLocation.Index + patternLocation.Length)
                                .Trim();
            } else {
                titleText.text = currentEntryText.Trim().TrimEnd('=');
                dateText.text = DisplayNames.DateString(CurrentEntry.Date);
                contentText.text = "";
            }
        }

        public void DismissButtonClicked() {
            _lastDismissedDate = _entries.Last().Date;
            gameObject.SetActive(false);
        }

        public void PreviousButtonClicked() {
            _currentIndex--;
            SetUp();
            ScrollToTop();
        }

        public void NextButtonClicked() {
            _currentIndex++;
            SetUp();
            ScrollToTop();
        }

        public void ClipboardButtonClicked() {
            TextEditor editor = (TextEditor)GUIUtility.GetStateObject(
                    typeof(TextEditor),
                    GUIUtility.keyboardControl);
            editor.text =
                    ClientTextProvider.Provider.GetTextEntry(CurrentEntry.GeneratedTextId).Text;
            editor.SelectAll();
            editor.Copy();
        }
    }
}
