import type {
  Generated,
  ColumnType,
  Selectable,
  Insertable,
  Updateable,
} from "kysely";

export interface Database {
  users: UserTable;
  chats: ChatTable;
  replies: ReplyTable;
  tokens: TokenTable;
}

export interface UserTable {
  // Columns that are generated by the database should be marked
  // using the `Generated` type. This way they are automatically
  // made optional in inserts and updates.
  id: Generated<number>;

  username: string | null;
  first_name: string | null;
  last_name: string | null;
  email: string;
  phone: string;
  address: string | null;
  password: string;
  is_admin: boolean | null;
  position: string | null;
  updated_at: ColumnType<Date, string | undefined, string | undefined>;

  // If the column is nullable in the database, make its type nullable.
  // Don't use optional properties. Optionality is always determined
  // automatically by Kysely.

  // You can specify a different type for each operation (select, insert and
  // update) using the `ColumnType<SelectType, InsertType, UpdateType>`
  // wrapper. Here we define a column `created_at` that is selected as
  // a `Date`, can optionally be provided as a `string` in inserts and
  // can never be updated:
  created_at: ColumnType<Date, string | undefined, never>;

  // You can specify JSON columns using the `JSONColumnType` wrapper.
  // It is a shorthand for `ColumnType<T, string, string>`, where T
  // is the type of the JSON object/array retrieved from the database,
  // and the insert and update types are always `string` since you're
  // always stringifying insert/update values.
  //   metadata: JSONColumnType<{
  //     login_at: string;
  //     ip: string | null;
  //     agent: string | null;
  //     plan: "free" | "premium";
  //   }>;
}

// You should not use the table schema interfaces directly. Instead, you should
// use the `Selectable`, `Insertable` and `Updateable` wrappers. These wrappers
// make sure that the correct types are used in each operation.
export type User = Selectable<UserTable>;
export type NewUser = Insertable<UserTable>;
export type UserUpdate = Updateable<UserTable>;

export interface ChatTable {
  id: Generated<number>;
  name: string;
  email: string;
  subject: string;
  message: string;
  is_read: boolean;
  is_replied: boolean;
  time: ColumnType<Date, string | undefined, never>;
}

export type Chat = Selectable<ChatTable>;
export type NewChat = Insertable<ChatTable>;
export type ChatUpdate = Updateable<ChatTable>;

export interface ReplyTable {
  id: Generated<number>;
  chat_id: number | null;
  reply: string;
  replied_by: number | null;
  time: ColumnType<Date, string | undefined, never>;
}

export type Reply = Selectable<ReplyTable>;
export type NewReply = Insertable<ReplyTable>;
export type ReplyUpdate = Updateable<ReplyTable>;

export interface TokenTable {
  token_id: Generated<number>;
  token: string;
  email: string;
  generated_at: ColumnType<Date, string | undefined, never>;
  expired_at: ColumnType<Date, string | undefined, never>;
}

export type Token = Selectable<TokenTable>;
export type NewToken = Insertable<TokenTable>;
export type TokenUpdate = Updateable<TokenTable>;
