<?php
namespace App\Command\Money;

use App\Alias\Connection;
use App\Service\Money;
use DateTimeImmutable;
use DateTimeInterface;
use PDO;
use PDOException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: 'money:uf:get',
    hidden: false
)]
class Get extends Command
{
    public function __construct(protected Money $service, protected Connection $connection, string $name = null)
    {
        parent::__construct($name);
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Get Money');

        $dates = $this->getDates();
        foreach ($dates as $date_string => $ids) {
            $date = $this->parseDate($date_string);
            $response = $this->service->getUF($date);
            if ($response->total === 0) {
                continue;
            }
            foreach ($ids as $id) {
                $this->queueUpdate($id, $response->uf->value);
            }
        }
        $this->updateUF();
        return Command::SUCCESS;
    }

    protected function getDates(): array
    {
        $query = "SELECT id, fecha FROM pago WHERE uf IS NULL AND fecha BETWEEN 0 AND DATE_ADD(CURDATE(), INTERVAL 9 DAY) ORDER BY fecha";
        $statement = $this->connection->connect()->query($query);
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
        if (count($rows) === 0) {
            return [];
        }
        $dates = [];
        foreach ($rows as $row) {
            if (!isset($dates[$row['fecha']])) {
                $dates[$row['fecha']] = [];
            }
            $dates[$row['fecha']] []= (int) $row['id'];
        }
        return $dates;
    }
    protected function parseDate(string $date_string): DateTimeInterface
    {
        return new DateTimeImmutable($date_string);
    }
    protected array $rows;
    protected function queueUpdate(int $id, float $value): void
    {
        $this->rows []= [$value, $id];
    }
    protected function updateUF(): void
    {
        $query = "UPDATE pago SET uf = ? WHERE id = ?";
        $statement = $this->connection->connect()->prepare($query);
        foreach ($this->rows as $row) {
            $this->connection->connect()->beginTransaction();
            try {
                $statement->execute($row);
                $this->connection->connect()->commit();
            } catch (PDOException $e) {
                $this->connection->connect()->rollBack();
            }
        }
    }
}
