<?php

namespace SugarCalendarBookings\SetupWizard;

use SugarCalendarBookings\Migration\MigrationRegistry;
use SugarCalendarBookings\Migration\MigrationUIConfigInterface;
use SugarCalendarBookings\Migration\SourceAdapterInterface;
use SugarCalendarBookings\Support\Helpers\Helpers;

/**
 * Migration Hydrator.
 *
 * Builds the `migration` data structure for the Setup Wizard `/hydrate` endpoint.
 * Iterates all registered migration sources and collects detection status,
 * entity counts, and entity labels for the external wizard to consume.
 *
 * @since 1.3.1
 */
class MigrationHydrator {

	/**
	 * Migration registry.
	 *
	 * @since 1.3.1
	 *
	 * @var MigrationRegistry
	 */
	private MigrationRegistry $registry;

	/**
	 * Constructor.
	 *
	 * @since 1.3.1
	 *
	 * @param MigrationRegistry $registry Migration registry instance.
	 */
	public function __construct( MigrationRegistry $registry ) {

		$this->registry = $registry;
	}

	/**
	 * Get migration data for hydration.
	 *
	 * Returns the `migration` key structure for the `/hydrate` response.
	 * Iterates all registered sources and builds detection/count data for each.
	 *
	 * @since 1.3.1
	 *
	 * @return array{sources: array<array<string, mixed>>}
	 */
	public function get_data(): array {

		$sources = [];

		foreach ( $this->registry->get_ui_configs() as $source_id => $ui_config ) {
			$adapter = $this->registry->get_adapter( $source_id );

			if ( ! $adapter ) {
				continue;
			}

			$sources[] = $this->build_source_data( $adapter, $ui_config );
		}

		return [
			'sources' => $sources,
		];
	}

	/**
	 * Build data for a single migration source.
	 *
	 * @since 1.3.1
	 *
	 * @param SourceAdapterInterface     $adapter   Source adapter.
	 * @param MigrationUIConfigInterface $ui_config UI config.
	 *
	 * @return array<string, mixed>
	 */
	private function build_source_data( SourceAdapterInterface $adapter, MigrationUIConfigInterface $ui_config ): array {

		$detected = $ui_config->is_available();

		if ( ! $detected ) {
			return [
				'id'            => $adapter->get_id(),
				'name'          => $adapter->get_name(),
				'detected'      => false,
				'has_data'      => false,
				'entity_counts' => [],
				'entities'      => [],
			];
		}

		$entity_counts = $this->get_entity_counts( $adapter );
		$has_data      = $this->has_any_data( $entity_counts );
		$entities      = $this->get_entity_definitions( $ui_config );

		return [
			'id'            => $adapter->get_id(),
			'name'          => $adapter->get_name(),
			'detected'      => true,
			'has_data'      => $has_data,
			'entity_counts' => $entity_counts,
			'entities'      => $entities,
			'support_url'   => Helpers::get_support_url(
				[
					'wpf96206_20' => 'Sugar Calendar Bookings',
					'wpf96206_5'  => 'Bug report or problem',
					'wpf96206_6'  => site_url(),
				]
			),
		];
	}

	/**
	 * Get entity counts from the adapter.
	 *
	 * @since 1.3.1
	 *
	 * @param SourceAdapterInterface $adapter Source adapter.
	 *
	 * @return array<string, int>
	 */
	private function get_entity_counts( SourceAdapterInterface $adapter ): array {

		$counts   = [];
		$entities = $adapter->get_supported_entities();

		foreach ( $entities as $entity_type ) {
			$count = $adapter->count( $entity_type );

			$counts[ $entity_type ] = is_wp_error( $count ) ? 0 : (int) $count;
		}

		return $counts;
	}

	/**
	 * Check if any entity has data.
	 *
	 * @since 1.3.1
	 *
	 * @param array<string, int> $entity_counts Entity counts.
	 *
	 * @return bool
	 */
	private function has_any_data( array $entity_counts ): bool {

		foreach ( $entity_counts as $count ) {
			if ( $count > 0 ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Get entity definitions with keys and labels from UI config.
	 *
	 * @since 1.3.1
	 *
	 * @param MigrationUIConfigInterface $ui_config UI config.
	 *
	 * @return array<array{key: string, label: string}>
	 */
	private function get_entity_definitions( MigrationUIConfigInterface $ui_config ): array {

		$modal_config  = $ui_config->get_modal_config();
		$entity_labels = $modal_config['entity_labels'] ?? [];
		$definitions   = [];

		foreach ( $entity_labels as $key => $label ) {
			$definitions[] = [
				'key'   => $key,
				'label' => $label,
			];
		}

		return $definitions;
	}
}
