<?php

declare(strict_types=1);

final class MicFormNotificationFailureRepository
{
    public function __construct(private readonly PDO $pdo)
    {
    }

    public function recordFailure(string $submissionId, string $formId, string $recipientEmail, string $reason): void
    {
        $statement = $this->pdo->prepare(
            'INSERT INTO form_notification_failures (id, submission_id, form_id, attempted_at, recipient_email, failure_reason, retry_count)
             VALUES (:id, :submission_id, :form_id, :attempted_at, :recipient_email, :failure_reason, 0)'
        );
        $statement->execute([
            ':id' => 'fnf_' . bin2hex(random_bytes(8)),
            ':submission_id' => $submissionId,
            ':form_id' => $formId,
            ':attempted_at' => myronNow(),
            ':recipient_email' => $recipientEmail,
            ':failure_reason' => substr($reason, 0, 500),
        ]);
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function listRecent(int $limit = 20): array
    {
        $this->deleteExpired();
        $statement = $this->pdo->prepare(
            'SELECT fnf.*, fd.name AS form_name
             FROM form_notification_failures fnf
             LEFT JOIN form_definitions fd ON fd.id = fnf.form_id
             ORDER BY fnf.attempted_at DESC
             LIMIT :limit'
        );
        $statement->bindValue(':limit', max(1, min(100, $limit)), PDO::PARAM_INT);
        $statement->execute();
        return array_map(static fn (array $row): array => array_map('strval', $row), $statement->fetchAll(PDO::FETCH_ASSOC) ?: []);
    }

    public function markRetried(string $id): void
    {
        $statement = $this->pdo->prepare('UPDATE form_notification_failures SET retry_count = retry_count + 1 WHERE id = :id');
        $statement->execute([':id' => trim($id)]);
    }

    public function delete(string $id): void
    {
        $statement = $this->pdo->prepare('DELETE FROM form_notification_failures WHERE id = :id');
        $statement->execute([':id' => trim($id)]);
    }

    public function deleteExpired(): void
    {
        $cutoff = gmdate('Y-m-d H:i:s', time() - (30 * 86400));
        $statement = $this->pdo->prepare('DELETE FROM form_notification_failures WHERE attempted_at < :cutoff');
        $statement->execute([':cutoff' => $cutoff]);
    }
}
