using Cryville.EEW.Report;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Cryville.EEW.Unity.UI {
	class EventOngoingListView : MonoBehaviour {
		public static EventOngoingListView Instance { get; private set; }

		[SerializeField] EventReportView m_currentView;
		[SerializeField] Transform m_listView;

		[SerializeField] EventOngoingView m_prefabEventOngoingView;

		readonly List<ReportViewModel> _displayingReports = new();
		readonly List<EventOngoingView> _displayingViews = new();

		public void Add(ReportViewModel e) {
			_displayingReports.Add(e);

			var child = Instantiate(m_prefabEventOngoingView);
			child.SetViewModel(e);
			child.transform.SetParent(m_listView, false);
			_displayingViews.Add(child);

			SwitchTo(_displayingReports.Count - 1);

			if (_displayingReports.Count > 1) m_listView.gameObject.SetActive(true);
		}
		public void Remove(ReportViewModel e) {
			int index = _displayingReports.IndexOf(e);
			if (index == -1) return;
			_displayingReports.RemoveAt(index);

			var child = m_listView.GetChild(index);
			child.SetParent(null, false);
			Destroy(child.gameObject);
			_displayingViews.RemoveAt(index);

			if (_displayingReports.Count == 0) {
				m_currentView.gameObject.SetActive(false);
				_index = -1;
			}
			else {
				if (_index > index) --_index;
				else if (_index == index) SwitchTo(index % _displayingReports.Count, true);
			}

			if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
		}

		void Awake() {
			if (Instance != null) {
				Destroy(this);
				throw new InvalidOperationException("Duplicate ongoing list view.");
			}
			Instance = this;
		}
		void Start() {
			m_currentView.gameObject.SetActive(false);
		}

		int _index = -1;
		float _tickDown;
		void Update() {
			if (_displayingReports.Count == 0) return;
			_tickDown -= Time.deltaTime;
			if (_tickDown < 0) {
				SwitchTo((_index + 1) % _displayingReports.Count);
			}
		}
		void SwitchTo(int index, bool forced = false) {
			if (!forced && _index == index) return;
			if (_index < _displayingReports.Count && _index != -1)
				_displayingViews[_index].SetCurrent(false);
			_index = index;
			var e = _displayingReports[index];
			m_currentView.SetViewModel(e, true);
			var keyProp = e.Properties.FirstOrDefault();
			_displayingViews[_index].SetCurrent(true);
			_tickDown = MathF.Exp(Math.Max(-1f, keyProp?.Severity ?? -1f) + 1);
			m_currentView.gameObject.SetActive(true);
			Worker.Instance.SetCurrent(e);
		}
		public void OnItemClicked(ReportViewModel viewModel) {
			int index = _displayingReports.IndexOf(viewModel);
			if (index == -1) return;
			SwitchTo(index);
			Worker.Instance.SetSelected(null);
		}
	}
}
