using Cryville.EEW.Core;
using Cryville.EEW.Report;
using System.Linq;
using System;
using UnityEngine;
using UnityEngine.UI;

namespace Cryville.EEW.Unity.UI {
	class EventGroupView : EventBaseView {
		[SerializeField] EventUnitListView m_listView;

		[SerializeField] Button m_groupHeader;
		[SerializeField] GameObject m_listViewContainer;
		[SerializeField] GameObject m_listViewRail;
		[SerializeField] GameObject m_expander;

		void Start() {
			m_groupHeader.onClick.AddListener(OnGroupHeaderClicked);
		}
		void OnGroupHeaderClicked() {
			SetExpanded(!m_listViewContainer.activeSelf);
		}
		void SetExpanded(bool expanded) {
			m_listViewContainer.SetActive(expanded);
			m_expander.SetActive(!expanded);
		}

		public void Set(ReportGroup group) {
			int reportCount;
			ReportViewModel[] latestValidReports;
			DateTime latestActiveTime;
			lock (group) {
				m_listView.Set(group);
				reportCount = group.Count;
				latestValidReports = group.Where(u => !u.IsCanceled).Select(u => u.LatestReport).Reverse().ToArray();
				latestActiveTime = group.Max(u => u.LatestActiveTime);
			}
			var mainLocationReport = latestValidReports.OrderByDescending(e => e.LocationSpecificity).FirstOrDefault();
			var mainTimeReport = mainLocationReport?.Time != null ? mainLocationReport : latestValidReports.LastOrDefault(e => e.Time != null);
			var props = latestValidReports
				.SelectMany(e => e.Properties.Select(p => new Localized<ReportViewModelProperty>(p, e.Culture)))
				.GroupBy(p => p.Value.Type)
				.Select(g => g.OrderBy(p => p.Value, DefaultRVMPropertyInnerComparer.Instance).First())
				.ToArray();
			var accuracyOrderThreshold = props.Length == 0 ? int.MaxValue : props.Min(p => p.Value.AccuracyOrder) switch {
				< 40 => 40,
				_ => int.MaxValue,
			};
			props = props
				.OrderBy(p => p.Value, DefaultRVMPropertyOuterComparer.Instance)
				.Where(p => p.Value.AccuracyOrder < accuracyOrderThreshold && DefaultRVMPropertyOuterComparer.Instance.ShouldDisplayInGroup(p.Value))
				.ToArray();

			SetView(
				props.FirstOrDefault().Value?.Severity ?? -1,
				new Localized<string>(mainLocationReport?.Location, mainLocationReport?.Culture),
				new Localized<string>(mainLocationReport?.Predicate, mainLocationReport?.Culture),
				new Localized<DateTime?>(mainTimeReport?.Time, mainTimeReport?.Culture), mainTimeReport?.TimeZone,
				props.FirstOrDefault(),
				props.Skip(1)
			);

			if (mainLocationReport?.Location == null || reportCount <= 1) {
				SetExpanded(true);
				m_listViewRail.SetActive(false);
				m_groupHeader.gameObject.SetActive(false);
			}
			else {
				SetExpanded(DateTime.UtcNow - latestActiveTime < TimeSpan.FromMinutes(5));
				m_listViewRail.SetActive(true);
				m_groupHeader.gameObject.SetActive(true);
			}
		}
	}
}
