<?php

namespace NeurogenesisTheme\QuickSetup;

use NeurogenesisTheme\Helpers\DashboardResources;
use NeurogenesisTheme\Helpers\RecommendedPlugin;
use NeurogenesisTheme\QuickSetup\Steps\ConnectLicense;
use NeurogenesisTheme\QuickSetup\Steps\CustomizeTheme;
use NeurogenesisTheme\QuickSetup\Steps\InstallCompanionPlugin;
use NeurogenesisTheme\QuickSetup\Steps\PublishFirstPage;

defined( 'ABSPATH' ) || exit;

/**
 * Quick Setup checklist for the Thinko admin dashboard.
 */
final class QuickSetup {

	private static ?self $instance = null;

	/** @var list<Step> */
	private array $steps = array();

	private bool $defaults_registered = false;

	public static function instance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * @param Step|class-string<Step> $step
	 */
	public function add_step( Step|string $step ): self {
		if ( is_string( $step ) ) {
			if ( ! is_subclass_of( $step, Step::class ) ) {
				throw new \InvalidArgumentException(
					sprintf( 'Quick setup step must extend %s.', Step::class )
				);
			}

			$step = new $step();
		}

		$this->steps[] = $step;

		return $this;
	}

	public function remove_step( string $id ): self {
		$this->steps = array_values(
			array_filter(
				$this->steps,
				static function ( Step $step ) use ( $id ): bool {
					return $step->id() !== $id;
				}
			)
		);

		return $this;
	}

	/**
	 * @return list<Step>
	 */
	public function get_steps(): array {
		$this->register_default_steps();

		return $this->steps;
	}

	/**
	 * @return array{completed:int,total:int,percent:int,steps:array<int, array{id:string,label:string,completed:bool,url:string,clickable:bool}>}
	 */
	public static function get_progress(): array {
		return self::instance()->resolve_progress();
	}

	/**
	 * @return array{completed:int,total:int,percent:int,steps:array<int, array{id:string,label:string,completed:bool,url:string,clickable:bool}>}
	 */
	public function resolve_progress(): array {
		$steps = array_map(
			static function ( Step $step ): array {
				return $step->to_array();
			},
			$this->get_steps()
		);

		$steps = (array) apply_filters( 'neurogenesis_theme_quick_setup_steps', $steps );

		$total     = count( $steps );
		$completed = count(
			array_filter(
				$steps,
				static function ( array $step ): bool {
					return ! empty( $step['completed'] );
				}
			)
		);

		$percent = $total > 0 ? (int) round( ( $completed / $total ) * 100 ) : 0;

		return array(
			'completed' => $completed,
			'total'     => $total,
			'percent'   => $percent,
			'steps'     => $steps,
		);
	}

	/**
	 * @deprecated Use DashboardResources::all() instead.
	 * @return array<int, array{id:string,title:string,description:string,url:string,icon:string}>
	 */
	public static function get_resources(): array {
		return DashboardResources::all();
	}

	public static function companion_slug(): string {
		return (string) apply_filters( 'neurogenesis_theme_companion_plugin_slug', RecommendedPlugin::SLUG );
	}

	/**
	 * Whether license UI and quick-setup step are shown.
	 */
	public static function license_is_enabled(): bool {
		return (bool) apply_filters( 'neurogenesis_theme_license_enabled', NEUROGENESIS_THEME_LICENSE_ENABLED );
	}

	public static function license_is_active(): bool {
		if ( ! self::license_is_enabled() ) {
			return false;
		}

		return (bool) apply_filters( 'neurogenesis_theme_license_is_active', false );
	}

	private function register_default_steps(): void {
		if ( $this->defaults_registered ) {
			return;
		}

		$this->defaults_registered = true;

		$this->add_step( InstallCompanionPlugin::class );

		if ( self::license_is_enabled() ) {
			$this->add_step( ConnectLicense::class );
		}

		$this->add_step( CustomizeTheme::class )
			->add_step( PublishFirstPage::class );

		/**
		 * Register additional quick setup steps.
		 *
		 * @param QuickSetup $quick_setup Quick setup registry.
		 */
		do_action( 'neurogenesis_theme_quick_setup_register', $this );
	}
}
