import type { SecretsHealthStatus } from '../monitoring/types'

interface SecretCheckConfig {
  name: string
  requiredInProduction: boolean
}

const SECRET_CONFIGS: SecretCheckConfig[] = [
  { name: 'PAYLOAD_SECRET', requiredInProduction: true },
  { name: 'CRON_SECRET', requiredInProduction: true },
  { name: 'CSRF_SECRET', requiredInProduction: false },
  { name: 'SMTP_PASS', requiredInProduction: false },
  { name: 'GOOGLE_CLIENT_SECRET', requiredInProduction: false },
  { name: 'META_APP_SECRET', requiredInProduction: false },
  { name: 'REDIS_PASSWORD', requiredInProduction: false },
]

function parseDate(value: string | undefined): Date | null {
  if (!value) return null
  const parsed = new Date(value)
  return Number.isNaN(parsed.getTime()) ? null : parsed
}

function getWarningDays(): number {
  const value = parseInt(process.env.SECRET_EXPIRY_WARNING_DAYS || '14', 10)
  return Number.isNaN(value) || value < 1 ? 14 : value
}

function getMaxRotationDays(): number {
  const value = parseInt(process.env.SECRET_ROTATION_MAX_DAYS || '90', 10)
  return Number.isNaN(value) || value < 1 ? 90 : value
}

function isMissingSecret(name: string): boolean {
  const value = process.env[name]
  return !value || value.trim().length === 0
}

export function checkSecretsHealth(referenceDate = new Date()): SecretsHealthStatus {
  const warningDays = getWarningDays()
  const maxRotationDays = getMaxRotationDays()
  const isProduction = process.env.NODE_ENV === 'production'

  const missing: string[] = []
  const expiringSoon: SecretsHealthStatus['expiringSoon'] = []
  const expired: SecretsHealthStatus['expired'] = []
  const rotationOverdue: SecretsHealthStatus['rotationOverdue'] = []

  for (const config of SECRET_CONFIGS) {
    if (!isProduction && config.requiredInProduction) {
      continue
    }

    const isMissing = isMissingSecret(config.name)
    if (isMissing && (isProduction ? config.requiredInProduction : false)) {
      missing.push(config.name)
      continue
    }
    if (isMissing) {
      continue
    }

    const expiresAt = parseDate(process.env[`${config.name}_EXPIRES_AT`])
    if (expiresAt) {
      const diffMs = expiresAt.getTime() - referenceDate.getTime()
      const daysRemaining = Math.floor(diffMs / (24 * 60 * 60 * 1000))
      if (diffMs <= 0) {
        expired.push({
          name: config.name,
          expiresAt: expiresAt.toISOString(),
        })
      } else if (daysRemaining <= warningDays) {
        expiringSoon.push({
          name: config.name,
          expiresAt: expiresAt.toISOString(),
          daysRemaining,
        })
      }
    }

    const rotatedAt = parseDate(process.env[`${config.name}_ROTATED_AT`])
    if (rotatedAt) {
      const ageDays = Math.floor(
        (referenceDate.getTime() - rotatedAt.getTime()) / (24 * 60 * 60 * 1000),
      )
      if (ageDays > maxRotationDays) {
        rotationOverdue.push({
          name: config.name,
          rotatedAt: rotatedAt.toISOString(),
          ageDays,
        })
      }
    }
  }

  const status: SecretsHealthStatus['status'] =
    missing.length > 0 || expired.length > 0
      ? 'critical'
      : expiringSoon.length > 0 || rotationOverdue.length > 0
        ? 'warning'
        : 'ok'

  return {
    status,
    checkedAt: referenceDate.toISOString(),
    missing,
    expiringSoon,
    expired,
    rotationOverdue,
  }
}

