<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * 宿主官方授权、系统更新检查/包/执行/备份（合并原 100000–171609 共 8 条迁移；不含 host_token / host_key 等密钥）。
 */
return new class extends Migration
{
    public function up(): void
    {
        if (! Schema::hasTable('host_system_authorizations')) {
            Schema::create('host_system_authorizations', function (Blueprint $table): void {
                $table->id();
                $table->string('singleton_key', 32)->default('default')->comment('单例键');
                $table->boolean('authorized')->default(false)->comment('是否已获官方授权');
                $table->string('product_code', 64)->nullable()->comment('产品线编码');
                $table->string('site_no', 128)->nullable()->comment('官方站点编号');
                $table->string('license_no', 128)->nullable()->comment('授权编号');
                $table->string('license_holder', 255)->nullable()->comment('版权商用许可主体（授权同步）');
                $table->string('service_status', 64)->nullable()->comment('服务状态');
                $table->timestamp('expires_at')->nullable()->comment('服务到期时间（UTC）');
                $table->json('bound_domains')->nullable()->comment('绑定域名列表');
                $table->json('entitlements')->nullable()->comment('权益快照');
                $table->string('last_sync_status', 32)->nullable()->comment('最近同步结果：success/failed');
                $table->text('last_sync_message')->nullable()->comment('最近同步用户可见说明');
                $table->string('last_sync_error_code', 128)->nullable()->comment('最近同步错误码');
                $table->timestamp('last_synced_at')->nullable()->comment('最近同步时间（UTC）');
                $table->json('raw_snapshot')->nullable()->comment('脱敏后的原始响应快照');
                $table->timestamps();

                $table->unique('singleton_key', 'uq_host_system_authorizations_singleton');
            });
        }

        if (! Schema::hasTable('host_system_update_checks')) {
            Schema::create('host_system_update_checks', function (Blueprint $table): void {
                $table->id();
                $table->string('singleton_key', 32)->default('default')->comment('单例键');
                $table->string('product_code', 64)->nullable()->comment('产品线编码');
                $table->string('current_version', 64)->nullable()->comment('当前展示版本');
                $table->unsignedInteger('current_update_version')->nullable()->comment('当前内部更新号');
                $table->string('latest_version', 64)->nullable()->comment('最新可用展示版本');
                $table->unsignedInteger('latest_update_version')->nullable()->comment('最新内部更新号');
                $table->string('release_channel', 64)->nullable()->comment('发行通道');
                $table->boolean('update_available')->default(false)->comment('是否存在可安装更新');
                $table->string('package_id', 128)->nullable()->comment('官方包标识');
                $table->string('package_type', 64)->nullable()->comment('包类型元数据');
                $table->string('package_version', 64)->nullable()->comment('包版本');
                $table->unsignedBigInteger('package_size')->nullable()->comment('包大小（字节）');
                $table->string('checksum', 255)->nullable()->comment('包校验和');
                $table->string('checksum_algorithm', 64)->nullable()->comment('校验算法');
                $table->text('signature')->nullable()->comment('包签名');
                $table->json('release_notes')->nullable()->comment('发行说明');
                $table->json('requirements')->nullable()->comment('安装要求');
                $table->string('min_upgradable_version', 64)->nullable()->comment('最低可升级版本');
                $table->boolean('entitled')->nullable()->comment('官方权益判定');
                $table->text('entitlement_message')->nullable()->comment('权益说明');
                $table->string('last_check_status', 32)->nullable()->comment('最近检查：success/failed');
                $table->text('last_check_message')->nullable()->comment('最近检查用户可见说明');
                $table->string('last_check_error_code', 128)->nullable()->comment('最近检查错误码');
                $table->string('last_request_id', 128)->nullable()->comment('最近请求 ID');
                $table->timestamp('last_checked_at')->nullable()->comment('最近检查时间（UTC）');
                $table->json('raw_snapshot')->nullable()->comment('脱敏后的原始响应快照');
                $table->timestamps();

                $table->unique('singleton_key', 'uq_host_system_update_checks_singleton');
            });
        }

        if (! Schema::hasTable('host_system_update_packages')) {
            Schema::create('host_system_update_packages', function (Blueprint $table): void {
                $table->id();
                $table->string('package_id', 128)->nullable()->comment('官方包标识');
                $table->string('package_no', 128)->nullable()->comment('官方包编号');
                $table->string('product_code', 64)->nullable()->comment('产品线编码');
                $table->string('version', 64)->nullable()->comment('包版本');
                $table->string('release_channel', 64)->nullable()->comment('发行通道');
                $table->string('package_type', 64)->nullable()->comment('包类型元数据');
                $table->string('package_name', 255)->nullable()->comment('包展示名');
                $table->unsignedBigInteger('package_size')->nullable()->comment('官方声明包大小（字节）');
                $table->string('checksum', 255)->nullable()->comment('官方包校验和');
                $table->string('checksum_algorithm', 64)->nullable()->comment('校验算法');
                $table->text('signature')->nullable()->comment('包签名');
                $table->string('download_status', 32)->nullable()->comment('下载/校验状态');
                $table->text('download_message')->nullable()->comment('下载或校验用户可见说明');
                $table->string('download_error_code', 128)->nullable()->comment('下载或校验错误码');
                $table->string('download_request_id', 128)->nullable()->comment('最近下载相关请求 ID');
                $table->timestamp('token_expires_at')->nullable()->comment('下载令牌过期时间（UTC，不含令牌本身）');
                $table->string('local_path', 512)->nullable()->comment('本地存储相对/绝对路径');
                $table->string('local_filename', 255)->nullable()->comment('本地安全文件名');
                $table->unsignedBigInteger('local_size')->nullable()->comment('本地文件大小（字节）');
                $table->boolean('verified')->default(false)->comment('整包校验是否通过');
                $table->timestamp('verified_at')->nullable()->comment('校验通过时间（UTC）');
                $table->timestamp('downloaded_at')->nullable()->comment('下载完成时间（UTC）');
                $table->json('raw_payload')->nullable()->comment('脱敏后的原始响应快照');
                $table->json('manifest')->nullable()->comment('解析后的 manifest.json');
                $table->string('manifest_status', 32)->nullable()->comment('manifest 状态：valid/invalid/unsupported/parse_failed');
                $table->text('manifest_message')->nullable()->comment('manifest 用户可见说明');
                $table->string('manifest_error_code', 128)->nullable()->comment('manifest 错误码');
                $table->timestamp('manifest_parsed_at')->nullable()->comment('manifest 解析时间（UTC）');
                $table->timestamps();

                $table->index('package_id', 'idx_host_system_update_packages_package_id');
                $table->index('version', 'idx_host_system_update_packages_version');
                $table->index('release_channel', 'idx_host_system_update_packages_release_channel');
                $table->index('download_status', 'idx_host_system_update_packages_download_status');
                $table->index('verified', 'idx_host_system_update_packages_verified');
            });
        }

        if (! Schema::hasTable('host_system_update_executions')) {
            Schema::create('host_system_update_executions', function (Blueprint $table): void {
                $table->id();
                $table->string('execution_no', 64)->unique()->comment('执行任务编号');
                $table->string('package_id', 128)->nullable()->comment('官方包标识');
                $table->unsignedBigInteger('host_system_update_package_id')->nullable()->comment('关联本地更新包记录');
                $table->string('product_code', 64)->nullable()->comment('产品线编码');
                $table->string('from_version', 64)->nullable()->comment('起始展示版本');
                $table->unsignedInteger('from_update_version')->nullable()->comment('起始内部更新号');
                $table->string('to_version', 64)->nullable()->comment('目标展示版本');
                $table->unsignedInteger('to_update_version')->nullable()->comment('目标内部更新号');
                $table->string('release_channel', 64)->nullable()->comment('发行通道');
                $table->string('package_type', 64)->nullable()->comment('包类型');
                $table->string('status', 32)->nullable()->comment('执行状态');
                $table->string('current_step', 64)->nullable()->comment('当前步骤');
                $table->unsignedSmallInteger('progress_percent')->default(0)->comment('进度百分比');
                $table->timestamp('started_at')->nullable()->comment('开始执行时间（UTC）');
                $table->timestamp('finished_at')->nullable()->comment('完成时间（UTC）');
                $table->timestamp('failed_at')->nullable()->comment('失败时间（UTC）');
                $table->timestamp('cancelled_at')->nullable()->comment('取消时间（UTC）');
                $table->string('rollback_status', 32)->nullable()->comment('回滚状态');
                $table->timestamp('rollback_started_at')->nullable()->comment('回滚开始时间（UTC）');
                $table->timestamp('rollback_finished_at')->nullable()->comment('回滚完成时间（UTC）');
                $table->string('error_code', 128)->nullable()->comment('错误码');
                $table->text('error_message')->nullable()->comment('用户可见错误说明');
                $table->unsignedBigInteger('operator_id')->nullable()->comment('操作人 ID');
                $table->string('operator_name', 128)->nullable()->comment('操作人姓名');
                $table->timestamp('locked_at')->nullable()->comment('并发锁持有时间（UTC）');
                $table->string('lock_owner', 128)->nullable()->comment('并发锁持有者标识');
                $table->json('raw_manifest')->nullable()->comment('脱敏 manifest 摘要');
                $table->timestamps();

                $table->index('package_id', 'idx_host_system_update_executions_package_id');
                $table->index('status', 'idx_host_system_update_executions_status');
                $table->index('current_step', 'idx_host_system_update_executions_current_step');
                $table->index('started_at', 'idx_host_system_update_executions_started_at');
                $table->index('operator_id', 'idx_host_system_update_executions_operator_id');

                $table->foreign('host_system_update_package_id', 'fk_host_sys_upd_exec_package_id')
                    ->references('id')
                    ->on('host_system_update_packages')
                    ->nullOnDelete();
            });
        }

        if (! Schema::hasTable('host_system_update_execution_logs')) {
            Schema::create('host_system_update_execution_logs', function (Blueprint $table): void {
                $table->id();
                $table->unsignedBigInteger('execution_id')->comment('关联执行任务');
                $table->string('step', 64)->nullable()->comment('步骤标识');
                $table->string('status', 32)->nullable()->comment('步骤状态');
                $table->text('message')->nullable()->comment('步骤说明');
                $table->json('context')->nullable()->comment('脱敏上下文');
                $table->timestamp('started_at')->nullable()->comment('步骤开始时间（UTC）');
                $table->timestamp('finished_at')->nullable()->comment('步骤结束时间（UTC）');
                $table->unsignedInteger('duration_ms')->nullable()->comment('步骤耗时（毫秒）');
                $table->string('error_code', 128)->nullable()->comment('错误码');
                $table->text('error_message')->nullable()->comment('用户可见错误说明');
                $table->timestamps();

                $table->index('execution_id', 'idx_host_system_update_execution_logs_execution_id');
                $table->index('step', 'idx_host_system_update_execution_logs_step');
                $table->index('status', 'idx_host_system_update_execution_logs_status');
                $table->index('created_at', 'idx_host_system_update_execution_logs_created_at');

                $table->foreign('execution_id', 'fk_host_sys_upd_exec_log_exec_id')
                    ->references('id')
                    ->on('host_system_update_executions')
                    ->cascadeOnDelete();
            });
        }

        if (! Schema::hasTable('host_system_update_backups')) {
            Schema::create('host_system_update_backups', function (Blueprint $table): void {
                $table->id();
                $table->unsignedBigInteger('execution_id')->comment('关联执行任务');
                $table->string('backup_no', 64)->unique()->comment('备份编号');
                $table->string('backup_type', 64)->nullable()->comment('备份类型');
                $table->string('status', 32)->nullable()->comment('备份状态');
                $table->string('backup_path', 512)->nullable()->comment('备份相对路径（storage 下）');
                $table->unsignedBigInteger('backup_size')->nullable()->comment('备份大小（字节）');
                $table->string('checksum', 255)->nullable()->comment('备份校验和');
                $table->string('checksum_algorithm', 64)->nullable()->comment('校验算法');
                $table->json('included_paths')->nullable()->comment('已纳入备份的相对路径');
                $table->json('excluded_paths')->nullable()->comment('排除的路径');
                $table->timestamp('started_at')->nullable()->comment('开始时间（UTC）');
                $table->timestamp('finished_at')->nullable()->comment('完成时间（UTC）');
                $table->timestamp('failed_at')->nullable()->comment('失败时间（UTC）');
                $table->string('error_code', 128)->nullable()->comment('错误码');
                $table->text('error_message')->nullable()->comment('用户可见错误说明');
                $table->timestamps();

                $table->index('execution_id', 'idx_host_system_update_backups_execution_id');
                $table->index('backup_type', 'idx_host_system_update_backups_backup_type');
                $table->index('status', 'idx_host_system_update_backups_status');

                $table->foreign('execution_id', 'fk_host_sys_upd_backup_exec_id')
                    ->references('id')
                    ->on('host_system_update_executions')
                    ->cascadeOnDelete();
            });
        }
    }

    public function down(): void
    {
        Schema::dropIfExists('host_system_update_backups');
        Schema::dropIfExists('host_system_update_execution_logs');
        Schema::dropIfExists('host_system_update_executions');
        Schema::dropIfExists('host_system_update_packages');
        Schema::dropIfExists('host_system_update_checks');
        Schema::dropIfExists('host_system_authorizations');
    }
};
