<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Api\Controllers;

use APD\Api\Middleware\PermissionGuard;
use APD\Api\RestNamespace;
use APD\Repositories\UserDesignRepository;
use APD\Support\PreviewStorage;
use APD\Support\PricingSnapshot;
use APD\Support\UserDesignAccess;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

defined('ABSPATH') || exit;

class DesignController
{
    public function registerRoutes() : void
    {
        register_rest_route(RestNamespace::NAME, '/design/save', [
            'methods' => 'POST',
            'permission_callback' => [PermissionGuard::class, 'authenticatedRuntime'],
            'callback' => [$this, 'save'],
        ]);

        register_rest_route(RestNamespace::NAME, '/design/(?P<id>\d+)', [
            'methods' => 'GET',
            'permission_callback' => [$this, 'canShow'],
            'callback' => [$this, 'show'],
        ]);
    }

    public function canShow(WP_REST_Request $request) : bool|WP_Error
    {
        $verified = PermissionGuard::runtime($request);
        if (is_wp_error($verified)) {
            return $verified;
        }

        $item = (new UserDesignRepository())->find(absint($request['id']));
        if ($item === []) {
            return new WP_Error(
                'apd_rest_design_not_found',
                __('Design not found.', 'asuka-product-designer'),
                ['status' => 404]
            );
        }

        if (UserDesignAccess::canAccessItem($item)) {
            return true;
        }

        return new WP_Error(
            'apd_rest_design_forbidden',
            __('You are not allowed to view this design.', 'asuka-product-designer'),
            ['status' => 403]
        );
    }

    public function save(WP_REST_Request $request) : WP_REST_Response
    {
        if (! is_user_logged_in()) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('You must be logged in to save a design.', 'asuka-product-designer'),
            ], 401);
        }

        $payload = $request->get_json_params();
        $preview = is_string($payload['preview'] ?? null) ? (string) $payload['preview'] : '';
        $previewUrls = [];

        if ($preview !== '') {
            $stored = (new PreviewStorage())->store($preview, 'apd-design-preview');
            if (! empty($stored['url'])) {
                $previewUrls[] = $stored['url'];
            }
        }

        $repo = new UserDesignRepository();
        $id = $repo->create([
            'title' => sanitize_text_field((string) ($payload['title'] ?? __('Saved design', 'asuka-product-designer'))),
            'userId' => get_current_user_id(),
            'configId' => absint($payload['configId'] ?? 0),
            'productId' => absint($payload['productId'] ?? 0),
            'designJson' => is_array($payload['design'] ?? null) ? $payload['design'] : [],
            'stateJson' => is_array($payload['state'] ?? null) ? $payload['state'] : [],
            'previewUrls' => $previewUrls,
            'priceSnapshot' => PricingSnapshot::normalize($payload['pricing'] ?? [], 0.0),
            'accessToken' => wp_generate_password(20, false, false),
        ]);

        if ($id <= 0) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Design save failed.', 'asuka-product-designer'),
            ], 500);
        }

        return new WP_REST_Response([
            'success' => true,
            'id' => $id,
            'message' => __('Design saved successfully.', 'asuka-product-designer'),
            'previewUrl' => $previewUrls[0] ?? '',
        ]);
    }

    public function show(WP_REST_Request $request) : WP_REST_Response
    {
        $repo = new UserDesignRepository();
        $item = $repo->find(absint($request['id']));

        if (! $item) {
            return new WP_REST_Response([
                'success' => false,
                'message' => __('Design not found.', 'asuka-product-designer'),
            ], 404);
        }

        if (UserDesignAccess::canAccessItem($item)) {
            unset($item['accessToken']);

            return new WP_REST_Response([
                'success' => true,
                'item' => $item,
            ]);
        }

        return new WP_REST_Response([
            'success' => false,
            'message' => __('You are not allowed to view this design.', 'asuka-product-designer'),
        ], 403);
    }
}
