<?php

namespace App\Services\Marketplace;

use App\Models\MarketplaceInstalled;

/**
 * Builds a pre-install preview DTO from a registry entry + local CMS state.
 *
 * The DTO is passed to admin/views/marketplace/preview.php and gives the
 * admin a complete picture before confirming installation.
 */
class PackagePreview
{
    private DependencyChecker $deps;
    private RollbackManager   $rollback;

    public function __construct(DependencyChecker $deps, RollbackManager $rollback)
    {
        $this->deps     = $deps;
        $this->rollback = $rollback;
    }

    /**
     * Build a preview array from a registry entry.
     *
     * @param array  $registryEntry Full registry API response for the package.
     * @param string $publicKeyB64  Public key used for verification (empty = not yet verified).
     * @param bool   $signatureValid Whether the signature has already been verified.
     */
    public function build(array $registryEntry, string $publicKeyB64 = '', bool $signatureValid = false): array
    {
        $slug       = $registryEntry['slug']    ?? '';
        $type       = $registryEntry['type']    ?? 'plugin';
        $manifest   = $this->extractManifest($registryEntry);

        // Installed state
        $installed        = MarketplaceInstalled::findBySlug($slug);
        $versionCurrent   = $installed['version'] ?? null;
        $isUpdate         = $installed !== null
            && version_compare($registryEntry['version'] ?? '0', $versionCurrent ?? '0', '>');

        // CMS compatibility
        $cmsCompatible = $this->deps->isCmsVersionCompatible($manifest);
        $cmsWarnings   = $this->deps->getCmsWarnings($manifest);

        // Backup estimate
        $backups         = $this->rollback->listBackups($type, $slug);
        $backupWillBeCreated = $installed !== null;

        // SHA256 / signature display
        $sha256      = $registryEntry['sha256_hash']   ?? '';
        $signedByKey = $registryEntry['key_id']        ?? '';
        $signedAt    = $registryEntry['signed_at']     ?? null;

        // Files affected estimate (human-readable, not computed – just the target dirs)
        if ($type === 'theme') {
            $filesAffectedNote = "themes/{$slug}/ + public/themes/{$slug}/";
        } else {
            $filesAffectedNote = "plugins/{$slug}/ + public/plugins/{$slug}/";
        }

        return [
            'slug'                  => $slug,
            'name'                  => $registryEntry['name']        ?? $slug,
            'type'                  => $type,
            'version_new'           => $registryEntry['version']     ?? '',
            'version_current'       => $versionCurrent,
            'is_update'             => $isUpdate,
            'description'           => $registryEntry['description'] ?? '',
            'author'                => $registryEntry['author']      ?? '',
            'thumbnail'             => $registryEntry['thumbnail']   ?? '',
            'screenshots'           => $type === 'theme' ? ($registryEntry['screenshots'] ?? []) : [],
            'category'              => $registryEntry['category']    ?? 'content',
            'size_bytes'            => (int) ($registryEntry['size_bytes'] ?? 0),
            'sha256'                => $sha256,
            'signature_valid'       => $signatureValid,
            'signed_by_key_id'      => $signedByKey,
            'signed_at'             => $signedAt,
            'min_cms_version'       => $manifest['min_cms_version']  ?? '0',
            'max_cms_version'       => $manifest['max_cms_version']  ?? '',
            'cms_compatible'        => $cmsCompatible,
            'cms_warnings'          => $cmsWarnings,
            'is_premium'            => !empty($registryEntry['is_premium']),
            'license_required'      => !empty($registryEntry['is_premium']),
            'categories'            => $registryEntry['categories']  ?? [],
            'files_affected_note'   => $filesAffectedNote,
            'backup_will_be_created'=> $backupWillBeCreated,
            'existing_backups'      => count($backups),
            'registry_url'          => $registryEntry['_registry_url'] ?? '',
        ];
    }

    // ─────────────────────────────────────────────────────────
    // Private helpers
    // ─────────────────────────────────────────────────────────

    private function extractManifest(array $entry): array
    {
        $manifestJson = $entry['manifest_json'] ?? '';

        if ($manifestJson !== '') {
            $decoded = json_decode($manifestJson, true);
            if (is_array($decoded)) {
                return $decoded;
            }
        }

        return [
            'min_cms_version' => $entry['min_cms_version'] ?? '0',
            'max_cms_version' => $entry['max_cms_version'] ?? '',
        ];
    }
}
