import { sendCommand } from "./client";
import { pickCase } from "./normalize";

export type TodoItemDto = {
  id: string;
  listId: string;
  text: string;
  done: boolean;
  sortOrder: number;
};

export type TodoListDto = {
  id: string;
  label: string;
  createdAt: string;
  items: TodoItemDto[];
};

export type CreateTodoListPayload = {
  label: string;
};

export type UpdateTodoListPayload = {
  label?: string;
};

export type CreateTodoItemPayload = {
  listId: string;
  text: string;
  sortOrder?: number;
};

export type UpdateTodoItemPayload = {
  text?: string;
  done?: boolean;
  sortOrder?: number;
};

type TodoItemDtoRaw = {
  id?: string;
  listId?: string;
  text?: string;
  done?: boolean;
  sortOrder?: number;
  Id?: string;
  ListId?: string;
  Text?: string;
  Done?: boolean;
  SortOrder?: number;
};

type TodoListDtoRaw = {
  id?: string;
  label?: string;
  createdAt?: string;
  items?: TodoItemDtoRaw[];
  Id?: string;
  Label?: string;
  CreatedAt?: string;
  Items?: TodoItemDtoRaw[];
};

function normalizeItem(raw: TodoItemDtoRaw): TodoItemDto {
  return {
    id: pickCase(raw, "id", "Id", ""),
    listId: pickCase(raw, "listId", "ListId", ""),
    text: pickCase(raw, "text", "Text", ""),
    done: pickCase(raw, "done", "Done", false),
    sortOrder: pickCase(raw, "sortOrder", "SortOrder", 0),
  };
}

function normalizeList(raw: TodoListDtoRaw): TodoListDto {
  const rawItems = pickCase(raw, "items", "Items", [] as TodoItemDtoRaw[]);
  return {
    id: pickCase(raw, "id", "Id", ""),
    label: pickCase(raw, "label", "Label", ""),
    createdAt: pickCase(raw, "createdAt", "CreatedAt", ""),
    items: rawItems.map(normalizeItem),
  };
}

export async function listTodoLists(): Promise<TodoListDto[]> {
  const data = await sendCommand<TodoListDtoRaw[]>({
    action: "todos.list",
  });
  return data.map(normalizeList).filter((item) => Boolean(item.id));
}

export async function getTodoList(id: string): Promise<TodoListDto | null> {
  const data = await sendCommand<TodoListDtoRaw | null>({
    action: "todos.get",
    id,
  });
  if (!data) return null;
  const normalized = normalizeList(data);
  return normalized.id ? normalized : null;
}

export async function createTodoList(
  payload: CreateTodoListPayload,
): Promise<TodoListDto> {
  const data = await sendCommand<TodoListDtoRaw>({
    action: "todos.create",
    payload,
  });
  return normalizeList(data);
}

export function updateTodoList(
  id: string,
  payload: UpdateTodoListPayload,
): Promise<boolean> {
  return sendCommand<boolean>({
    action: "todos.update",
    id,
    payload,
  });
}

export function deleteTodoList(id: string): Promise<boolean> {
  return sendCommand<boolean>({
    action: "todos.delete",
    id,
  });
}

export async function createTodoItem(
  payload: CreateTodoItemPayload,
): Promise<TodoItemDto> {
  const data = await sendCommand<TodoItemDtoRaw>({
    action: "todos.items.create",
    payload,
  });
  return normalizeItem(data);
}

export function updateTodoItem(
  id: string,
  payload: UpdateTodoItemPayload,
): Promise<boolean> {
  return sendCommand<boolean>({
    action: "todos.items.update",
    id,
    payload,
  });
}

export function deleteTodoItem(id: string): Promise<boolean> {
  return sendCommand<boolean>({
    action: "todos.items.delete",
    id,
  });
}
