/** Ma vérification de la diffusion. Une tâche, prise puis remise à l'identique. */
import { eq, sql } from "drizzle-orm"

import { db } from "@/lib/db/client"
import { domainEvents, notifications, people, recurringTemplates, taskInstances } from "@/lib/db/schema"
import { finish, approve } from "@/lib/services/task-commands"
import type { SignedIn } from "@/lib/services/session"

const [row] = await db
  .select({
    id: taskInstances.id,
    assignee: taskInstances.assigneePersonId,
    checker: recurringTemplates.checkerPersonId,
    status: taskInstances.status,
    startedAt: taskInstances.startedAt,
    finishedAt: taskInstances.finishedAt,
    checkedAt: taskInstances.checkedAt,
  })
  .from(taskInstances)
  .innerJoin(recurringTemplates, eq(recurringTemplates.id, taskInstances.recurringTemplateId))
  .where(sql`${taskInstances.status} in ('todo','started') and ${taskInstances.assigneePersonId} is not null
             and ${recurringTemplates.checkerPersonId} is not null
             and ${recurringTemplates.checkerPersonId} <> ${taskInstances.assigneePersonId}`)
  .limit(1)
if (!row) throw new Error("aucune tâche utilisable")
const snapshot = { ...row }
console.log("cobaye :", row.id, "exécutant ≠ contrôleur")

const nameOf = async (id: string) => {
  const [p] = await db.select({ n: people.firstName }).from(people).where(eq(people.id, id))
  return p?.n
}
const asUser = (id: string): SignedIn => ({
  personId: id, employeeCode: "", name: "", positionTitle: null,
  department: null, level: null, tier: "staff", language: "en",
})

const who = async () => {
  const rows = await db
    .select({ person: notifications.personId, key: notifications.messageKey })
    .from(notifications)
  return Promise.all(rows.map(async (r) => ({ qui: await nameOf(r.person), quoi: r.key })))
}

await db.update(taskInstances).set({ status: "started", startedAt: new Date() }).where(eq(taskInstances.id, row.id))
console.log("finish par l'exécutant :", await finish(asUser(row.assignee!), row.id, "fait"))
console.log("  notifications :", await who())

console.log("approve par le contrôleur :", await approve(asUser(row.checker!), row.id, ""))
console.log("  notifications :", await who())

// Remise en état.
await db.delete(notifications)
await db.delete(domainEvents)
await db
  .update(taskInstances)
  .set({
    status: snapshot.status,
    startedAt: snapshot.startedAt,
    finishedAt: snapshot.finishedAt,
    checkedAt: snapshot.checkedAt,
  })
  .where(eq(taskInstances.id, row.id))

const [back] = await db
  .select({ s: taskInstances.status, st: taskInstances.startedAt, f: taskInstances.finishedAt, c: taskInstances.checkedAt })
  .from(taskInstances)
  .where(eq(taskInstances.id, row.id))
console.log("remis :", back, "identique :", JSON.stringify(back) === JSON.stringify({
  s: snapshot.status, st: snapshot.startedAt, f: snapshot.finishedAt, c: snapshot.checkedAt,
}))

const [e] = await db.select({ n: sql<number>`count(*)::int` }).from(domainEvents)
const [n] = await db.select({ n: sql<number>`count(*)::int` }).from(notifications)
console.log("restant :", { evenements: e?.n, notifications: n?.n })

process.exit(0)
