import type { ActivitySeverity } from '@overdeck/activity-contract'

export type ReportRange = '1h' | '24h' | '3d' | '7d' | '30d' | '90d'

export interface ReportUrlState {
  range: ReportRange
  projects: string[]
  sources: string[]
  severity?: ActivitySeverity
  q: string
}

export const DEFAULT_REPORT_URL_STATE: ReportUrlState = {
  range: '24h',
  projects: [],
  sources: [],
  q: '',
}

export const REPORT_RANGE_MS: Record<ReportRange, number> = {
  '1h': 60 * 60 * 1000,
  '24h': 24 * 60 * 60 * 1000,
  '3d': 3 * 24 * 60 * 60 * 1000,
  '7d': 7 * 24 * 60 * 60 * 1000,
  '30d': 30 * 24 * 60 * 60 * 1000,
  '90d': 90 * 24 * 60 * 60 * 1000,
}

const VALID_RANGES = new Set<ReportRange>(['1h', '24h', '3d', '7d', '30d', '90d'])
const VALID_SEVERITIES = new Set<ActivitySeverity>(['warn', 'error'])

function distinct(values: string[]): string[] {
  return [...new Set(values.map((value) => value.trim()).filter(Boolean))]
}

export function parseReportUrlState(search: string): ReportUrlState {
  const params = new URLSearchParams(search)
  const rangeValue = params.get('range')
  const severityValue = params.get('severity')
  const range = VALID_RANGES.has(rangeValue as ReportRange)
    ? rangeValue as ReportRange
    : DEFAULT_REPORT_URL_STATE.range
  const severity = VALID_SEVERITIES.has(severityValue as ActivitySeverity)
    ? severityValue as ActivitySeverity
    : undefined

  return {
    range,
    projects: distinct(params.getAll('project')),
    sources: distinct(params.getAll('source')),
    ...(severity ? { severity } : {}),
    q: (params.get('q') ?? '').trim(),
  }
}

export function serializeReportUrlState(state: ReportUrlState): string {
  const params = new URLSearchParams()
  if (state.range !== DEFAULT_REPORT_URL_STATE.range) params.set('range', state.range)
  distinct(state.projects).forEach((project) => params.append('project', project))
  distinct(state.sources).forEach((source) => params.append('source', source))
  if (state.severity) params.set('severity', state.severity)
  if (state.q.trim()) params.set('q', state.q.trim())
  const query = params.toString()
  return query ? `?${query}` : ''
}
