<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Console\Commands;

use Illuminate\Console\Command;
use InvalidArgumentException;
use RuntimeException;
use Tools\PluginRelease\OfficialPluginReleasePackageBuilder;

final class BuildOfficialPluginPackageCommand extends Command
{
    protected $signature = 'dberp:build-plugin
                            {pluginAlias : 官方插件 alias，例如 dberp-barcode-label}
                            {--plugin-version= : 发布版本，默认取 plugin.json；若指定则必须与 plugin.json 一致（勿使用 Artisan 全局 --version）}
                            {--force : 覆盖 dist/plugins 下该插件版本目录已有输出}';

    protected $description = '构建 DBErp 官方插件发布包（ZIP + manifest.json + release-manifest.json + checksums.json + signature.sig）';

    public function handle(OfficialPluginReleasePackageBuilder $builder): int
    {
        $pluginAlias = trim((string) $this->argument('pluginAlias'));

        if ($pluginAlias === '') {
            $this->error('pluginAlias 不能为空。');

            return self::FAILURE;
        }

        try {
            $requestedVersion = $this->resolveRequestedVersion();
        } catch (InvalidArgumentException $exception) {
            $this->error($exception->getMessage());

            return self::FAILURE;
        }

        $this->newLine();
        $this->line("Building DBErp official plugin release package for [{$pluginAlias}]...");

        try {
            $result = $builder->build(
                projectRoot: base_path(),
                pluginAlias: $pluginAlias,
                requestedVersion: $requestedVersion,
                force: (bool) $this->option('force'),
            );
        } catch (InvalidArgumentException|RuntimeException $exception) {
            $this->newLine();
            $this->error($exception->getMessage());

            return self::FAILURE;
        }

        /** @var array<string, mixed> $manifest */
        $manifest = $result['manifest'];

        $this->newLine();
        $this->line('DBErp official plugin release package built successfully.');
        $this->line('Plugin alias: '.$result['plugin_alias']);
        $this->line('Version: '.$result['version']);
        $this->line('Plugin root: '.$this->relativeOutputPath($result['plugin_root']));
        $this->line('Output directory: '.$this->relativeOutputPath($result['output_directory']));
        $this->line('Archive path: '.$this->relativeOutputPath($result['archive_path']));
        $this->line('Manifest path: '.$this->relativeOutputPath($result['manifest_path']));
        $this->line('Release manifest path: '.$this->relativeOutputPath($result['release_manifest_path']));
        $this->line('Release no: '.$result['release_no']);
        $this->line('Checksums path: '.$this->relativeOutputPath($result['checksums_path']));
        $this->line('Signature path: '.$this->relativeOutputPath($result['signature_path']));
        $this->line('Files in archive: '.$result['file_count']);
        $this->line('Archive SHA256: '.$result['archive_sha256']);
        $this->line('Archive size (bytes): '.$result['archive_size_bytes']);
        $this->line('Signature strategy: '.$result['signature_strategy']);
        $this->line('Schema: '.($manifest['schema'] ?? ''));
        $this->line('Product code: '.($manifest['product_code'] ?? ''));
        $this->line('Plugin code: '.($manifest['plugin_code'] ?? ''));
        $this->line('Plugin name: '.($manifest['plugin_name'] ?? ''));

        /** @var array<string, mixed> $releaseManifest */
        $releaseManifest = $result['release_manifest'];
        $this->line('Release manifest schema_version: '.($releaseManifest['schema_version'] ?? ''));
        $this->line('Release manifest package path: '.($releaseManifest['package']['path'] ?? ''));

        $this->newLine();
        $this->comment('release-manifest.json 已按 Support Center schema v1 生成，可在运营后台「插件版本」使用「从清单导入」填表。');
        $this->comment('本步骤仅生成本地发布产物，不会上传至 Support Center。');

        return self::SUCCESS;
    }

    private function resolveRequestedVersion(): ?string
    {
        $resolved = trim((string) $this->option('plugin-version'));

        return $resolved !== '' ? $resolved : null;
    }

    private function relativeOutputPath(string $absolutePath): string
    {
        $base = rtrim(base_path(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;

        if (str_starts_with($absolutePath, $base)) {
            return str_replace('\\', '/', substr($absolutePath, strlen($base)));
        }

        return str_replace('\\', '/', $absolutePath);
    }
}
