import crypto from 'crypto'
import { prisma } from '@/lib/prisma'

/**
 * Service for managing Hub API keys with SHA-256 hashing.
 * API keys are stored as hashes to prevent plaintext exposure in the database.
 */
class ApiKeyService {
  private static instance: ApiKeyService

  static getInstance(): ApiKeyService {
    if (!ApiKeyService.instance) {
      ApiKeyService.instance = new ApiKeyService()
    }
    return ApiKeyService.instance
  }

  /**
   * Generate a new Hub API key with prefix
   */
  generateKey(): string {
    return `hk_${crypto.randomBytes(32).toString('hex')}`
  }

  /**
   * Hash an API key using SHA-256
   */
  hashKey(key: string): string {
    return crypto.createHash('sha256').update(key).digest('hex')
  }

  /**
   * Find a server connection by API key (checks both plaintext and hash)
   * During migration, we check both fields. Once all keys are migrated,
   * the plaintext hubApiKey column can be removed.
   */
  async findByApiKey(apiKey: string) {
    const hash = this.hashKey(apiKey)

    // First try hash lookup (preferred)
    let connection = await prisma.serverConnection.findUnique({
      where: { hubApiKeyHash: hash },
      include: {
        order: {
          select: {
            id: true,
            domain: true,
            serverIp: true,
          },
        },
      },
    })

    if (connection) return connection

    // Fallback to plaintext lookup during migration
    connection = await prisma.serverConnection.findUnique({
      where: { hubApiKey: apiKey },
      include: {
        order: {
          select: {
            id: true,
            domain: true,
            serverIp: true,
          },
        },
      },
    })

    // If found via plaintext, migrate to hash
    if (connection && !connection.hubApiKeyHash) {
      await prisma.serverConnection.update({
        where: { id: connection.id },
        data: { hubApiKeyHash: hash },
      })
    }

    return connection
  }
}

export const apiKeyService = ApiKeyService.getInstance()
