<?php

namespace App\Doctor\Service\Repair;

use App\Doctor\Entity\Doctor;
use App\Doctor\Service\IrimcDegreeMapper;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * خزندهٔ irimc (clinicpro-crawler/crawler_core.py::map_degree) تا ۱۴۰۵/۰۴/۲۸ دو کد را
 * جابه‌جا می‌فرستاد: «فوق تخصص» را specialist (برچسب: متخصص) و «تخصص» را expert
 * (برچسب: فوق تخصص). خزنده اصلاح شده، ولی رکوردهای ایمپورت‌شده هنوز غلط‌اند.
 *
 * درجه دوباره از روی متن خام `info` — همان رشته‌ای که خزنده از ستون تخصص سایت گرفته —
 * محاسبه می‌شود، نه با معکوس‌کردن کورکورانهٔ مقدار فعلی؛ چون فقط رکوردهای همان دورهٔ
 * معیوب باید عوض شوند و اجرای دوباره نباید چیزی را خراب کند.
 */
final class FixDegreeStep implements DoctorRepairStep
{
    public function __construct(private readonly EntityManagerInterface $em)
    {
    }

    public function name(): string
    {
        return 'degrees';
    }

    public function description(): string
    {
        return 'محاسبهٔ دوبارهٔ درجه از روی عنوان خام نظام پزشکی';
    }

    public function run(RepairOptions $options, SymfonyStyle $io): RepairResult
    {
        $qb = $this->em->getRepository(Doctor::class)->createQueryBuilder('d');
        if (!$options->allSources) {
            $qb->andWhere('d.source = :src')->setParameter('src', 'irimc');
        }
        if (!$options->includeClaimed) {
            $qb->andWhere('d.ownerStatus != :claimed')->setParameter('claimed', 'claimed');
        }
        /** @var Doctor[] $doctors */
        $doctors = $qb->getQuery()->getResult();

        $changed = 0;
        $skipped = 0;
        foreach ($doctors as $doctor) {
            $want = IrimcDegreeMapper::fromTitle($doctor->getInfo());

            // متن خام قابل نگاشت نیست — درجهٔ فعلی را حدس‌زده تغییر نده.
            if ($want === null) {
                $skipped++;
                continue;
            }
            if ($want === $doctor->getDegree()) {
                continue;
            }

            $io->text(sprintf(
                '  #%d %s: %s → %s',
                $doctor->getId(),
                $doctor->getName(),
                IrimcDegreeMapper::label($doctor->getDegree()),
                IrimcDegreeMapper::label($want),
            ));
            if (!$options->dryRun) {
                $doctor->setDegree($want);
            }
            $changed++;
        }

        return new RepairResult(
            scanned: count($doctors),
            changed: $changed,
            skipped: $skipped,
            note: $skipped > 0 ? "$skipped رکورد بدون عنوان قابل نگاشت" : null,
        );
    }
}
