<?php

namespace App\Auth\Command;

use App\Auth\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

/**
 * کاربر «مالک سیستمی» (پیش‌فرض موبایل 0000000000) که کرالر با آن به API لاگین می‌کند
 * تا پزشکان نظام پزشکی را وارد کند. ROLE_ADMIN دارد تا اندپوینت ایمپورت را صدا بزند.
 *
 * ساخت/به‌روزرسانی رمز و فعال‌سازی:
 *   php bin/console app:system-owner 0000000000 --password=secret --activate
 * غیرفعال‌سازی پس از پایان کار کرالر:
 *   php bin/console app:system-owner 0000000000 --deactivate
 */
#[AsCommand(
    name: 'app:system-owner',
    description: 'Manage the system-owner user used by the IRIMC crawler (create/activate/deactivate).',
)]
class SystemOwnerCommand extends Command
{
    public function __construct(
        private readonly EntityManagerInterface $em,
        private readonly UserPasswordHasherInterface $hasher,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addArgument('mobile', InputArgument::OPTIONAL, 'System-owner mobile identifier', '0000000000')
            ->addOption('password', 'p', InputOption::VALUE_REQUIRED, 'Set/replace the login password')
            ->addOption('activate', null, InputOption::VALUE_NONE, 'Activate the account (status=1)')
            ->addOption('deactivate', null, InputOption::VALUE_NONE, 'Deactivate the account (status=0)');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io       = new SymfonyStyle($input, $output);
        $mobile   = (string) $input->getArgument('mobile');
        $password = $input->getOption('password');
        $activate = (bool) $input->getOption('activate');
        $deactiv  = (bool) $input->getOption('deactivate');

        if ($activate && $deactiv) {
            $io->error('--activate و --deactivate با هم مجاز نیستند.');
            return Command::INVALID;
        }

        $repo    = $this->em->getRepository(User::class);
        $user    = $repo->findOneBy(['mobileNumber' => $mobile]);
        $existed = $user !== null;

        if (!$existed) {
            $user = new User($mobile);
            $user->setRealName('مالک سیستمی (کرالر نظام پزشکی)');
            if ($password === null) {
                $io->error('برای ساخت کاربر جدید، --password الزامی است.');
                return Command::INVALID;
            }
        }

        // least privilege: کاربر سیستمی فقط ROLE_IMPORTER می‌گیرد (دسترسی فقط به اندپوینت
        // ایمپورت پزشک). اگر از نسخه‌های قبلی ROLE_ADMIN دارد، حذف می‌شود.
        $roles = $user->getRoles();
        if (in_array('ROLE_ADMIN', $roles, true)) {
            $roles = array_values(array_diff($roles, ['ROLE_ADMIN']));
            $io->note('ROLE_ADMIN از کاربر سیستمی حذف شد (least privilege).');
        }
        if (!in_array('ROLE_IMPORTER', $roles, true)) {
            $roles[] = 'ROLE_IMPORTER';
        }
        $user->setRoles(array_values(array_unique($roles)));

        if ($password !== null) {
            $user->setPasswordHash($this->hasher->hashPassword($user, (string) $password));
        }

        // پیش‌فرضِ کاربرِ تازه: فعال، مگر آنکه --deactivate داده شده باشد.
        if ($activate) {
            $user->setStatus(1);
        } elseif ($deactiv) {
            $user->setStatus(0);
        } elseif (!$existed) {
            $user->setStatus(1);
        }

        $this->em->persist($user);
        $this->em->flush();

        $io->success(sprintf(
            '%s system-owner %s (uuid=%s, status=%d, roles=%s)',
            $existed ? 'Updated' : 'Created',
            $mobile,
            $user->getUuid(),
            $user->getStatus(),
            implode(',', $user->getRoles()),
        ));

        return Command::SUCCESS;
    }
}
