import { expect, type Page } from "@playwright/test";

export const 用户 = {
  主用户: { id: "user-primary", name: "测试一", password: "test12345" },
  成员: { id: "user-member", name: "测试二", password: "test12345" },
};

export const 账本 = {
  个人: { id: "ledger-personal", name: "个人账本", role: "owner", isPersonal: true },
  家庭: { id: "ledger-family", name: "家庭账本", role: "owner", isPersonal: false },
};

type Entry = Record<string, unknown>;

export function makeEntry(overrides: Partial<Entry> = {}): Entry {
  return {
    id: "entry-lunch",
    ownerId: 用户.主用户.id,
    ledgerIds: [账本.个人.id, 账本.家庭.id],
    type: "expense",
    amount: 3200,
    currency: "CNY",
    baseCurrency: "CNY",
    baseAmount: 3200,
    exchangeRate: "1",
    exchangeRateDate: "2026-08-01",
    exchangeRateEffectiveDate: "2026-08-01",
    exchangeRateSource: "system",
    conversionStatus: "exact",
    reimbursementOfEntryId: null,
    categoryId: "restaurant",
    note: "午餐",
    occurredAt: "2026-08-01T12:00:00.000Z",
    createdBy: 用户.主用户.id,
    updatedBy: 用户.主用户.id,
    createdAt: "2026-08-01T12:00:00.000Z",
    updatedAt: "2026-08-01T12:00:00.000Z",
    deletedAt: null,
    version: 1,
    ...overrides,
  };
}

export type MockOptions = {
  initialEntries?: Entry[];
  currentUser?: typeof 用户.主用户 | typeof 用户.成员 | null;
  memberRole?: "owner" | "member";
  apiAvailable?: boolean;
};

export async function mockApi(page: Page, options: MockOptions = {}) {
  const state = {
    currentUser: options.currentUser ?? null,
    entries: [...(options.initialEntries ?? [])],
    ledgers: [
      { ...账本.个人, defaultCurrency: "CNY", theme: "jade", icon: "wallet", archivedAt: null },
      { ...账本.家庭, defaultCurrency: "CNY", theme: "coral", icon: "users", archivedAt: null, role: options.memberRole ?? "owner" },
    ],
    apiAvailable: options.apiAvailable ?? true,
    requestPaths: [] as string[],
  };

  await page.route("**/api/**", async (route) => {
    const request = route.request();
    const url = new URL(request.url());
    state.requestPaths.push(`${request.method()} ${url.pathname}`);
    if (!state.apiAvailable) {
      await route.abort("failed");
      return;
    }

    const json = async (body: unknown, status = 200) => route.fulfill({ status, contentType: "application/json", body: JSON.stringify(body) });
    if (url.pathname === "/api/auth/session") return json({ user: state.currentUser });
    if (url.pathname === "/api/auth/login" && request.method() === "POST") {
      const body = request.postDataJSON() as { name?: string; password?: string };
      const account = Object.values(用户).find((item) => item.name === body.name && item.password === body.password);
      if (!account) return json({ error: "姓名或密码错误" }, 401);
      state.currentUser = account;
      return json({ user: account });
    }
    if (url.pathname === "/api/auth/logout") {
      state.currentUser = null;
      return json({ ok: true });
    }
    if (url.pathname === "/api/ledgers") {
      if (request.method() === "POST") {
        const body = request.postDataJSON() as { name: string; defaultCurrency?: string; theme?: string; icon?: string };
        const created = { id: `ledger-${state.entries.length + 10}`, name: body.name, role: "owner", isPersonal: false, defaultCurrency: body.defaultCurrency ?? "CNY", theme: body.theme ?? "jade", icon: body.icon ?? "wallet", archivedAt: null };
        state.ledgers.push(created);
        return json({ ledger: created }, 201);
      }
      return json({ ledgers: state.ledgers });
    }
    if (/^\/api\/ledgers\/[^/]+\/members$/.test(url.pathname)) return json({ members: [{ id: 用户.主用户.id, name: 用户.主用户.name, role: options.memberRole ?? "owner", joinedAt: "2026-08-01" }] });
    if (url.pathname.startsWith("/api/ledgers/") && request.method() === "PATCH") return json({ ledger: {} });
    if (url.pathname === "/api/sync/pull") return json({ entries: state.entries, cursor: "cursor-1", hasMore: false });
    if (url.pathname === "/api/sync/push" && request.method() === "POST") {
      const body = request.postDataJSON() as { operations?: Array<{ id: string; action: string; payload: Entry }> };
      for (const operation of body.operations ?? []) {
        if (operation.action === "delete") continue;
        const index = state.entries.findIndex((entry) => entry.id === operation.payload.id);
        if (index >= 0) state.entries[index] = operation.payload;
        else state.entries.push(operation.payload);
      }
      return json({ acceptedOperationIds: (body.operations ?? []).map((operation) => operation.id) });
    }
    if (/^\/api\/exchange-rates\//.test(url.pathname)) {
      const [, , currency, date] = url.pathname.split("/");
      return json({ rate: { currency, requestedDate: date, effectiveDate: date, cnyPerUnit: currency === "USD" ? "7.2" : "1", status: "exact" } });
    }
    if (url.pathname === "/api/me") return json({ user: state.currentUser });
    return json({ error: "未模拟的测试 API" }, 404);
  });

  return state;
}

export async function 登录(page: Page, user = 用户.主用户) {
  await page.goto("/login");
  await page.getByLabel("姓名").fill(user.name);
  await page.locator('input[autocomplete="current-password"]').fill(user.password);
  await page.getByRole("button", { name: "登录" }).click();
  await expect(page).toHaveURL(/\/$/);
  await expect(page.getByLabel("账本流水")).toBeVisible();
}
