<?php
/**
 * Custom capabilities for AI Alt Text.
 *
 * @package AIAltTextGenerator
 * @since 1.4.0
 */

namespace AIAltTextGenerator;

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

/**
 * @since 1.4.0
 */
class Capabilities {

	public const GENERATE = 'wpps_ai_alt_generate';
	public const MANAGE   = 'wpps_ai_alt_manage';
	public const VIEW     = 'wpps_ai_alt_view';

	public static function register(): void {
		$settings  = Settings::get();
		$role_caps = self::normalizeRoleCaps( $settings['role_caps'] ?? [] );

		$all_roles = wp_roles()->roles;
		foreach ( array_keys( $all_roles ) as $role_slug ) {
			$role = get_role( $role_slug );
			if ( ! $role ) {
				continue;
			}

			$role->remove_cap( self::GENERATE );
			$role->remove_cap( self::MANAGE );
			$role->remove_cap( self::VIEW );

			if ( in_array( $role_slug, $role_caps['generate'], true ) ) {
				$role->add_cap( self::GENERATE );
			}
			if ( in_array( $role_slug, $role_caps['view'], true ) ) {
				$role->add_cap( self::VIEW );
			}
			if ( in_array( $role_slug, $role_caps['manage'], true ) ) {
				$role->add_cap( self::MANAGE );
				$role->add_cap( self::VIEW );
			}
		}
	}

	/**
	 * @param array<string, mixed> $role_caps
	 * @return array{generate: list<string>, view: list<string>, manage: list<string>}
	 */
	public static function normalizeRoleCaps( array $role_caps ): array {
		$defaults = self::defaultRoleCaps();
		$valid    = array_keys( wp_roles()->roles );

		$normalize = static function ( $roles, array $fallback ) use ( $valid ): array {
			if ( ! is_array( $roles ) ) {
				return $fallback;
			}
			$roles = array_values( array_unique( array_filter( array_map( 'sanitize_key', $roles ) ) ) );
			return array_values( array_intersect( $roles, $valid ) ) ?: $fallback;
		};

		return [
			'generate' => $normalize( $role_caps['generate'] ?? null, $defaults['generate'] ),
			'view'     => $normalize( $role_caps['view'] ?? null, $defaults['view'] ),
			'manage'   => $normalize( $role_caps['manage'] ?? null, $defaults['manage'] ),
		];
	}

	/** @return array{generate: list<string>, view: list<string>, manage: list<string>} */
	public static function defaultRoleCaps(): array {
		return [
			'generate' => [ 'administrator', 'editor', 'author' ],
			'view'     => [ 'administrator', 'editor' ],
			'manage'   => [ 'administrator' ],
		];
	}

	public static function canGenerate(): bool {
		return current_user_can( self::GENERATE );
	}

	public static function canManage(): bool {
		return current_user_can( self::MANAGE ) || current_user_can( 'manage_options' );
	}

	public static function canView(): bool {
		return current_user_can( self::VIEW ) || self::canManage();
	}
}
