<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use App\Core\Support\StringHelper;
use PDO;
use Throwable;

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

    /**
     * @return array<string, mixed>|null
     */
    public function findByTypeAndName(string $type, string $name): ?array
    {
        try {
            $statement = $this->pdo->prepare(
                'SELECT * FROM integrations WHERE type = :type AND name = :name LIMIT 1'
            );
            $statement->execute([
                'type' => trim($type),
                'name' => trim($name),
            ]);
            $row = $statement->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable) {
            return null;
        }

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

    /**
     * @return array<string, mixed>|null
     */
    public function findFirstByType(string $type): ?array
    {
        try {
            $statement = $this->pdo->prepare(
                'SELECT * FROM integrations WHERE type = :type ORDER BY id ASC LIMIT 1'
            );
            $statement->execute(['type' => trim($type)]);
            $row = $statement->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable) {
            return null;
        }

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

    /**
     * @return array<string, mixed>|null
     */
    public function findById(int $id): ?array
    {
        if ($id <= 0) {
            return null;
        }

        try {
            $statement = $this->pdo->prepare('SELECT * FROM integrations WHERE id = :id LIMIT 1');
            $statement->execute(['id' => $id]);
            $row = $statement->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable) {
            return null;
        }

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

    public function ensureIntegration(
        string $type,
        string $name,
        string $baseUrl,
        int $timeoutSeconds = 10,
        bool $isActive = true
    ): int {
        $typeValue = trim($type);
        $nameValue = trim($name);
        $baseUrlValue = trim($baseUrl);

        $existing = $this->findByTypeAndName($typeValue, $nameValue);
        if ($existing !== null) {
            return (int) ($existing['id'] ?? 0);
        }

        $statement = $this->pdo->prepare(
            'INSERT INTO integrations (
                type, name, base_url, timeout_seconds, is_active, created_at, updated_at
            ) VALUES (
                :type, :name, :base_url, :timeout_seconds, :is_active, NOW(), NOW()
            )'
        );
        $statement->execute([
            'type' => $typeValue,
            'name' => $nameValue,
            'base_url' => $baseUrlValue,
            'timeout_seconds' => max(1, $timeoutSeconds),
            'is_active' => $isActive ? 1 : 0,
        ]);

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

    public function updateApiKeyEncrypted(int $integrationId, ?string $encrypted): void
    {
        if ($integrationId <= 0) {
            return;
        }

        $statement = $this->pdo->prepare(
            'UPDATE integrations
            SET api_key_encrypted = :api_key_encrypted,
                updated_at = NOW()
            WHERE id = :id'
        );
        $statement->execute([
            'id' => $integrationId,
            'api_key_encrypted' => StringHelper::nullableString((string) $encrypted),
        ]);
    }

    public function getApiKeyEncrypted(int $integrationId): ?string
    {
        if ($integrationId <= 0) {
            return null;
        }

        try {
            $statement = $this->pdo->prepare(
                'SELECT api_key_encrypted FROM integrations WHERE id = :id LIMIT 1'
            );
            $statement->execute(['id' => $integrationId]);
            $value = $statement->fetchColumn();
        } catch (Throwable) {
            return null;
        }

        if (!is_string($value)) {
            return null;
        }

        $trimmed = trim($value);
        return $trimmed === '' ? null : $trimmed;
    }

}
