<?php

namespace Fotogenic_AI;

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

final class Rest_Studio_Bulk {
    private Service_Bulk $service;

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

    public function register_routes( Rest_Router $router ): void {
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/snapshot',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'snapshot' ],
                'permission_callback' => [ $router, 'permissions_generate_upload' ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/start',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'start' ],
                'permission_callback' => [ $router, 'permissions_generate_upload' ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/progress',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'progress' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
					'runUuid' => [
                        'type'     => 'string',
                        'required' => true,
                    ],
                ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/pause',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'pause' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
					'runUuid' => [
                        'type'     => 'string',
                        'required' => true,
                    ],
                ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/resume',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'resume' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
					'runUuid' => [
                        'type'     => 'string',
                        'required' => true,
                    ],
                ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/stop',
            [
                'methods'             => 'POST',
                'callback'            => [ $this, 'stop' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
					'runUuid' => [
                        'type'     => 'string',
                        'required' => true,
                    ],
                ],
            ]
        );
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/bulk/active',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'active' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
            ]
        );
    }

    /**
     * Decode the temporary universal Bulk envelope without REST schema coercion.
     *
     * @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;
        }
        if ( ! $request->is_json_content_type() ) {
            return new \WP_Error(
                'fotogenic_ai_studio_json_required',
                __( 'Studio Bulk 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 Studio Bulk JSON is invalid.', 'fotogenic-ai' ),
                [ 'status' => 400 ]
            );
        }
        if ( ! ( $envelope instanceof \stdClass ) ) {
            return Messages::error( 'invalid_request', 400 );
        }
        $fields = get_object_vars( $envelope );
		if (
			[ 'draft', 'runUuid', 'snapshotFingerprint', 'authority' ] !== array_values( array_intersect( [ 'draft', 'runUuid', 'snapshotFingerprint', 'authority' ], array_keys( $fields ) ) )
			|| 4 !== count( $fields )
			|| ! is_string( $fields['runUuid'] ?? null )
			|| ! is_string( $fields['snapshotFingerprint'] ?? null )
			|| ! ( ( $fields['draft'] ?? null ) instanceof \stdClass )
			|| ! ( ( $fields['authority'] ?? null ) instanceof \stdClass )
		) {
			return new \WP_Error(
				'fotogenic_ai_invalid_bulk_envelope',
				__( 'Studio Bulk requires one runUuid, one snapshot fingerprint, one authority proof, and one draft object.', 'fotogenic-ai' ),
                [ 'status' => 400 ]
            );
        }
		return $this->service->start( $fields['runUuid'], $fields['draft'], $fields['snapshotFingerprint'], $fields['authority'] );
    }

    /**
     * Decode one strict, non-billable Bulk snapshot request.
     *
     * @return \WP_REST_Response|\WP_Error
     */
    public function snapshot( \WP_REST_Request $request ) {
        if ( ! $request->is_json_content_type() ) {
            return new \WP_Error(
                'fotogenic_ai_studio_json_required',
                __( 'Studio Bulk snapshot 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 Studio Bulk snapshot JSON is invalid.', 'fotogenic-ai' ),
                [ 'status' => 400 ]
            );
        }
        if ( ! ( $envelope instanceof \stdClass ) ) {
            return Messages::error( 'invalid_request', 400 );
        }
        $fields = get_object_vars( $envelope );
        if ( [ 'draft' ] !== array_keys( $fields ) || ! ( $fields['draft'] instanceof \stdClass ) ) {
            return new \WP_Error(
                'fotogenic_ai_invalid_bulk_snapshot_envelope',
                __( 'Studio Bulk snapshot requires exactly one draft object.', 'fotogenic-ai' ),
                [ 'status' => 400 ]
            );
        }

        return $this->service->snapshot( $fields['draft'] );
    }

    /** @return \WP_REST_Response|\WP_Error */
    public function progress( \WP_REST_Request $request ) {
		return $this->service->progress( (string) $request->get_param( 'runUuid' ), get_current_user_id() );
    }
    /** @return \WP_REST_Response|\WP_Error */
    public function pause( \WP_REST_Request $request ) {
        $not_ready = $this->migration_error();
        if ( is_wp_error( $not_ready ) ) {
            return $not_ready;
        }
		return $this->service->pause( (string) $request->get_param( 'runUuid' ), get_current_user_id() );
    }
    /** @return \WP_REST_Response|\WP_Error */
    public function resume( \WP_REST_Request $request ) {
        $not_ready = $this->migration_error();
        if ( is_wp_error( $not_ready ) ) {
            return $not_ready;
        }
		return $this->service->resume( (string) $request->get_param( 'runUuid' ), get_current_user_id() );
    }
    /** @return \WP_REST_Response|\WP_Error */
    public function stop( \WP_REST_Request $request ) {
        $not_ready = $this->migration_error();
        if ( is_wp_error( $not_ready ) ) {
            return $not_ready;
        }
		return $this->service->stop( (string) $request->get_param( 'runUuid' ), get_current_user_id() );
    }
    /** @return \WP_REST_Response|\WP_Error */
    public function active( \WP_REST_Request $request ) {
		unset( $request );
		return $this->service->active( get_current_user_id() );
    }

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