import { Todo, type TodoJSON } from "./todo"
import { ensure } from "@workshop/shared/utils"

type TodoHeader = {
  title?: string
  todos: (Todo | string)[]
}

export type TodoList = TodoHeader[]

export const parseTodoList = (input: string): TodoList => {
  const lines = input.split("\n")
  const todoList: TodoList = []
  let currentHeader: TodoHeader = { todos: [] }
  let parentStack: Todo[] = []

  lines.forEach((line) => {
    if (line.startsWith("#")) {
      currentHeader = { title: line, todos: [] }
      todoList.push(currentHeader)
    } else {
      const todo = Todo.parse(line)

      if (todo) {
        for (let i = parentStack.length - 1; i >= 0; i--) {
          const parent = parentStack[i]
          ensure(parent, `Parent at index ${i} should not be undefined`)

          if (todo.indent.length > parent.indent.length) {
            parent.addChild(todo)
            parentStack.push(todo)
            return
          }
        }

        currentHeader.todos.push(todo)
        parentStack = [todo]
        return
      } else {
        currentHeader.todos.push(line)
      }
    }
  })

  return todoList
}

export const todoListToString = (todoList: TodoList): string => {
  let output = ""

  todoList.forEach((header) => {
    if (header.title) {
      output += `${header.title}\n`
    }

    header.todos.forEach((todo) => {
      if (typeof todo === "string") {
        output += `${todo}\n`
      } else {
        output += todoJsonToString(todo)
      }
    })
  })

  return output
}

const todoJsonToString = (todoOrString: Todo): string => {
  let result = `${todoOrString.indent}[${todoOrString.done ? "x" : " "}] ${todoOrString.text}\n`

  todoOrString.children.forEach((child) => {
    result += todoJsonToString(child)
  })

  return result
}
