import { intelligentEvalsApi, type IntelligentEval } from '../api'

export type ReadPhase = 'idle' | 'loading' | 'refreshing' | 'ready' | 'error'

export interface ReadSlot<T> {
  phase: ReadPhase
  value: T
  error: string | null
}

export interface IntelligentEvalReadState {
  list: ReadSlot<IntelligentEval[]>
  detail: ReadSlot<IntelligentEval | null> & {
    selectedId: string | null
    requestId: number
  }
}

export type IntelligentEvalReadAction =
  | { type: 'list_requested'; silent?: boolean }
  | { type: 'list_succeeded'; value: IntelligentEval[] }
  | { type: 'list_failed'; error: string }
  | { type: 'detail_cleared'; requestId: number }
  | { type: 'detail_requested'; id: string; requestId: number; silent?: boolean }
  | { type: 'detail_succeeded'; id: string; requestId: number; value: IntelligentEval }
  | { type: 'detail_failed'; id: string; requestId: number; error: string }

export interface IntelligentEvalReadAdapter {
  list: () => Promise<IntelligentEval[]>
  get: (id: string) => Promise<IntelligentEval>
}

export const intelligentEvalReadAdapter: IntelligentEvalReadAdapter = {
  list: () => intelligentEvalsApi.list().then((response) => response.data.intelligent_evals),
  get: (id) => intelligentEvalsApi.get(id).then((response) => response.data),
}

export const initialIntelligentEvalReadState: IntelligentEvalReadState = {
  list: { phase: 'idle', value: [], error: null },
  detail: { phase: 'idle', value: null, error: null, selectedId: null, requestId: 0 },
}

function requestPhase<T>(slot: ReadSlot<T>, silent: boolean | undefined): ReadSlot<T> {
  return { ...slot, phase: silent && slot.phase === 'ready' ? 'refreshing' : 'loading', error: null }
}

export function intelligentEvalReadReducer(
  state: IntelligentEvalReadState,
  action: IntelligentEvalReadAction,
): IntelligentEvalReadState {
  switch (action.type) {
    case 'list_requested':
      return { ...state, list: requestPhase(state.list, action.silent) }
    case 'list_succeeded':
      return { ...state, list: { phase: 'ready', value: action.value, error: null } }
    case 'list_failed':
      return {
        ...state,
        list: state.list.value.length > 0
          ? { ...state.list, phase: 'ready', error: null }
          : { ...state.list, phase: 'error', error: action.error },
      }
    case 'detail_cleared':
      return {
        ...state,
        detail: { phase: 'idle', value: null, error: null, selectedId: null, requestId: action.requestId },
      }
    case 'detail_requested': {
      const sameSelection = state.detail.selectedId === action.id
      const current = sameSelection
        ? state.detail
        : { ...state.detail, value: null, selectedId: action.id }
      return {
        ...state,
        detail: { ...requestPhase(current, action.silent), selectedId: action.id, requestId: action.requestId },
      }
    }
    case 'detail_succeeded':
      if (state.detail.selectedId !== action.id || state.detail.requestId !== action.requestId) return state
      return {
        ...state,
        detail: {
          phase: 'ready',
          value: action.value,
          error: null,
          selectedId: action.id,
          requestId: action.requestId,
        },
      }
    case 'detail_failed':
      if (state.detail.selectedId !== action.id || state.detail.requestId !== action.requestId) return state
      return {
        ...state,
        detail: state.detail.value
          ? { ...state.detail, phase: 'ready', error: null }
          : { ...state.detail, phase: 'error', error: action.error },
      }
  }
}
