import { z } from 'zod';
import * as base from './base.js';
import { generateTodoId } from '../id.js';

/**
 * Todo 状态
 */
export const TodoStatusSchema = z.enum(['pending', 'in_progress', 'completed']);
export type TodoStatus = z.infer<typeof TodoStatusSchema>;

/**
 * Todo Item Schema
 */
export const TodoItemSchema = z.object({
  id: z.string(),
  content: z.string(),
  status: TodoStatusSchema,
  createdAt: z.number(),
  updatedAt: z.number(),
});
export type TodoItem = z.infer<typeof TodoItemSchema>;

/**
 * Todo List Schema (存储在单个文件中)
 */
export const TodoListSchema = z.object({
  sessionId: z.string(),
  items: z.array(TodoItemSchema),
  updatedAt: z.number(),
});
export type TodoList = z.infer<typeof TodoListSchema>;

/**
 * 获取会话的 Todo 列表
 */
export async function get(sessionId: string): Promise<TodoList | null> {
  try {
    return await base.read(['todo', sessionId], TodoListSchema);
  } catch (e) {
    if (e instanceof base.StorageNotFoundError) {
      return null;
    }
    throw e;
  }
}

/**
 * 获取或创建 Todo 列表
 */
export async function getOrCreate(sessionId: string): Promise<TodoList> {
  const existing = await get(sessionId);
  if (existing) return existing;

  const todoList: TodoList = {
    sessionId,
    items: [],
    updatedAt: Date.now(),
  };
  await base.write(['todo', sessionId], todoList);
  return todoList;
}

/**
 * 保存 Todo 列表
 */
export async function save(todoList: TodoList): Promise<void> {
  todoList.updatedAt = Date.now();
  await base.write(['todo', todoList.sessionId], todoList);
}

/**
 * 添加 Todo 项
 */
export async function add(sessionId: string, content: string): Promise<TodoItem> {
  const todoList = await getOrCreate(sessionId);

  const item: TodoItem = {
    id: generateTodoId(),
    content,
    status: 'pending',
    createdAt: Date.now(),
    updatedAt: Date.now(),
  };

  todoList.items.push(item);
  await save(todoList);

  return item;
}

/**
 * 批量添加 Todo 项
 */
export async function addMany(sessionId: string, contents: string[]): Promise<TodoItem[]> {
  const todoList = await getOrCreate(sessionId);
  const now = Date.now();

  const items: TodoItem[] = contents.map((content) => ({
    id: generateTodoId(),
    content,
    status: 'pending' as TodoStatus,
    createdAt: now,
    updatedAt: now,
  }));

  todoList.items.push(...items);
  await save(todoList);

  return items;
}

/**
 * 更新 Todo 项状态
 */
export async function updateStatus(sessionId: string, todoId: string, status: TodoStatus): Promise<TodoItem | null> {
  const todoList = await get(sessionId);
  if (!todoList) return null;

  const item = todoList.items.find((t) => t.id === todoId);
  if (!item) return null;

  item.status = status;
  item.updatedAt = Date.now();

  await save(todoList);
  return item;
}

/**
 * 更新 Todo 项内容
 */
export async function updateContent(sessionId: string, todoId: string, content: string): Promise<TodoItem | null> {
  const todoList = await get(sessionId);
  if (!todoList) return null;

  const item = todoList.items.find((t) => t.id === todoId);
  if (!item) return null;

  item.content = content;
  item.updatedAt = Date.now();

  await save(todoList);
  return item;
}

/**
 * 删除 Todo 项
 */
export async function remove(sessionId: string, todoId: string): Promise<boolean> {
  const todoList = await get(sessionId);
  if (!todoList) return false;

  const index = todoList.items.findIndex((t) => t.id === todoId);
  if (index === -1) return false;

  todoList.items.splice(index, 1);
  await save(todoList);

  return true;
}

/**
 * 清空 Todo 列表
 */
export async function clear(sessionId: string): Promise<void> {
  const todoList = await get(sessionId);
  if (!todoList) return;

  todoList.items = [];
  await save(todoList);
}

/**
 * 删除会话的 Todo 列表
 */
export async function removeBySession(sessionId: string): Promise<void> {
  await base.remove(['todo', sessionId]);
}

/**
 * 替换整个 Todo 列表
 */
export async function replace(sessionId: string, items: Omit<TodoItem, 'id' | 'createdAt' | 'updatedAt'>[]): Promise<TodoList> {
  const now = Date.now();
  const todoList: TodoList = {
    sessionId,
    items: items.map((item) => ({
      id: generateTodoId(),
      content: item.content,
      status: item.status,
      createdAt: now,
      updatedAt: now,
    })),
    updatedAt: now,
  };

  await base.write(['todo', sessionId], todoList);
  return todoList;
}
