function normalizeAssetPrefix(rawValue, basePath) {
  if (!rawValue) return undefined

  try {
    const url = new URL(rawValue)
    const pathname = url.pathname.replace(/\/$/, '')
    if (!pathname.endsWith(basePath)) {
      url.pathname = `${pathname}${basePath}`
    }
    return url.toString().replace(/\/$/, '')
  } catch {
    const trimmed = rawValue.replace(/\/$/, '')
    return trimmed.endsWith(basePath) ? trimmed : `${trimmed}${basePath}`
  }
}

function collectOrigins(assetSources) {
  const origins = new Set()

  for (const source of assetSources) {
    if (!source) continue

    try {
      origins.add(new URL(source).origin)
    } catch {
      continue
    }
  }

  return [...origins]
}

function collectWebSocketOrigins(assetSources) {
  const origins = new Set()

  for (const source of assetSources) {
    if (!source) continue

    try {
      const url = new URL(source)
      const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
      origins.add(`${protocol}//${url.host}`)
    } catch {
      continue
    }
  }

  return [...origins]
}

function collectBrowserApiSources() {
  const sources = [process.env.NEXT_PUBLIC_API_URL, process.env.API_URL]

  if (process.env.NODE_ENV !== 'production') {
    sources.push('http://localhost:4000/api/v1')
  }

  return sources
}

function buildSecurityHeaders({ assetSources = [], connectSources = collectBrowserApiSources() } = {}) {
  const assetOrigins = collectOrigins(assetSources)
  const connectOrigins = collectOrigins(connectSources)
  const websocketOrigins = [
    ...collectWebSocketOrigins(assetSources),
    ...collectWebSocketOrigins(connectSources),
  ]

  const scriptSrc = ["'self'", "'unsafe-inline'"]
  if (process.env.NODE_ENV !== 'production') {
    scriptSrc.push("'unsafe-eval'")
  }
  scriptSrc.push(...assetOrigins)

  const styleSrc = ["'self'", "'unsafe-inline'", ...assetOrigins]
  const imgSrc = [...new Set(["'self'", 'data:', 'blob:', 'https:', ...assetOrigins, ...connectOrigins])]
  const fontSrc = ["'self'", 'data:', ...assetOrigins]
  const connectSrc = [...new Set(["'self'", 'https:', 'wss:', ...assetOrigins, ...connectOrigins, ...websocketOrigins])]

  return [
    { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
    { key: 'X-Content-Type-Options', value: 'nosniff' },
    { key: 'X-Frame-Options', value: 'DENY' },
    { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
    { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
    {
      key: 'Content-Security-Policy',
      value: [
        "default-src 'self'",
        `script-src ${scriptSrc.join(' ')}`,
        `style-src ${styleSrc.join(' ')}`,
        `img-src ${imgSrc.join(' ')}`,
        `font-src ${fontSrc.join(' ')}`,
        `connect-src ${connectSrc.join(' ')}`,
        "frame-ancestors 'none'",
        "base-uri 'self'",
        "form-action 'self'",
        "object-src 'none'",
      ].join('; '),
    },
  ]
}

module.exports = {
  buildSecurityHeaders,
  normalizeAssetPrefix,
}
