import { createApp } from "../src/app.js";
import { DryRunMailer, type Mailer } from "../src/mailer.js";
import { DryRunSmsSender, type SmsSender } from "../src/sms.js";
import { InMemoryStore } from "../src/store.js";
import type { RuntimeConfig } from "../src/types.js";

export const T0 = 1_700_000_000_000; // 固定起点

export function makeClock(start = T0) {
  let t = start;
  return {
    now: () => t,
    advanceMinutes: (m: number) => {
      t += m * 60_000;
    },
    set: (v: number) => {
      t = v;
    },
  };
}

export function makeConfig(over: Partial<RuntimeConfig> = {}): RuntimeConfig {
  return {
    dryRun: true,
    mailFrom: "noreply@test.example",
    senderInfo: "テスト送信者 / 住所",
    maxSendsPerTick: 100,
    maxSendsPerDay: 2000,
    appBaseUrl: "https://app.test",
    smsDryRun: true,
    maxSmsPerTick: 20,
    maxSmsPerDay: 100,
    smsCostPerSegment: 10,
    smsSenderInfo: "",
    smsBaseUrl: "",
    ...over,
  };
}

export const ADMIN_PASSWORD = "secret-pass";
export const SESSION_SECRET = "unit-test-session-secret-please-long";

export function setup(opts: {
  cfg?: Partial<RuntimeConfig>;
  mailer?: Mailer;
  smsSender?: SmsSender;
  now?: () => number;
} = {}) {
  const clock = makeClock();
  const now = opts.now ?? clock.now;
  const store = new InMemoryStore(now);
  const mailer = opts.mailer ?? new DryRunMailer();
  const smsSender = opts.smsSender ?? new DryRunSmsSender();
  const cfg = makeConfig(opts.cfg);
  const app = createApp({
    store,
    mailer,
    smsSender,
    cfg,
    adminPassword: ADMIN_PASSWORD,
    sessionSecret: SESSION_SECRET,
    now,
  });
  return { app, store, mailer, smsSender, cfg, clock, now };
}

/** ログインして Cookie 文字列を得る */
export async function login(app: ReturnType<typeof createApp>): Promise<string> {
  const res = await app.request("/api/login", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ password: ADMIN_PASSWORD }),
  });
  const setCookie = res.headers.get("Set-Cookie") ?? "";
  return setCookie.split(";")[0]; // mds_session=...
}

export function authed(cookie: string, body?: unknown): RequestInit {
  return {
    method: "POST",
    headers: { "Content-Type": "application/json", Cookie: cookie },
    body: body === undefined ? undefined : JSON.stringify(body),
  };
}
