<?php

namespace Fotogenic_AI;

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

/**
 * Strict owner-scoped REST boundary for Store Queue orchestration.
 */
final class Rest_Studio_Store_Queue {
	private Service_Store_Queue $service;

	public function __construct( Service_Store_Queue $service ) {
		$this->service = $service;
	}

	public function register_routes( Rest_Router $router ): void {
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/snapshot', [ 'methods' => 'POST', 'callback' => [ $this, 'snapshot' ], 'permission_callback' => [ $router, 'permissions_generate_upload' ] ] );
		$router->register_route(
			'fotogenic-ai/v1',
			'/studio/store-queue/progress',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'progress' ],
				'permission_callback' => [ $router, 'permissions_admin' ],
				'args'                => [
					'queueUuid' => [ 'type' => 'string', 'required' => true ],
					'page'      => [ 'type' => 'integer', 'default' => 1, 'minimum' => 1 ],
					'perPage'   => [ 'type' => 'integer', 'default' => 24, 'minimum' => 1, 'maximum' => 48 ],
					'status'    => [ 'type' => 'string', 'default' => '', 'enum' => [ '', 'ready', 'ineligible', 'reserved', 'admitted', 'review_required', 'completed', 'partial', 'failed', 'skipped', 'uncertain' ] ],
				],
			]
		);
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/start', [ 'methods' => 'POST', 'callback' => [ $this, 'start' ], 'permission_callback' => [ $router, 'permissions_generate_upload' ] ] );
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/pause', [ 'methods' => 'POST', 'callback' => [ $this, 'pause' ], 'permission_callback' => [ $router, 'permissions_admin' ] ] );
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/resume', [ 'methods' => 'POST', 'callback' => [ $this, 'resume' ], 'permission_callback' => [ $router, 'permissions_admin' ] ] );
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/stop', [ 'methods' => 'POST', 'callback' => [ $this, 'stop' ], 'permission_callback' => [ $router, 'permissions_admin' ] ] );
		$router->register_route( 'fotogenic-ai/v1', '/studio/store-queue/active', [ 'methods' => 'GET', 'callback' => [ $this, 'active' ], 'permission_callback' => [ $router, 'permissions_admin' ] ] );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function snapshot( \WP_REST_Request $request ) {
		$envelope = $this->decode_envelope( $request, [ 'queueUuid', 'draft', 'selection' ] );
		return is_wp_error( $envelope ) ? $envelope : $this->no_store( $this->service->snapshot( $envelope, get_current_user_id() ) );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function start( \WP_REST_Request $request ) {
		$not_ready = $this->migration_error();
		if ( is_wp_error( $not_ready ) ) {
			return $not_ready;
		}
		$envelope = $this->decode_envelope( $request, [ 'queueUuid', 'authority', 'allowPartialBalance' ] );
		if ( is_wp_error( $envelope ) ) {
			return $envelope;
		}
		$fields = get_object_vars( $envelope );
		if ( ! is_string( $fields['queueUuid'] ?? null ) || ! ( ( $fields['authority'] ?? null ) instanceof \stdClass ) || ! is_bool( $fields['allowPartialBalance'] ?? null ) ) {
			return Messages::error( 'invalid_request', 400 );
		}
		return $this->no_store( $this->service->start( $fields['queueUuid'], get_current_user_id(), $fields['authority'], $fields['allowPartialBalance'] ) );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function progress( \WP_REST_Request $request ) {
		return $this->no_store(
			$this->service->progress(
				(string) $request->get_param( 'queueUuid' ),
				get_current_user_id(),
				max( 1, (int) $request->get_param( 'page' ) ),
				min( 48, max( 1, (int) $request->get_param( 'perPage' ) ) ),
				(string) $request->get_param( 'status' )
			)
		);
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function pause( \WP_REST_Request $request ) {
		return $this->control( $request, 'pause' );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function resume( \WP_REST_Request $request ) {
		return $this->control( $request, 'resume' );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function stop( \WP_REST_Request $request ) {
		return $this->control( $request, 'stop' );
	}

	/** @return \WP_REST_Response|\WP_Error */
	public function active( \WP_REST_Request $request ) {
		unset( $request );
		return $this->no_store( $this->service->active( get_current_user_id() ) );
	}

	/** @return \WP_REST_Response|\WP_Error */
	private function control( \WP_REST_Request $request, string $action ) {
		$not_ready = $this->migration_error();
		if ( is_wp_error( $not_ready ) ) {
			return $not_ready;
		}
		$envelope = $this->decode_envelope( $request, [ 'queueUuid' ] );
		$fields = is_wp_error( $envelope ) ? [] : get_object_vars( $envelope );
		if ( is_wp_error( $envelope ) || ! is_string( $fields['queueUuid'] ?? null ) ) {
			return is_wp_error( $envelope ) ? $envelope : Messages::error( 'invalid_request', 400 );
		}
		$result = 'pause' === $action
			? $this->service->pause( $fields['queueUuid'], get_current_user_id() )
			: ( 'resume' === $action
				? $this->service->resume( $fields['queueUuid'], get_current_user_id() )
				: $this->service->stop( $fields['queueUuid'], get_current_user_id() ) );
		return $this->no_store( $result );
	}

	/** @return \stdClass|\WP_Error */
	private function decode_envelope( \WP_REST_Request $request, array $expected_fields ) {
		if ( ! $request->is_json_content_type() ) {
			return new \WP_Error( 'fotogenic_ai_studio_json_required', __( 'Store Queue requests must use application/json.', 'fotogenic-ai' ), [ 'status' => 415 ] );
		}
		try {
			$envelope = json_decode( $request->get_body(), false, 64, JSON_THROW_ON_ERROR );
		} catch ( \JsonException $exception ) {
			unset( $exception );
			return new \WP_Error( 'fotogenic_ai_invalid_studio_json', __( 'The Store Queue JSON is invalid.', 'fotogenic-ai' ), [ 'status' => 400 ] );
		}
		if ( ! $envelope instanceof \stdClass ) {
			return Messages::error( 'invalid_request', 400 );
		}
		$actual = array_keys( get_object_vars( $envelope ) );
		sort( $actual, SORT_STRING );
		sort( $expected_fields, SORT_STRING );
		return $actual === $expected_fields ? $envelope : Messages::error( 'invalid_request', 400 );
	}

	/** @param mixed $value */
	private function no_store( $value ) {
		if ( is_wp_error( $value ) ) {
			return $value;
		}
		$response = rest_ensure_response( $value );
		$response->header( 'Cache-Control', 'no-store, no-cache, must-revalidate' );
		return $response;
	}

	private function migration_error(): ?\WP_Error {
		$migration = Universal_Data_Migration::instance();
		return $migration->is_ready() ? null : $migration->readiness_error();
	}
}
