<?php

namespace Fotogenic_AI;

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

/**
 * REST handler for Studio Media Library target list and summary.
 */
final class Rest_Studio_Media {
    private MediaQueryAdapter $media_query_adapter;

    public function __construct( MediaQueryAdapter $media_query_adapter ) {
        $this->media_query_adapter = $media_query_adapter;
    }

    public function register_routes( Rest_Router $router ): void {
        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/media',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'handle_media_list' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
                    'q' => [
                        'type'    => 'string',
                        'default' => '',
                    ],
                    'page' => [
                        'type'    => 'integer',
                        'default' => 1,
                    ],
                    'perPage' => [
                        'type'    => 'integer',
                        'default' => 6,
                    ],
                    'type' => [
                        'type'    => 'string',
                        'default' => 'all',
                        'enum'    => [ 'all', 'jpg', 'png', 'webp' ],
                    ],
                    'date' => [
                        'type'    => 'string',
                        'default' => 'all',
                        'enum'    => [ 'all', 'today', 'week', 'month', 'older' ],
                    ],
                    'orientation' => [
                        'type'    => 'string',
                        'default' => 'all',
                        'enum'    => [ 'all', 'square', 'landscape', 'portrait' ],
                    ],
                    'size' => [
                        'type'    => 'string',
                        'default' => 'all',
                        'enum'    => [ 'all', 'under_300kb', '300kb_and_over' ],
                    ],
                ],
            ]
        );

        $router->register_route(
            'fotogenic-ai/v1',
            '/studio/media-summary',
            [
                'methods'             => 'GET',
                'callback'            => [ $this, 'handle_media_summary' ],
                'permission_callback' => [ $router, 'permissions_admin' ],
                'args'                => [
                    'id' => [
                        'type'    => 'integer',
                        'default' => 0,
                    ],
                    'mediaId' => [
                        'type'    => 'integer',
                        'default' => 0,
                    ],
                ],
            ]
        );

    }

    public function handle_media_list( \WP_REST_Request $request ) {
        if ( ! current_user_can( 'upload_files' ) ) {
            return Messages::error( 'forbidden', 403 );
        }

        $q        = sanitize_text_field( (string) $request->get_param( 'q' ) );
        $q        = strlen( $q ) > 100 ? substr( $q, 0, 100 ) : $q;
        $page     = max( 1, absint( $request->get_param( 'page' ) ) );
        $per_page = absint( $request->get_param( 'perPage' ) );
        $per_page = $per_page <= 0 ? 6 : min( 100, max( 1, $per_page ) );

        $filters = [
            'type'        => $this->allow_media_filter( $request, 'type', [ 'all', 'jpg', 'png', 'webp' ] ),
            'date'        => $this->allow_media_filter( $request, 'date', [ 'all', 'today', 'week', 'month', 'older' ] ),
            'orientation' => $this->allow_media_filter( $request, 'orientation', [ 'all', 'square', 'landscape', 'portrait' ] ),
            'size'        => $this->allow_media_filter( $request, 'size', [ 'all', 'under_300kb', '300kb_and_over' ] ),
        ];

        $result      = $this->media_query_adapter->list_media( $q, $page, $per_page, $filters );
        $items       = isset( $result['items'] ) && is_array( $result['items'] ) ? $result['items'] : [];
        $total_items = isset( $result['totalItems'] ) ? (int) $result['totalItems'] : 0;
        $total_pages = isset( $result['totalPages'] ) ? max( 1, (int) $result['totalPages'] ) : 1;

		$data = [
			'items'      => $items,
			'page'       => $page,
			'perPage'    => $per_page,
			'totalPages' => $total_pages,
			'totalItems' => $total_items,
		];

        $response = new \WP_REST_Response( $this->sanitize_for_json( $data ), 200 );
        $response->header( 'Content-Type', 'application/json; charset=' . get_option( 'blog_charset' ) );
        $response->header( 'Cache-Control', 'no-store, no-cache, must-revalidate' );
        return $response;
    }

    public function handle_media_summary( \WP_REST_Request $request ) {
        if ( ! current_user_can( 'upload_files' ) ) {
            return Messages::error( 'forbidden', 403 );
        }

        $id = $this->resolve_media_id( $request );
        if ( $id <= 0 ) {
            return Messages::error( 'invalid_request', 400 );
        }

        $summary = $this->media_query_adapter->get_media_summary( $id );
        if ( is_wp_error( $summary ) ) {
            $status = (int) ( $summary->get_error_data()['status'] ?? 403 );
            return Messages::error( 'forbidden', $status );
        }
        if ( null === $summary ) {
            return Messages::error( 'invalid_request', 404 );
        }

		return rest_ensure_response( $this->sanitize_for_json( $summary ) );
    }

    private function resolve_media_id( \WP_REST_Request $request ): int {
        $media_id = absint( $request->get_param( 'mediaId' ) );
        if ( $media_id > 0 ) {
            return $media_id;
        }
        return absint( $request->get_param( 'id' ) );
    }

    /**
     * Read one fail-closed Media Library filter.
     *
     * @param \WP_REST_Request $request Request.
     * @param string           $key     Query key.
     * @param string[]         $allowed Allowed values, including the default.
     */
    private function allow_media_filter( \WP_REST_Request $request, string $key, array $allowed ): string {
        $value = sanitize_key( (string) $request->get_param( $key ) );
        return in_array( $value, $allowed, true ) ? $value : $allowed[0];
    }

    private function sanitize_for_json( $payload ) {
        if ( is_array( $payload ) ) {
            $out = [];
            foreach ( $payload as $key => $value ) {
                $out[ $key ] = $this->sanitize_for_json( $value );
            }
            return $out;
        }
        if ( $payload instanceof \stdClass ) {
            return $this->sanitize_for_json( (array) $payload );
        }
        if ( is_object( $payload ) || is_resource( $payload ) ) {
            return '';
        }
        if ( is_string( $payload ) ) {
            return wp_check_invalid_utf8( $payload, true );
        }
        if ( is_int( $payload ) || is_float( $payload ) || is_bool( $payload ) || null === $payload ) {
            return $payload;
        }
        return $payload;
    }
}
