import { PostgresDialect, CamelCasePlugin } from "kysely";
import type {
  GeneratedAlways,
  Generated,
  ColumnType,
  Selectable,
} from "kysely";
import pg from "pg";
import { KyselyAuth } from "@auth/kysely-adapter";
const { Pool, types } = pg;

type Timestamp = ColumnType<Date, Date | string>;

types.setTypeParser(types.builtins.TIMESTAMPTZ, (val) =>
  new Date(val).toISOString(),
);

type GraphileJob = {
  taskIdentifier: string;
  payload: Record<string, any>;
  priority: number;
  maxAttempts: number;
  key: string;
  queueName: string;
};

export const addGraphileJob = async (jobInfo: GraphileJob) => {
  // await db.insertInto("graphile_worker.jobs").values(jobInfo).execute();
};

export interface Database {
  User: {
    id: string;
    name: string | null;
    email: string;
    emailVerified: Date | null;
    image: string | null;
  };

  Account: {
    id: GeneratedAlways<string>;
    userId: string;
    type: "oidc" | "oauth" | "email" | "webauthn";
    provider: string;
    providerAccountId: string;
    refresh_token: string | undefined;
    access_token: string | undefined;
    expires_at: number | undefined;
    token_type: Lowercase<string> | undefined;
    scope: string | undefined;
    id_token: string | undefined;
    session_state: string | undefined;
  };

  Session: {
    id: GeneratedAlways<string>;
    userId: string;
    sessionToken: string;
    expires: Date;
  };

  VerificationToken: {
    identifier: string;
    token: string;
    expires: Date;
  };

  WhatsappBot: {
    id: GeneratedAlways<string>;
    name: string;
    description: string;
    phoneNumber: string;
    token: string;
    qrCode: string;
    verified: boolean;
    userId: string;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };

  FacebookBot: {
    id: GeneratedAlways<string>;
    name: string | null;
    description: string | null;
    token: string | null;
    pageAccessToken: string | null;
    appSecret: string | null;
    verifyToken: string | null;
    pageId: string | null;
    appId: string | null;
    userId: string | null;
    verified: Generated<boolean>;
    createdAt: GeneratedAlways<Timestamp>;
    updatedAt: GeneratedAlways<Timestamp>;
  };

  VoiceLine: {
    id: GeneratedAlways<string>;
    name: string;
    description: string;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };

  SignalBot: {
    id: GeneratedAlways<string>;
    name: string;
    description: string;
    phoneNumber: string;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };

  Webhook: {
    id: GeneratedAlways<string>;
    name: string;
    description: string;
    backendType: string;
    backendId: string;
    endpointUrl: string;
    httpMethod: "post" | "put";
    headers: Record<string, any>;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;
  };
}

export type FacebookBot = Selectable<Database["FacebookBot"]>;
export type SignalBot = Selectable<Database["SignalBot"]>;
export type WhatsappBot = Selectable<Database["WhatsappBot"]>;
export type VoiceLine = Selectable<Database["VoiceLine"]>;
export type Webhook = Selectable<Database["Webhook"]>;
export type User = Selectable<Database["User"]>;

export const db = new KyselyAuth<Database>({
  dialect: new PostgresDialect({
    pool: new Pool({
      host: process.env.DATABASE_HOST,
      database: process.env.DATABASE_NAME,
      port: parseInt(process.env.DATABASE_PORT!),
      user: process.env.DATABASE_USER,
      password: process.env.DATABASE_PASSWORD,
    }),
  }),
  plugins: [new CamelCasePlugin()],
});
