/*
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC.
 */

using System.Collections.ObjectModel;

using Syncfusion.Maui.TreeView;
using Syncfusion.TreeView.Engine;

using DXLib.UI;
using DXLib.UI.Alert;

using DXLib.Data;
using DXLib.Utils;

namespace iStatVball3;

/*
 * An SfTreeView used to display a hierarchical tree of help video tutorials.
 */
public class HelpTree : SfTreeView
{
	/* Fields */
	private HelpPlayer player;

	/* Methods */
	public HelpTree()
	{
		// Populate on demand
		NotificationSubscriptionMode = TreeViewNotificationSubscriptionMode.PropertyChange;
		NodePopulationMode = TreeNodePopulationMode.OnDemand;

		// Manual expand, animated
		ExpanderPosition = TreeViewExpanderPosition.Start;
		ExpandActionTarget = TreeViewExpandActionTarget.Node;
		AutoExpandMode = TreeViewAutoExpandMode.None;
		IsAnimationEnabled = true;

		// Single select
		SelectionMode = TreeViewSelectionMode.Single;
		SelectionBackground = DXColors.Light2;

		// Custom expand/collapse icons
		ExpanderWidth = 0;

		// Custom sizing
		ItemHeight = 35;
		Indentation = 20;

		ChildPropertyName = "SubData";

		// Custom data
		ItemTemplateContextType = ItemTemplateContextType.Node;
		ItemTemplate = new HelpTreeSelector();

		// Event handling
		Loaded += OnLoaded;
		SelectionChanged += OnSelectionChanged;
	}

	// Post-construction initialization
	public void Init()
	{
		ObservableCollection<HelpTreeData> data = [];

		// Read external strings
		List<DXItem> items = DXString.GetLookupList( "help" );

		// Populate root level
		foreach ( DXItem item in items )
		{
			string key = item.Key;

			// Root node
			HelpTreeData node = new()
			{
				Tree = this,
				Name = item.Value,
				SubData = []
			};

			List<DXItem> subItems = DXString.GetLookupList( $"help.{key}" );

			// Populate second level
			foreach ( DXItem subItem in subItems )
			{
				string subKey = subItem.Key;

				List<DXItem> subSubItems = DXString.GetLookupList( $"help.{key}.{subKey}" );

				// Might have third level
				if ( subSubItems.Count > 0 )
				{
					HelpTreeData subNode = new()
					{
						Tree = this,
						Name = subItem.Value,
						SubData = []
					};

					// Populate leaf topics
					foreach ( DXItem subSubItem in subSubItems )
					{
						HelpTreeData subSubNode = CreateTopic( $"{key}.{subKey}", subSubItem );

						subNode.SubData.Add( subSubNode );
					}

					node.SubData.Add( subNode );
				}
				// Populate leaf topic
				else
				{
					HelpTreeData subNode = CreateTopic( key, subItem );

					node.SubData.Add( subNode );
				}
			}

			data.Add( node );
		}

		ItemsSource = data;
	}

	// Creates leaf level help topic for specified key
	private HelpTreeData CreateTopic( string baseKey, DXItem item )
	{
		string key = $"{baseKey}.{item.Key}";
		string[] tokens = item.Value.Split( "|" );

		// Create leaf node
		HelpTreeData data = new()
		{
			Tree = this,

			Key = key,
			Viewed = Shell.CurrentUser.Help.Contains( key ),

			Name = tokens[0],
			Duration = tokens[1]
		};

		if ( tokens.Length > 2 )
		{
			data.VideoId = tokens[2];
			data.VideoSig = tokens[3];
		}

		return data;
	}

	// Handles topic selection
	public void HandleSelect( HelpTreeData data )
	{
		// Requires network connection
		if ( DXData.HasConnection() )
		{
			// Start video (leaf topics only)
			if ( data.SubData == null )
			{
				// Reusable video player
				player = new HelpPlayer
				{
					Closed = OnPlayerClosed
				};

				player.Show( data );
			}
		}
		else
		{
			DXAlert.ShowNetworkError( "net.err.help" );
		}
	}

	/* Event Callbacks */

	// Expands first node once tree loaded
	private void OnLoaded( object sender, TreeViewLoadedEventArgs args )
	{
		ExpandNode( Nodes[0] );
	}

	// User selected category/topic
	private void OnSelectionChanged( object sender, ItemSelectionChangedEventArgs args )
	{
		if ( args.AddedItems != null )
		{
			HelpTreeData data = args.AddedItems[0] as HelpTreeData;

			HandleSelect( data );
		}
	}

	// Reset selection after video closed/ends
	private void OnPlayerClosed()
	{
		SelectedItems.Clear();

		// Update viewed icon
		if ( DXDevice.IsAndroid )
		{
			RefreshView();
		}
	}
}

//
