<?php

declare(strict_types=1);

namespace app\command;

use app\common\library\MallDailyPushLogReplay;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Throwable;

#[AsCommand('mall:daily-push:replay-log', '从原始日志幂等回放每日推送数据')]
class MallDailyPushReplayLog extends Command
{
    protected function configure(): void
    {
        $this->addOption('file', null, InputOption::VALUE_REQUIRED, 'daily_push_*.log 文件路径');
        $this->addOption('dry-run', null, InputOption::VALUE_NONE, '仅预检，不修改数据库');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $file = trim(strval($input->getOption('file') ?? ''));
        if ($file === '') {
            $output->writeln('<error>必须提供 --file 日志文件路径</error>');
            return self::FAILURE;
        }

        $dryRun = boolval($input->getOption('dry-run'));
        try {
            $result = (new MallDailyPushLogReplay())->replay($file, $dryRun);
        } catch (Throwable $e) {
            $output->writeln('<error>' . $e->getMessage() . '</error>');
            return self::FAILURE;
        }

        $output->writeln('<info>DailyPush 日志回放' . ($dryRun ? '预检' : '完成') . '</info>');
        foreach ([
            'dry_run',
            'log_file',
            'backup_file',
            'lines',
            'members',
            'unique_members',
            'daily_created',
            'daily_updated',
            'daily_unchanged',
            'assets_created',
            'assets_updated',
            'locked_points_delta',
            'invalid_lines',
            'failed_members',
        ] as $key) {
            $value = $result[$key] ?? '';
            if (is_bool($value)) {
                $value = $value ? 'true' : 'false';
            }
            $output->writeln($key . ': ' . strval($value));
        }

        $errors = $result['errors'] ?? [];
        if (is_array($errors) && $errors !== []) {
            $output->writeln('<comment>错误明细（最多显示 100 条）：</comment>');
            foreach ($errors as $error) {
                $output->writeln('- ' . strval($error));
            }
        }

        return intval($result['failed_members'] ?? 0) > 0 || intval($result['invalid_lines'] ?? 0) > 0
            ? self::FAILURE
            : self::SUCCESS;
    }
}
