import { openDB, field, validate, type QueryOpts } from '../src/index'

enum UserState {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  BANNED = 'banned',
}

class User {
  @field('primary key')
  id!: number

  @field('required', 'unique', 'email')
  @form('email')
  email!: string

  @field('required', 'password')
  @form('password')
  password!: string

  @field('required')
  @form('text')
  name!: string

  @field()
  @form('checkbox')
  admin = false

  @field()
  @form('select')
  state: UserState = UserState.ACTIVE
}

class UserForm extends User {
  @form('file picker')
  profile!: string
}


const action = async (user: User) => {
  const [ok, errors] = db.users.validate(user)
  if (!ok) {
    return { errors }
  }

  return { success: true }
}

async function main() {
  // Open database with type information
  const db = (await openDB({ sqlite: "users.db" }))
    .model(User, 'users')

  // Create users table
  await db.run(`
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      email TEXT NOT NULL
    )
  `)

  const john = await db.users.create({ name: "John" })
  console.log("Created:", john.id, john.name)

  const search = (find: string, opts?: QueryOpts) =>
    db.users.all(`name LIKE $name`, { ...opts, name: `%${find}%` })

  console.log("Search:", await search("John", { limit: 2 }))

  const errors = validate(john)
  console.log("Errors:", john, errors)

  const jane = await db.users.create({ name: "Jane" })
  console.log("Created:", jane.name)

  const found = await db.users.find(john.id)
  console.log("Found:", found?.name)

  const updated = await db.users.update(john.id, { name: "John Smith" })
  console.log("Updated:", updated?.name)

  const smiths = await db.users.all("name LIKE $name", { name: "Smith%" })
  console.log("Smiths:", smiths.map(u => u.name))

  const firstJane = await db.users.one({ name: "Jane" })
  console.log("First Jane:", firstJane?.name)

  const topSmiths = await db.users.all("name LIKE $name", {
    name: "%Smith%",
    order: "id DESC",
    limit: 3,
  })
  console.log("Top Smiths:", topSmiths.map(u => u.name))

  const recent = await db.users.all({ order: "id DESC", limit: 5 })
  console.log("Recent:", recent.map(u => u.name))

  const secondJane = await db.users.one({ name: "Jane", order: "id ASC", offset: 1 })
  console.log("Second Jane:", secondJane?.name)

  const latestJ = await db.users.one("name LIKE $name ORDER BY id DESC", { name: "J%" })
  console.log("Latest J:", latestJ?.name)

  // Get all users
  const allUsers = await db.users.all()
  console.log("All users:", allUsers.map(u => u.name))

  // Delete
  await db.users.delete(john.id)
  console.log("Deleted John")

  await db.close()
}

main().catch(console.error)