<?php

namespace Licenzo\Http\Controller\Api\V1;

use Licenzo\Framework\Http\Request;
use Licenzo\Http\Traits\HandlesErrors;
use Licenzo\Services\Updates\ProductUpdateService;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class ProductUpdatesController
{
    use HandlesErrors;

    /**
     * @var ProductUpdateService
     */
    private $service;

    public function __construct(?ProductUpdateService $service = null)
    {
        $this->service = $service ?? new ProductUpdateService();
    }

    public function check(Request $request, $license, $product, $variation): array
    {
        try {
            $context = $this->extractContext($request);

            return [
                'success' => true,
                'data' => $this->service->checkForUpdate((string) $license, (string) $product, (string) $variation, $context),
            ];
        } catch (\Throwable $e) {
            return $this->handleError($e, 'Failed to check for update', 403);
        }
    }

    public function info(Request $request, $license, $product, $variation): array
    {
        try {
            $context = $this->extractContext($request);

            return [
                'success' => true,
                'data' => $this->service->getUpdateInfo((string) $license, (string) $product, (string) $variation, $context),
            ];
        } catch (\Throwable $e) {
            return $this->handleError($e, 'Failed to retrieve update information', 403);
        }
    }

    /**
     * @return array<string,mixed>|\WP_REST_Response
     */
    public function download(Request $request, $token)
    {
        try {
            $releaseUuid = (string) $request->query('release', '');
            $licenseId = (int) $request->query('lid', 0);
            $variationId = (int) $request->query('vid', 0);

            return $this->service->handleDownload(
                (string) $token,
                $releaseUuid,
                $licenseId,
                $variationId
            );
        } catch (\Throwable $e) {
            return $this->handleError($e, 'Failed to process update download', 403);
        }
    }

    /**
     * @return array<string,mixed>
     */
    private function extractContext(Request $request): array
    {
        $context = $request->getSafe([
            'current_version' => 'sanitize_text_field',
            'installed_version' => 'sanitize_text_field',
            'version' => 'sanitize_text_field',
            'channel' => 'sanitize_text_field',
            'site_url' => 'esc_url_raw',
            'home_url' => 'esc_url_raw',
            'plugin' => 'sanitize_text_field',
            'slug' => 'sanitize_text_field',
            'instance_identifier' => 'sanitize_text_field',
        ]);

        $meta = $request->get('meta', null);
        if (is_string($meta) && $meta !== '') {
            $decoded = json_decode($meta, true);
            $meta = is_array($decoded) ? $decoded : null;
        }

        if (is_array($meta)) {
            $context['meta'] = $meta;
        }

        return $context;
    }
}
