import type { BookingsData, StaffMember, GeneralTask, PickupData, TimeReqs, WfDayData, Adjustment } from './types'

const BASE = '/hk-planner/api'

export interface ConfigData {
  time_requirements: TimeReqs
  staff_data: StaffMember[]
  pickup_data: PickupData
  general_tasks: GeneralTask[]
  last_reviewed: string
  workforce_departments: string[]
  adjustments: Adjustment[]
  warn_over_red_hrs: number
  warn_over_amber_hrs: number
  warn_under_amber_hrs: number
  warn_under_red_hrs: number
}

export interface CategoryConfig {
  id: string
  name: string
  room_count: number
  excluded: boolean
}

async function request<T>(path: string, opts?: RequestInit): Promise<T> {
  const res = await fetch(BASE + path, { credentials: 'include', ...opts })
  if (res.status === 401) {
    ;(window.top ?? window).location.href = '/login'
    throw new Error('Unauthenticated')
  }
  if (!res.ok) {
    const body = await res.json().catch(() => ({})) as { error?: string }
    throw new Error(body.error || `HTTP ${res.status}`)
  }
  return res.json() as Promise<T>
}

export function getBookings(weekStart?: string, lastViewed?: string, forceRefresh = false): Promise<BookingsData> {
  const p = new URLSearchParams()
  if (weekStart)    p.set('week_start',    weekStart)
  if (lastViewed)   p.set('last_viewed',   lastViewed)
  if (forceRefresh) p.set('force_refresh', '1')
  return request<BookingsData>(`/bookings?${p}`)
}

export function getConfig(): Promise<ConfigData> {
  return request<ConfigData>('/config')
}

export function putTimeReq(cat: string, action: string, value: number): Promise<{ ok: boolean }> {
  return request('/config/time-requirements', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ cat, action, value }),
  })
}

export function putStaff(staff_data: StaffMember[]): Promise<{ ok: boolean }> {
  return request('/config/staff', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ staff_data }),
  })
}

export function putPickup(pickup_data: PickupData): Promise<{ ok: boolean }> {
  return request('/config/pickup', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ pickup_data }),
  })
}

export function putGeneralTasks(general_tasks: GeneralTask[]): Promise<{ ok: boolean }> {
  return request('/config/general-tasks', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ general_tasks }),
  })
}

export function putLastReviewed(date: string): Promise<{ ok: boolean }> {
  return request('/config/last-reviewed', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ date }),
  })
}

export function getCategories(): Promise<{ categories: CategoryConfig[] }> {
  return request('/categories')
}

export function putCategories(order: string[], excluded: string[]): Promise<{ ok: boolean }> {
  return request('/categories', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ order, excluded }),
  })
}

export function testNewbook(): Promise<{ ok: boolean; message?: string; error?: string }> {
  return request('/newbook/test', { method: 'POST' })
}

export function getWorkforceDepartments(): Promise<{ id: string; name: string }[]> {
  return request('/workforce/departments')
}

export function putWorkforceDepartments(dept_ids: string[]): Promise<{ ok: boolean }> {
  return request('/config/workforce-departments', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ dept_ids }),
  })
}

export function syncWorkforce(): Promise<{ ok: boolean; from: string; to: string; dates_synced: number }> {
  return request('/workforce/sync', { method: 'POST' })
}

export function getWorkforceShifts(start: string, end: string): Promise<Record<string, WfDayData>> {
  return request(`/workforce/shifts?start=${start}&end=${end}`)
}

export function getWorkforceStaff(): Promise<{ id: string; name: string }[]> {
  return request('/workforce/staff')
}

export function putAdjustments(adjustments: Adjustment[]): Promise<{ ok: boolean }> {
  return request('/config/adjustments', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ adjustments }),
  })
}

export function putWarningThresholds(thresholds: {
  warn_over_red_hrs: number
  warn_over_amber_hrs: number
  warn_under_amber_hrs: number
  warn_under_red_hrs: number
}): Promise<{ ok: boolean }> {
  return request('/config/warning-thresholds', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(thresholds),
  })
}
