<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Migration;

use Contao\CoreBundle\Migration\AbstractMigration;
use Contao\CoreBundle\Migration\MigrationResult;
use Doctrine\DBAL\Connection;
use Ferienpass\CoreBundle\Entity\Offer\Base;

/**
 * Backfills Offer.randomSeed for rows created before the column existed.
 *
 * New offers get a random seed from the entity constructor; existing rows
 * have NULL until this runs. The seed is the server-side HMAC key behind the
 * private share link, so each offer needs its own. Runs after the schema diff
 * (contao:migrate) has added the column.
 */
class OfferRandomSeedMigration extends AbstractMigration
{
    public function __construct(private readonly Connection $db)
    {
    }

    public function shouldRun(): bool
    {
        $schemaManager = $this->db->createSchemaManager();

        if (!$schemaManager->tablesExist(['Offer'])) {
            return false;
        }

        if (!isset($schemaManager->listTableColumns('Offer')['randomseed'])) {
            // Column not created yet — let the schema diff run first.
            return false;
        }

        return (bool) $this->db
            ->executeQuery("SELECT 1 FROM Offer WHERE randomSeed IS NULL OR randomSeed = '' LIMIT 1")
            ->fetchOne()
        ;
    }

    public function run(): MigrationResult
    {
        $ids = $this->db
            ->executeQuery("SELECT id FROM Offer WHERE randomSeed IS NULL OR randomSeed = ''")
            ->fetchFirstColumn()
        ;

        $update = $this->db->prepare('UPDATE Offer SET randomSeed = :seed WHERE id = :id');
        foreach ($ids as $id) {
            $update->executeStatement(['seed' => Base::generateRandomSeed(), 'id' => $id]);
        }

        return $this->createResult(true, \sprintf('Backfilled %d offer random seed(s).', \count($ids)));
    }
}
