import type { TypedFetchConfig } from '../types/config.js'
import { mergeConfig } from '../types/config.js'
import { mergePartialConfig } from './body-utils.js'

export type TypedFetchPreset =
  | TypedFetchConfig
  | ((current: Required<TypedFetchConfig>) => TypedFetchConfig)

export function applyPresetChain(
  current: Required<TypedFetchConfig>,
  presets: TypedFetchPreset[]
): { overrides: TypedFetchConfig; preview: Required<TypedFetchConfig> } {
  let preview = current
  let overrides: TypedFetchConfig = {}

  for (const preset of presets) {
    const patch = typeof preset === 'function' ? preset(preview) : preset
    overrides = mergePartialConfig(overrides, patch)
    preview = mergeConfig(preview, patch)
  }

  return { overrides, preview }
}

export const presets = {
  browser(): TypedFetchPreset {
    return () => ({
      cache: { ttl: 60000, maxSize: 200, enabled: true },
      retry: { maxAttempts: 2, delays: [100, 300, 600] },
      request: {
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json'
        }
      }
    })
  },
  resilient(): TypedFetchPreset {
    return () => ({
      retry: { maxAttempts: 5, delays: [100, 250, 500, 1000, 2000] },
      circuit: { threshold: 3, timeout: 45000, enabled: true },
      metrics: { enabled: true }
    })
  },
  offlineFirst(): TypedFetchPreset {
    return () => ({
      cache: { ttl: 5 * 60 * 1000, maxSize: 1000, enabled: true },
      retry: { maxAttempts: 4, delays: [100, 250, 500, 1000] },
      debug: { verbose: false }
    })
  },
  jsonApi(): TypedFetchPreset {
    return () => ({
      request: {
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json'
        }
      }
    })
  },
  auth: {
    bearer(token: string): TypedFetchPreset {
      return () => ({
        request: {
          headers: {
            Authorization: token.startsWith('Bearer') ? token : `Bearer ${token}`
          }
        }
      })
    }
  }
}
