<?php

namespace MintyPHP\Module\Helpdesk\Repository;

use MintyPHP\DB;
use MintyPHP\Service\Settings\SettingsCryptoGatewayInterface;

/**
 * Repository for OAuth2 token cache (helpdesk_oauth_token_cache table).
 *
 * All tokens are stored encrypted and tenant-scoped.
 * This is part of the OAuth2 skeleton for V1.
 */
class HelpdeskTokenRepository
{
    public function __construct(
        private readonly SettingsCryptoGatewayInterface $settingsCryptoGateway
    ) {
    }

    /**
     * Find a valid (non-expired) cached token for the given tenant.
     */
    public function findValidToken(int $tenantId): ?string
    {
        if ($tenantId <= 0) {
            return null;
        }

        $result = DB::selectOne(
            'SELECT access_token_encrypted FROM helpdesk_oauth_token_cache WHERE tenant_id = ? AND expires_at > NOW() ORDER BY created_at DESC LIMIT 1',
            (string) $tenantId
        );

        // MintyPHP wraps selectOne results in ['table_name' => [...]]
        $row = is_array($result) ? ($result['helpdesk_oauth_token_cache'] ?? $result) : null;
        if (!is_array($row) || !isset($row['access_token_encrypted'])) {
            return null;
        }

        $encrypted = trim((string) $row['access_token_encrypted']);
        if ($encrypted === '') {
            return null;
        }

        try {
            return $this->settingsCryptoGateway->decryptString($encrypted);
        } catch (\Throwable) {
            return null;
        }
    }

    /**
     * Delete all cached tokens (used when global BC config changes).
     */
    public function deleteAll(): bool
    {
        return (bool) DB::delete('DELETE FROM helpdesk_oauth_token_cache WHERE 1=1');
    }

    /**
     * Delete cached tokens for a specific tenant (used when tenant config changes).
     */
    public function deleteByTenantId(int $tenantId): bool
    {
        if ($tenantId <= 0) {
            return false;
        }

        return (bool) DB::delete(
            'DELETE FROM helpdesk_oauth_token_cache WHERE tenant_id = ?',
            (string) $tenantId
        );
    }

    /**
     * Store a new token in the cache (encrypted, tenant-scoped).
     */
    public function storeToken(int $tenantId, string $accessToken, \DateTimeInterface $expiresAt): bool
    {
        if ($tenantId <= 0 || $accessToken === '') {
            return false;
        }

        try {
            $encrypted = $this->settingsCryptoGateway->encryptString($accessToken);
        } catch (\Throwable) {
            return false;
        }

        // Remove existing tokens for this tenant first
        DB::delete(
            'DELETE FROM helpdesk_oauth_token_cache WHERE tenant_id = ?',
            (string) $tenantId
        );

        return (bool) DB::insert(
            'INSERT INTO helpdesk_oauth_token_cache (tenant_id, access_token_encrypted, expires_at) VALUES (?, ?, ?)',
            (string) $tenantId,
            $encrypted,
            $expiresAt->format('Y-m-d H:i:s')
        );
    }
}
