<?php

declare(strict_types=1);

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

    /**
     * @return list<array<string, string>>
     */
    public function listForUser(string $userId): array
    {
        $statement = $this->pdo->prepare(
            'SELECT *
             FROM dashboard_notes
             WHERE user_id = :user_id
             ORDER BY created_at DESC, id DESC'
        );
        $statement->execute([':user_id' => $userId]);

        return array_map(
            static fn (array $row): array => array_map('strval', $row),
            $statement->fetchAll(PDO::FETCH_ASSOC) ?: []
        );
    }

    public function saveForUser(string $userId, string $title, string $content, ?string $noteId = null): string
    {
        $title = trim($title);
        $content = trim($content);
        if ($title === '') {
            throw new InvalidArgumentException('Note title is required.');
        }

        $now = myronNow();
        if ($noteId !== null && trim($noteId) !== '') {
            $statement = $this->pdo->prepare(
                'UPDATE dashboard_notes
                 SET title = :title,
                     content = :content,
                     updated_at = :updated_at
                 WHERE id = :id
                   AND user_id = :user_id'
            );
            $statement->execute([
                ':title' => $title,
                ':content' => $content,
                ':updated_at' => $now,
                ':id' => $noteId,
                ':user_id' => $userId,
            ]);
            if (!$this->existsForUser($userId, $noteId)) {
                throw new RuntimeException('Note not found.');
            }

            return $noteId;
        }

        $id = myronGenerateId('note');
        $statement = $this->pdo->prepare(
            'INSERT INTO dashboard_notes (id, user_id, title, content, created_at, updated_at)
             VALUES (:id, :user_id, :title, :content, :created_at, :updated_at)'
        );
        $statement->execute([
            ':id' => $id,
            ':user_id' => $userId,
            ':title' => $title,
            ':content' => $content,
            ':created_at' => $now,
            ':updated_at' => $now,
        ]);

        return $id;
    }

    public function deleteForUser(string $userId, string $noteId): void
    {
        $statement = $this->pdo->prepare(
            'DELETE FROM dashboard_notes
             WHERE id = :id
               AND user_id = :user_id'
        );
        $statement->execute([
            ':id' => $noteId,
            ':user_id' => $userId,
        ]);
    }

    private function existsForUser(string $userId, string $noteId): bool
    {
        $statement = $this->pdo->prepare('SELECT id FROM dashboard_notes WHERE id = :id AND user_id = :user_id LIMIT 1');
        $statement->execute([
            ':id' => $noteId,
            ':user_id' => $userId,
        ]);

        return $statement->fetchColumn() !== false;
    }
}
