import { describe, expect, it } from "vitest"
import type { SupabaseClient } from "@supabase/supabase-js"

import { requestDeletion } from "../deletion"

/**
 * Tests for the GDPR deletion-request helper (KAR-529).
 *
 * The helper marks the profile and returns. Hard-delete is out of scope —
 * a separate operator-supervised scrub job does the actual data removal.
 */

interface RecordedUpdate {
  table: string
  values: Record<string, unknown>
  predicateColumn?: string
  predicateValue?: unknown
}

function makeMockClient(opts: {
  updated?: { auth_user_id: string } | null
  updateError?: { message: string }
}): { client: SupabaseClient; recorded: RecordedUpdate[] } {
  const recorded: RecordedUpdate[] = []

  const builder = (table: string): unknown => {
    const recording: RecordedUpdate = { table, values: {} }
    const chain = {
      update(values: Record<string, unknown>) {
        recording.values = values
        return chain
      },
      eq(column: string, value: unknown) {
        recording.predicateColumn = column
        recording.predicateValue = value
        return chain
      },
      select() {
        return chain
      },
      maybeSingle() {
        recorded.push(recording)
        if (opts.updateError) {
          return Promise.resolve({ data: null, error: opts.updateError })
        }
        return Promise.resolve({
          data: opts.updated ?? null,
          error: null,
        })
      },
    }
    return chain
  }

  return { client: { from: builder } as unknown as SupabaseClient, recorded }
}

describe("requestDeletion (KAR-529)", () => {
  it("marks the profile with account_status = deletion_requested", async () => {
    const { client, recorded } = makeMockClient({ updated: { auth_user_id: "u1" } })
    const result = await requestDeletion(client, "u1", () => "2026-05-23T00:00:00.000Z")

    expect(result.ok).toBe(true)
    expect(recorded).toHaveLength(1)
    expect(recorded[0].table).toBe("user_profiles")
    expect(recorded[0].values).toMatchObject({
      account_status: "deletion_requested",
      deletion_requested_at: "2026-05-23T00:00:00.000Z",
    })
    expect(recorded[0].predicateColumn).toBe("auth_user_id")
    expect(recorded[0].predicateValue).toBe("u1")
  })

  it("returns the deletion-request timestamp on success", async () => {
    const { client } = makeMockClient({ updated: { auth_user_id: "u1" } })
    const result = await requestDeletion(client, "u1", () => "2026-01-02T03:04:05.000Z")
    expect(result).toEqual({ ok: true, deletion_requested_at: "2026-01-02T03:04:05.000Z" })
  })

  it("returns profile_not_found when the UPDATE matched no rows", async () => {
    const { client } = makeMockClient({ updated: null })
    const result = await requestDeletion(client, "ghost")
    expect(result).toEqual({ ok: false, error: "profile_not_found" })
  })

  it("returns the underlying error message when Supabase rejects the update", async () => {
    const { client } = makeMockClient({ updateError: { message: "permission denied" } })
    const result = await requestDeletion(client, "u1")
    expect(result).toEqual({ ok: false, error: "permission denied" })
  })
})
