<?php

declare(strict_types=1);

namespace FecaMailshots\Repository;

use FecaMailshots\Infrastructure\DatabaseRouter;
use PDO;

final class LastRunRepository
{
    private DatabaseRouter $router;

    public function __construct(DatabaseRouter $router)
    {
        $this->router = $router;
    }

    /** @return list<array<string, mixed>> */
    public function listForMailshot(int $mailshotId): array
    {
        $sql = 'SELECT id, mailshot_id, recipient_key, recipient_key_field, recipient_email_last, status, error_message, warning_message, attempt_count, run_started_at, last_attempt_at FROM mailshot_last_run WHERE mailshot_id = :mailshot_id ORDER BY last_attempt_at DESC, id DESC';
        $stmt = $this->router->mailshotsPdo()->prepare($sql);
        $stmt->execute(['mailshot_id' => $mailshotId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function clearForMailshot(int $mailshotId): void
    {
        $stmt = $this->router->mailshotsPdo()->prepare('DELETE FROM mailshot_last_run WHERE mailshot_id = :mailshot_id');
        $stmt->execute(['mailshot_id' => $mailshotId]);
    }

    /** @param array<string, mixed> $row */
    public function create(array $row): int
    {
        $sql = 'INSERT INTO mailshot_last_run (mailshot_id, data_source, row_index, recipient_key, recipient_key_field, recipient_email_last, status, error_message, warning_message, attempt_count) VALUES (:mailshot_id, :data_source, :row_index, :recipient_key, :recipient_key_field, :recipient_email_last, :status, :error_message, :warning_message, :attempt_count)';
        $stmt = $this->router->mailshotsPdo()->prepare($sql);
        $stmt->execute([
            'mailshot_id' => (int) ($row['mailshot_id'] ?? 0),
            'data_source' => $this->textOrNull($row['data_source'] ?? null),
            'row_index' => (int) ($row['row_index'] ?? 0),
            'recipient_key' => $this->textOrNull($row['recipient_key'] ?? null),
            'recipient_key_field' => $this->textOrNull($row['recipient_key_field'] ?? null),
            'recipient_email_last' => $this->textOrNull($row['recipient_email_last'] ?? null),
            'status' => trim((string) ($row['status'] ?? 'failed')),
            'error_message' => $this->textOrNull($row['error_message'] ?? null),
            'warning_message' => $this->textOrNull($row['warning_message'] ?? null),
            'attempt_count' => (int) ($row['attempt_count'] ?? 1),
        ]);
        return (int) $this->router->mailshotsPdo()->lastInsertId();
    }

    private function textOrNull($value): ?string
    {
        if ($value === null) {
            return null;
        }
        $v = trim((string) $value);
        return $v === '' ? null : $v;
    }
}
