import { test } from "bun:test"
import assert from "assert"
import { buildWhere } from "../src/where-builder"

test("buildWhere with number ID", () => {
  assert.throws(() => buildWhere(502), /Invalid query/)
})

test("buildWhere with string ID", () => {
  assert.equal(buildWhere("name = 'bob'"), "WHERE name = 'bob'")
})

test("buildWhere with simple object", () => {
  assert.equal(buildWhere({ name: "bob" }), "WHERE name = $name")
  assert.equal(buildWhere({ id: 502 }), "WHERE id = $id")
})

test("buildWhere with multiple conditions", () => {
  assert.equal(buildWhere({ name: "bob", age: 20 }), "WHERE name = $name AND age = $age")
})

test("buildWhere with special parameters", () => {
  // Test limit
  assert.equal(buildWhere({ name: "bob", limit: 10 }), "WHERE name = $name LIMIT 10")

  // Test offset
  assert.equal(buildWhere({ name: "bob", offset: 5 }), "WHERE name = $name OFFSET 5")

  // Test order
  assert.equal(buildWhere({ name: "bob", order: "age DESC" }), "WHERE name = $name ORDER BY age DESC")
})

test("buildWhere with combined special parameters", () => {
  assert.equal(
    buildWhere({
      name: "bob",
      age: 20,
      limit: 10,
      offset: 5,
      order: "name ASC",
    }),
    "WHERE name = $name AND age = $age LIMIT 10 OFFSET 5 ORDER BY name ASC",
  )
})

test("buildWhere with empty or invalid input", () => {
  assert.throws(() => buildWhere(null as any), /Invalid query/)
  assert.throws(() => buildWhere(undefined as any), /Invalid query/)
  assert.throws(() => buildWhere(true as any), /Invalid query/)
  assert.throws(() => buildWhere([] as any), /Invalid query/)
})

test("buildWhere with only special parameters", () => {
  assert.equal(buildWhere({ limit: 10 }), "LIMIT 10")
  assert.equal(buildWhere({ offset: 5 }), "OFFSET 5")
  assert.equal(buildWhere({ order: "id DESC" }), "ORDER BY id DESC")
  assert.equal(buildWhere({ limit: 10, offset: 5 }), "LIMIT 10 OFFSET 5")
})

// test("buildWhere with array", () => {
//   assert.throws(() => buildWhere([53, { name: "bob" }]), /Invalid query/)
//   assert.throws(() => buildWhere([55]), /Invalid query/)
//   assert.throws(() => buildWhere(["id = 100", { limit: 50 }]), /Invalid query/)
//   assert.throws(() => buildWhere([53, { name: "bob" }, { age: 20 }, { offset: 20 }]), /Invalid query/)
// })

test("buildWhere with sql string and args", () => {
  assert.equal(buildWhere("id = $id", { id: 502 }), "WHERE id = $id")
  assert.equal(buildWhere("502"), "WHERE 502")
  assert.equal(buildWhere("id = 502"), "WHERE id = 502")
  assert.equal(buildWhere({ id: 502 }), "WHERE id = $id")
  assert.equal(buildWhere({ name: "bob" }), "WHERE name = $name")
  assert.equal(buildWhere({ name: "bob", limit: 10 }), "WHERE name = $name LIMIT 10")
  assert.equal(buildWhere({ name: "bob", age: 20 }), "WHERE name = $name AND age = $age")
  assert.equal(buildWhere({ name: "bob", age: 20, limit: 10 }), "WHERE name = $name AND age = $age LIMIT 10")
  assert.equal(buildWhere({ name: "bob", age: 20, limit: 10, offset: 5 }), "WHERE name = $name AND age = $age LIMIT 10 OFFSET 5")
  assert.equal(buildWhere("id = $id", { id: 502, limit: 10, offset: 5 }), "WHERE id = $id LIMIT 10 OFFSET 5")
  assert.equal(buildWhere("id = $id", { id: 502, name: "bob", limit: 10, offset: 5 }), "WHERE id = $id AND name = $name LIMIT 10 OFFSET 5")
})
