<?php

declare(strict_types=1);

namespace AllCoach\API\Controllers\V1;

defined( 'ABSPATH' ) || exit;

use AllCoach\API\RestController;
use AllCoach\Modules\ModuleRegistry;

class ModulesController extends RestController {

	protected string $restBase = 'modules';

	public function __construct(
		private readonly ModuleRegistry $moduleRegistry
	) {
	}

	public function registerRoutes(): void {
		register_rest_route(
			$this->namespace,
			'/' . $this->restBase,
			[
				[
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => [ $this, 'getModules' ],
					'permission_callback' => fn() => $this->checkPermission( null, 'manage_options' ),
				],
			]
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->restBase . '/(?P<id>[a-zA-Z0-9_-]+)',
			[
				[
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => [ $this, 'getModule' ],
					'permission_callback' => fn() => $this->checkPermission( null, 'manage_options' ),
				],
			]
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->restBase . '/(?P<id>[a-zA-Z0-9_-]+)/enable',
			[
				[
					'methods'             => \WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'enableModule' ],
					'permission_callback' => fn() => $this->checkPermission( null, 'manage_options' ),
				],
			]
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->restBase . '/(?P<id>[a-zA-Z0-9_-]+)/disable',
			[
				[
					'methods'             => \WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'disableModule' ],
					'permission_callback' => fn() => $this->checkPermission( null, 'manage_options' ),
				],
			]
		);
	}


	public function getModules( \WP_REST_Request $request ): \WP_REST_Response {
		$allModules     = $this->moduleRegistry->getAllModules();
		$enabledModules = get_option( '_allcoach_enabled_modules', [] );

		$modules = [];
		foreach ( $allModules as $id => $module ) {
			$modules[] = $this->prepareModule( $id, $module, in_array( $id, $enabledModules, true ) );
		}

		return $this->successResponse( [ 'modules' => $modules ] );
	}

	public function getModule( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
		$id = $request->get_param( 'id' );

		if ( ! $this->moduleRegistry->hasModule( $id ) ) {
			return $this->errorResponse( 'Module not found', 404 );
		}

		$module         = $this->moduleRegistry->getModule( $id );
		$enabledModules = get_option( '_allcoach_enabled_modules', [] );
		$isEnabled      = in_array( $id, $enabledModules, true );

		return $this->successResponse( $this->prepareModule( $id, $module, $isEnabled ) );
	}

	public function enableModule( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
		$id = $request->get_param( 'id' );

		if ( ! $this->moduleRegistry->hasModule( $id ) ) {
			return $this->errorResponse( 'Module not found', 404 );
		}

		$enabledModules = get_option( '_allcoach_enabled_modules', [] );

		if ( ! in_array( $id, $enabledModules, true ) ) {
			$enabledModules[] = $id;
			update_option( '_allcoach_enabled_modules', $enabledModules );
		}

		$module = $this->moduleRegistry->getModule( $id );

		return $this->successResponse(
			[
				'message' => sprintf( 'Module "%s" enabled successfully', $id ),
				'module'  => $this->prepareModule( $id, $module, true ),
			]
		);
	}

	public function disableModule( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
		$id = $request->get_param( 'id' );

		if ( ! $this->moduleRegistry->hasModule( $id ) ) {
			return $this->errorResponse( 'Module not found', 404 );
		}

		$enabledModules = get_option( '_allcoach_enabled_modules', [] );
		$enabledModules = array_filter( $enabledModules, fn( $moduleId ) => $moduleId !== $id );

		update_option( '_allcoach_enabled_modules', array_values( $enabledModules ) );

		$module = $this->moduleRegistry->getModule( $id );

		return $this->successResponse(
			[
				'message' => sprintf( 'Module "%s" disabled successfully', $id ),
				'module'  => $this->prepareModule( $id, $module, false ),
			]
		);
	}

	private function prepareModule( string $id, $module, bool $isEnabled ): array {
		return [
			'id'          => $id,
			'name'        => $module->getName(),
			'description' => $module->getDescription(),
			'version'     => $module->getVersion(),
			'enabled'     => $isEnabled,
		];
	}
}
