import { eq, sql } from "drizzle-orm"
import { db } from "@/lib/db/client"
import { domainEvents, notifications, people, taskInstances, taskSubmissions } from "@/lib/db/schema"
import { remind } from "@/lib/services/task-commands"

const BASE = "http://127.0.0.1:4148"
const signIn = async (u: string, p: string) => {
  const r = await fetch(`${BASE}/api/auth/sign-in/username`, {
    method: "POST", headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ username: u, password: p }),
  })
  return r.headers.getSetCookie().map((c) => c.split(";")[0]).join("; ")
}
const read = async (cookie: string, lastId?: string, ms = 1200) => {
  const c = new AbortController()
  const res = await fetch(`${BASE}/api/notifications/stream`, {
    headers: { cookie, ...(lastId ? { "Last-Event-ID": lastId } : {}) }, signal: c.signal,
  })
  const reader = res.body!.getReader(); const dec = new TextDecoder(); let txt = ""
  setTimeout(() => c.abort(), ms)
  try { while (true) { const { done, value } = await reader.read(); if (done) break; txt += dec.decode(value) } } catch {}
  return txt
}
const nudge = async (n: number, note: string) => {
  const [admin] = await db.select({ id: people.id, code: people.employeeCode }).from(people).where(eq(people.username, "narin"))
  const rows = await db.select({ id: taskInstances.id }).from(taskInstances)
    .innerJoin(people, eq(people.id, taskInstances.assigneePersonId))
    .where(sql`${people.username} = 'nattikan' and ${taskInstances.status} in ('todo','started')`).limit(n)
  for (const t of rows) {
    await remind({ personId: admin!.id, employeeCode: admin!.code, name: "", positionTitle: null,
      department: null, level: "admin", tier: "admin", language: "en" }, t.id, note)
  }
}

const cookie = await signIn("nattikan", "staff1")

await nudge(1, "premiere")
const a = await read(cookie)
const ids = [...a.matchAll(/^id: (.+)$/gm)].map((m) => m[1])
console.log("connexion 1, notifications :", (a.match(/event: notification/g) ?? []).length, "| ids :", ids)
console.log("  ready :", a.match(/event: ready\ndata: (.*)/)?.[1])

await nudge(2, "pendant la coupure")
const [total] = await db.select({ n: sql<number>`count(*)::int` }).from(notifications)
console.log("total en base :", total?.n)

const b = await read(cookie, ids.at(-1))
console.log("reconnexion avec le dernier id, rejouees :", (b.match(/event: notification/g) ?? []).length)

const c2 = await read(cookie)
console.log("connexion neuve sans id, rejouees :", (c2.match(/event: notification/g) ?? []).length)

await db.delete(notifications); await db.delete(domainEvents); await db.delete(taskSubmissions)
const st = await db.select({ s: taskInstances.status, n: sql<number>`count(*)::int` }).from(taskInstances).groupBy(taskInstances.status).orderBy(taskInstances.status)
console.log("remis :", st.map((r) => `${r.s} ${r.n}`).join(", "))
process.exit(0)
