import { get, writable } from "svelte/store";
import {
  createList as createListCommand,
  deleteList as deleteListCommand,
  listLists,
  updateList as updateListCommand,
  type ListDocumentDto,
} from "$lib/backend/lists";

export type ListItem = {
  id: string;
  label: string;
  initialContent: string;
};

export const listsStore = writable<ListItem[]>([]);
export const listsBusyStore = writable(false);

function toStoreId(id: string): string {
  return `lists/${id}`;
}

function toBackendId(id: string): string | null {
  const prefix = "lists/";
  if (!id.startsWith(prefix)) return null;
  const backendId = id.slice(prefix.length).trim();
  return backendId || null;
}

function dtoToItem(dto: ListDocumentDto): ListItem {
  return {
    id: toStoreId(dto.id),
    label: dto.label,
    initialContent: dto.content || `# ${dto.label}\n\n`,
  };
}

function upsertById(items: ListItem[], next: ListItem): ListItem[] {
  const idx = items.findIndex((item) => item.id === next.id);
  if (idx === -1) return [next, ...items];
  const clone = [...items];
  clone[idx] = next;
  return clone;
}

export function createListDraft(): ListItem {
  const id = `lists/draft-${Date.now()}`;
  return {
    id,
    label: "Untitled List",
    initialContent: "# Untitled List\n\n- Item 1",
  };
}

export async function hydrateLists(): Promise<void> {
  listsBusyStore.set(true);
  try {
    const items = await listLists();
    listsStore.set(items.map(dtoToItem));
  } catch (error) {
    console.error("[lists] hydrate:error", error);
    throw error;
  } finally {
    listsBusyStore.set(false);
  }
}

export async function createListFromLabel(
  label: string,
  content = "",
): Promise<ListItem> {
  const resolvedLabel = label.trim() || "Untitled List";
  const resolvedContent = content || `# ${resolvedLabel}\n\n`;
  const created = await createListCommand({
    label: resolvedLabel,
    content: resolvedContent,
  });
  const item = dtoToItem(created);
  listsStore.update((items) => [item, ...items]);
  return item;
}

export async function updateListByStoreId(
  storeId: string,
  label?: string,
  content?: string,
): Promise<boolean> {
  const backendId = toBackendId(storeId);
  if (!backendId) return false;

  const payload: { label?: string; content?: string } = {};
  if (label !== undefined) payload.label = label;
  if (content !== undefined) payload.content = content;

  const ok = await updateListCommand(backendId, payload);
  if (!ok) return false;

  listsStore.update((items) =>
    items.map((item) =>
      item.id === storeId
        ? {
            ...item,
            label: label ?? item.label,
            initialContent: content ?? item.initialContent,
          }
        : item,
    ),
  );
  return true;
}

export async function deleteListByStoreId(storeId: string): Promise<boolean> {
  const backendId = toBackendId(storeId);
  if (!backendId) return false;

  const ok = await deleteListCommand(backendId);
  if (!ok) return false;
  listsStore.update((items) => items.filter((item) => item.id !== storeId));
  return true;
}

export function hasList(storeId: string): boolean {
  return get(listsStore).some((item) => item.id === storeId);
}
