<?php

namespace App\Package\Command;

use App\Package\Entity\SessionCreditLedger;
use App\Package\Repository\PatientPackageRepository;
use App\Package\Service\CreditLedgerService;
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 Symfony\Component\Console\Style\SymfonyStyle;

/**
 * ثبت ردیف `expiry` برای پکیج‌هایی که تاریخشان گذشته و هنوز مانده دارند.
 *
 * دفتر دست‌نخورده می‌ماند و تاریخچه کامل است: بیمار می‌تواند بپرسد «۳ جلسه‌ام چه شد؟»
 * و جواب یک ردیف با تاریخ و دلیل است، نه سکوت.
 */
#[AsCommand(name: 'app:package:expire', description: 'Write expiry ledger rows for lapsed patient packages.')]
class ExpirePackagesCommand extends Command
{
    public function __construct(
        private readonly PatientPackageRepository $packages,
        private readonly CreditLedgerService      $ledger,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this->addOption('dry-run', null, InputOption::VALUE_NONE, 'Report without writing');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io      = new SymfonyStyle($input, $output);
        $dryRun  = (bool) $input->getOption('dry-run');
        $expired = 0;

        foreach ($this->packages->findExpiredSince(time()) as $package) {
            $balance = $this->ledger->balance($package);

            if ($balance <= 0) {
                continue;
            }

            if (!$dryRun) {
                $this->ledger->record(
                    $package,
                    SessionCreditLedger::KIND_EXPIRY,
                    -$balance,
                    reason: 'انقضای اعتبار پکیج',
                );
            }

            $expired++;
        }

        $io->success(sprintf(
            $dryRun ? '%d پکیج منقضی می‌شد.' : '%d پکیج منقضی شد.',
            $expired,
        ));

        return Command::SUCCESS;
    }
}
