export type TodoStatus = 'pending' | 'in_progress' | 'completed' | 'cancelled'

export interface TodoItem {
  content: string
  id: string
  status: TodoStatus
}

const STATUSES: readonly TodoStatus[] = ['pending', 'in_progress', 'completed', 'cancelled']

const isRecord = (v: unknown): v is Record<string, unknown> => Boolean(v && typeof v === 'object' && !Array.isArray(v))
const isStatus = (v: unknown): v is TodoStatus => (STATUSES as readonly string[]).includes(v as string)

function parseArray(value: unknown[]): TodoItem[] {
  return value.flatMap(item => {
    if (!isRecord(item) || !isStatus(item.status)) {return []}
    const id = String(item.id ?? '').trim()
    const content = String(item.content ?? '').trim()

    return id && content ? [{ content, id, status: item.status }] : []
  })
}

function parse(value: unknown, depth: number): null | TodoItem[] {
  if (depth > 2) {return null}

  if (Array.isArray(value)) {return parseArray(value)}

  if (typeof value === 'string' && value.trim()) {
    try { return parse(JSON.parse(value), depth + 1) } catch { return null }
  }

  if (isRecord(value) && Object.hasOwn(value, 'todos')) {return parse(value.todos, depth + 1)}

  return null
}

export const parseTodos = (value: unknown): null | TodoItem[] => parse(value, 0)
