import { describe, expect, it } from "vitest";
import { appRouter } from "./routers";
import { getSessionCookieOptions } from "./_core/cookies";
import type { TrpcContext } from "./_core/context";
import { inspectImportRows } from "./routers/studentRecords";

function contextFor(role: "admin" | "user" | null): TrpcContext {
  const now = new Date();
  return {
    user: role
      ? {
          id: 1,
          openId: "test-user",
          name: "Test User",
          email: "test@example.com",
          loginMethod: "test",
          role,
          isActive: true,
          createdAt: now,
          updatedAt: now,
          lastSignedIn: now,
        }
      : null,
    req: { protocol: "https", headers: {} } as TrpcContext["req"],
    res: { clearCookie: () => undefined } as TrpcContext["res"],
  };
}

describe("student records access rules", () => {
  it("returns an explicit unauthenticated status instead of an empty response", async () => {
    const caller = appRouter.createCaller(contextFor(null));

    await expect(caller.auth.status()).resolves.toEqual({ user: null });
  });

  it("requires a signed-in user before a seat-number search", async () => {
    const caller = appRouter.createCaller(contextFor(null));

    await expect(caller.students.searchBySeatNumber({ seatNumber: "seat-123" })).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });

  it("prevents an unauthenticated request from listing protected student records", async () => {
    const caller = appRouter.createCaller(contextFor(null));

    await expect(caller.students.list({ page: 1, pageSize: 25 })).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });

  it("prevents an unauthenticated request from requesting report rows", async () => {
    const caller = appRouter.createCaller(contextFor(null));

    await expect(caller.students.report()).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });

  it("prevents unauthenticated requests from opening the import preview", async () => {
    const caller = appRouter.createCaller(contextFor(null));

    await expect(caller.students.previewImport({ rows: [{ seatNumber: "2", bankFormNumber: "3" }] })).rejects.toMatchObject({
      code: "UNAUTHORIZED",
    });
  });
});

describe("student-record import validation", () => {
  const validRow = { seatNumber: "2001", bankFormNumber: "3001" };

  it("accepts a valid import preview when no existing record has a matching official number", async () => {
    const result = await inspectImportRows([validRow], async () => []);

    expect(result.validRecords).toEqual([validRow]);
    expect(result.errors).toEqual([]);
  });

  it("blocks duplicate seat numbers that appear twice in the uploaded file", async () => {
    const result = await inspectImportRows([validRow, { ...validRow, bankFormNumber: "3002" }], async () => []);

    expect(result.validRecords).toHaveLength(0);
    expect(result.errors).toHaveLength(2);
    expect(result.errors[0]?.messages.join(" ")).toContain("رقم الجلوس مكرر داخل الملف");
  });

  it("blocks a row when a seat number already exists in the database lookup", async () => {
    const result = await inspectImportRows([validRow], async () => [
      { seatNumber: "2001", bankFormNumber: "9001" },
    ]);

    expect(result.validRecords).toHaveLength(0);
    expect(result.errors[0]?.messages).toContain("رقم الجلوس موجود بالفعل في قاعدة البيانات.");
  });
});

describe("local session cookie options", () => {
  it("uses an HTTP-compatible cookie policy for a local server", () => {
    const options = getSessionCookieOptions({ protocol: "http", headers: {} } as unknown as Request);

    expect(options).toMatchObject({ httpOnly: true, path: "/", sameSite: "lax", secure: false });
  });
});
