<?php
/**
 * Setup Wizard Service.
 *
 * Handles all business logic for the setup wizard including
 * step saving, state retrieval, and setup completion.
 *
 * @package RadiusTheme\RadiusBooking\Services
 * @since 1.0.0
 */

namespace RadiusTheme\RadiusBooking\Services;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use RadiusTheme\RadiusBooking\Common\Keys;
use RadiusTheme\RadiusBooking\Core\Container\Container;
use RadiusTheme\RadiusBooking\Repositories\SettingsRepository;
use RadiusTheme\RadiusBooking\Repositories\UserRepository;

/**
 * Class SetupWizardService
 */
class SetupWizardService {

	/**
	 * Settings repository instance.
	 *
	 * @var SettingsRepository
	 */
	private SettingsRepository $settingsRepo;

	/**
	 * Map of wizard step names to settings sections.
	 *
	 * @var array
	 */
	private array $step_section_map = array(
		'business'    => array( 'business' ),
		'currency'    => array( 'currency' ),
		'schedule'    => array( 'weeklySchedule' ),
		'appointment' => array( 'dateTime', 'statuses' ),
		'modules'     => array( 'modules' ),
	);

	/**
	 * Constructor.
	 *
	 * @param SettingsRepository $settingsRepo Settings repository.
	 */
	public function __construct( SettingsRepository $settingsRepo ) {
		$this->settingsRepo = $settingsRepo;
	}

	/**
	 * Check if setup wizard has been completed.
	 *
	 * @return bool
	 */
	public function isSetupCompleted(): bool {
		return (bool) get_option( Keys::RADIUS_BOOKING_SETUP_COMPLETED, false );
	}

	/**
	 * Get current wizard state with all relevant settings.
	 *
	 * @return array
	 */
	public function getWizardState(): array {
		return array(
			'setup_completed' => $this->isSetupCompleted(),
			'business'        => $this->settingsRepo->getSection( 'business' ),
			'currency'        => $this->settingsRepo->getSection( 'currency' ),
			'weeklySchedule'  => $this->settingsRepo->getSection( 'weeklySchedule' ),
			'dateTime'        => $this->settingsRepo->getSection( 'dateTime' ),
			'statuses'        => $this->settingsRepo->getSection( 'statuses' ),
			'modules'         => $this->settingsRepo->getSection( 'modules' ),
		);
	}

	/**
	 * Save a single wizard step's data.
	 *
	 * Uses deep merge to preserve existing settings when re-running the wizard.
	 *
	 * @param string $step The wizard step identifier.
	 * @param array  $data The step data to save.
	 *
	 * @return bool Whether the step was saved successfully.
	 */
	public function saveStep( string $step, array $data ): bool {
		if ( ! isset( $this->step_section_map[ $step ] ) ) {
			return false;
		}

		$sections = $this->step_section_map[ $step ];

		foreach ( $sections as $section ) {
			if ( isset( $data[ $section ] ) ) {
				$current = $this->settingsRepo->getSection( $section );
				$merged  = array_replace_recursive( $current ?? array(), $data[ $section ] );
				$this->settingsRepo->saveSection( $section, $merged );
			}
		}

		return true;
	}

	/**
	 * Create the current admin user as a staff member.
	 *
	 * @return array Result with staff info or error details.
	 */
	public function createAdminAsStaff(): array {
		$current_user = wp_get_current_user();

		if ( ! $current_user || ! $current_user->ID ) {
			return array(
				'success' => false,
				'message' => __( 'No authenticated user found.', 'radius-booking' ),
			);
		}

		$user_repo    = Container::resolve( UserRepository::class );
		$user_service = Container::resolve( UserService::class );

		// Check if this admin already exists as employee.
		$existing = $user_repo->findByEmail( $current_user->user_email );
		if ( $existing ) {
			// Ensure the WP user also has the employee role (supports multiple roles).
			$current_user->add_role( 'radius_booking_employee' );

			return array(
				'success' => true,
				'message' => __( 'Staff member already exists.', 'radius-booking' ),
				'user_id' => $existing->get_id(),
			);
		}

		$user_data = array(
			'email'      => $current_user->user_email,
			'user_type'  => 'employee',
			'status'     => 'active',
			'first_name' => $current_user->first_name ?: $current_user->display_name,
			'last_name'  => $current_user->last_name ?: '',
			'wp_user_id' => $current_user->ID,
		);

		$user_id = $user_service->createUser( $user_data );

		if ( is_array( $user_id ) && isset( $user_id['error'] ) ) {
			return array(
				'success' => false,
				'message' => $user_id['error'],
			);
		}

		// Add the employee role to the WP user without removing existing roles (e.g. administrator).
		$current_user->add_role( 'radius_booking_employee' );

		return array(
			'success' => true,
			'message' => __( 'Staff member created successfully.', 'radius-booking' ),
			'user_id' => $user_id,
		);
	}

	/**
	 * Mark setup wizard as complete.
	 *
	 * @return bool
	 */
	public function completeSetup(): bool {
		return update_option( Keys::RADIUS_BOOKING_SETUP_COMPLETED, true );
	}
}