import { describe, expect, it, vi, beforeEach } from "vitest";
import { appRouter } from "./routers";
import type { TrpcContext } from "./_core/context";

// Mock db helpers
vi.mock("./db", () => ({
  getDocumentsByUser: vi.fn().mockResolvedValue([
    { id: 1, userId: 1, fileId: null, title: "Test Doc", content: "Hello world", wordCountGoal: 500, createdAt: new Date(), updatedAt: new Date() },
  ]),
  getDocumentById: vi.fn().mockResolvedValue(
    { id: 1, userId: 1, fileId: null, title: "Test Doc", content: "Hello world", wordCountGoal: 500, createdAt: new Date(), updatedAt: new Date() }
  ),
  createDocument: vi.fn().mockResolvedValue(42),
  saveDocument: vi.fn().mockResolvedValue(undefined),
  deleteDocument: vi.fn().mockResolvedValue(undefined),
  getFilesByUser: vi.fn().mockResolvedValue([]),
  getFileById: vi.fn().mockResolvedValue(null),
  createFile: vi.fn().mockResolvedValue(99),
  updateFile: vi.fn().mockResolvedValue(undefined),
  deleteFile: vi.fn().mockResolvedValue(undefined),
  upsertUser: vi.fn(),
  getUserByOpenId: vi.fn(),
}));

function makeCtx(): TrpcContext {
  return {
    user: {
      id: 1,
      openId: "test-user",
      email: "test@example.com",
      name: "Test User",
      loginMethod: "manus",
      role: "user",
      createdAt: new Date(),
      updatedAt: new Date(),
      lastSignedIn: new Date(),
    },
    req: { protocol: "https", headers: {} } as TrpcContext["req"],
    res: { clearCookie: vi.fn() } as unknown as TrpcContext["res"],
  };
}

describe("documents procedures", () => {
  it("list returns documents for the current user", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.documents.list({});
    expect(result).toHaveLength(1);
    expect(result[0].title).toBe("Test Doc");
  });

  it("get returns a single document", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const doc = await caller.documents.get({ id: 1 });
    expect(doc.id).toBe(1);
    expect(doc.content).toBe("Hello world");
  });

  it("create returns a new document id", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.documents.create({ title: "New Doc", wordCountGoal: 1000 });
    expect(result.id).toBe(42);
  });

  it("save returns success", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.documents.save({ id: 1, content: "Updated content" });
    expect(result.success).toBe(true);
  });

  it("delete returns success", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.documents.delete({ id: 1 });
    expect(result.success).toBe(true);
  });

  it("list requires authentication", async () => {
    const ctx: TrpcContext = { ...makeCtx(), user: null };
    const caller = appRouter.createCaller(ctx);
    await expect(caller.documents.list({})).rejects.toThrow();
  });

  it("files.list returns empty list for new user", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.files.list();
    expect(Array.isArray(result)).toBe(true);
  });

  it("files.create returns a new file id", async () => {
    const caller = appRouter.createCaller(makeCtx());
    const result = await caller.files.create({ name: "My Novel" });
    expect(result.id).toBe(99);
  });
});
