<?php

declare(strict_types=1);

namespace App\Modules\Sms;

use App\Core\Http\ToggleableRepositoryTrait;
use PDO;
use RuntimeException;

final class SmsTemplateRepository
{
    use ToggleableRepositoryTrait;

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

    /**
     * @return list<array<string, mixed>>
     */
    public function listAll(): array
    {
        $statement = $this->pdo->prepare(
            'SELECT id, name, body, is_active, created_at, updated_at
             FROM sms_templates
             ORDER BY name ASC'
        );
        $statement->execute();
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        return is_array($rows) ? $rows : [];
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function listActive(): array
    {
        $statement = $this->pdo->prepare(
            'SELECT id, name, body
             FROM sms_templates
             WHERE is_active = 1
             ORDER BY name ASC'
        );
        $statement->execute();
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        return is_array($rows) ? $rows : [];
    }

    /**
     * @return array<string, mixed>|null
     */
    public function findById(int $id): ?array
    {
        $statement = $this->pdo->prepare(
            'SELECT id, name, body, is_active, created_at, updated_at
             FROM sms_templates
             WHERE id = :id'
        );
        $statement->execute(['id' => $id]);
        $row = $statement->fetch(PDO::FETCH_ASSOC);

        return is_array($row) ? $row : null;
    }

    /**
     * @param array<string, mixed> $data
     */
    public function save(array $data): int
    {
        $name = trim((string) ($data['name'] ?? ''));
        $body = (string) ($data['body'] ?? '');
        if ($name === '') {
            throw new RuntimeException('Nazwa szablonu jest wymagana.');
        }
        if (trim($body) === '') {
            throw new RuntimeException('Tresc szablonu jest wymagana.');
        }

        $id = isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : null;
        $params = [
            'name' => $name,
            'body' => $body,
            'is_active' => isset($data['is_active']) && $data['is_active'] ? 1 : 0,
        ];

        if ($id !== null) {
            $params['id'] = $id;
            $statement = $this->pdo->prepare(
                'UPDATE sms_templates
                 SET name = :name, body = :body, is_active = :is_active
                 WHERE id = :id'
            );
            $statement->execute($params);

            return $id;
        }

        $statement = $this->pdo->prepare(
            'INSERT INTO sms_templates (name, body, is_active)
             VALUES (:name, :body, :is_active)'
        );
        $statement->execute($params);

        return (int) $this->pdo->lastInsertId();
    }

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

    public function toggleStatus(int $id): void
    {
        $this->toggleActive('sms_templates', $id);
    }
}
