import { drizzle } from 'drizzle-orm/libsql';
import { sqliteTable, text, integer, customType } from 'drizzle-orm/sqlite-core';
import { relations, sql } from 'drizzle-orm';
import crypto from 'crypto';
import 'dotenv/config.js';
import { type } from 'arktype';

let urlAlphabet =
  'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';

const POOL_SIZE_MULTIPLIER = 128;
let pool, poolOffset;
let fillPool = bytes => {
  if (!pool || pool.length < bytes) {
    pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
    crypto.randomFillSync(pool);
    poolOffset = 0;
  } else if (poolOffset + bytes > pool.length) {
    crypto.randomFillSync(pool);
    poolOffset = 0;
  }
  poolOffset += bytes;
};
let nanoid = (size = 21) => {
  fillPool((size |= 0));
  let id = '';
  for (let i = poolOffset - size; i < poolOffset; i++) {
    id += urlAlphabet[pool[i] & 63];
  }
  return id
};

const NODE_ENV = process.env.NODE_ENV;
const APP_NAME = "Perx";
const ORIGIN = type("string > 0").describe("provided: process.env.ORIGIN").assert(process.env.ORIGIN);
const DATABASE_URL = type("string > 0").describe("provided: process.env.DATABASE_URL").assert(process.env.DATABASE_URL);
const DATABASE_AUTH_TOKEN = type("string").describe("provided: process.env.DATABASE_AUTH_TOKEN").assert(process.env.DATABASE_AUTH_TOKEN);
const PW_MIN_LENGTH = 8;
const BETTER_AUTH_SESSION_COOKIE = "better-auth.session_token";
const SMTP_URL = type("string > 0").describe("provided: process.env.SMTP_URL").assert(process.env.SMTP_URL);
const SMTP_USER = type("string > 0").describe("provided: process.env.SMTP_USER").assert(process.env.SMTP_USER);
const SMTP_PASS = type("string > 0").describe("provided: process.env.SMTP_PASS").assert(process.env.SMTP_PASS);
const SMTP_PORT = type("string > 0").describe("provided: process.env.SMTP_PORT").assert(process.env.SMTP_PORT);
const EMAIL_DEFAULT_FROM = type("string > 0").describe("provided: process.env.EMAIL_DEFAULT_FROM").assert(process.env.EMAIL_DEFAULT_FROM);
const BONUS_TYPES = (
  /** @type {const} */
  ["MILES", "POINTS", "CASH"]
);
const PLAID_CLIENT_ID = type("string > 0").describe("provided: process.env.PLAID_CLIENT_ID").assert(process.env.PLAID_CLIENT_ID);
const PLAID_SECRET = type("string > 0").describe("provided: process.env.PLAID_SECRET").assert(process.env.PLAID_SECRET);
const REGISTRATION_ALLOW_LIST = JSON.parse(
  type("string > 0").describe("provided: process.env.REGISTRATION_ALLOW_LIST").assert(process.env.REGISTRATION_ALLOW_LIST)
);
const sharedFields = {
  id: text().primaryKey().notNull().$defaultFn(() => nanoid()),
  createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull().default(sql`(current_timestamp)`),
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull().$onUpdateFn(() => /* @__PURE__ */ new Date())
};
const user = sqliteTable("user", {
  ...sharedFields,
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  emailVerified: integer("email_verified", { mode: "boolean" }).notNull().default(false),
  image: text("image")
  // /** @type {"guest"|"user"|"admin"} */
  // role: t.text().$type().default("guest"),
});
const session = sqliteTable("session", {
  ...sharedFields,
  expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
  token: text("token").notNull().unique(),
  ipAddress: text("ip_address"),
  userAgent: text("user_agent"),
  userId: text("user_id").notNull().references(() => user.id, { onUpdate: "cascade", onDelete: "cascade" })
});
const account = sqliteTable("account", {
  ...sharedFields,
  accountId: text("account_id").notNull(),
  providerId: text("provider_id").notNull(),
  userId: text("user_id").notNull().references(() => user.id, { onUpdate: "cascade", onDelete: "cascade" }),
  accessToken: text("access_token"),
  refreshToken: text("refresh_token"),
  idToken: text("id_token"),
  accessTokenExpiresAt: integer("access_token_expires_at", {
    mode: "timestamp_ms"
  }),
  refreshTokenExpiresAt: integer("refresh_token_expires_at", {
    mode: "timestamp_ms"
  }),
  scope: text("scope"),
  password: text("password"),
  createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
});
const verification = sqliteTable("verification", {
  ...sharedFields,
  identifier: text("identifier").notNull(),
  value: text("value").notNull(),
  expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull()
});
const bonusTypeEnum = customType(
  /** @type {import("drizzle-orm/sqlite-core").CustomTypeParams<{data: BONUS_TYPES[number]}>} */
  {
    dataType() {
      return "text";
    },
    toDriver(value) {
      if (!BONUS_TYPES.includes(value)) {
        throw new Error("bonus type not allowed");
      }
      return value;
    }
  }
);
const userCard = sqliteTable("user_card", {
  ...sharedFields,
  nickname: text().notNull(),
  openedAt: integer("opened_on", { mode: "timestamp_ms" }).notNull(),
  closedAt: integer("closed_on", { mode: "timestamp_ms" }),
  bonusType: bonusTypeEnum("bonus_type"),
  bonusAmount: integer("bonus_amount"),
  bonusSpend: integer("bonus_spend"),
  // bonusPeriod: bonusPeriodEnum("bonus_period"),
  bonusDeadline: integer("bonus_deadline", { mode: "timestamp_ms" }),
  annualFee: integer("annual_fee").default(0),
  plaidName: text("plaid_name"),
  plaidItemId: text("plaid_item_id"),
  plaidAccessToken: text("plaid_access_token"),
  plaidMask: text("plaid_mask"),
  plaidBank: text(),
  plaidInstitutionId: text("plaid_institution_id"),
  plaidTxCursor: text("plaid_transaction_cursor"),
  syncedAt: integer("synced_at", { mode: "timestamp_ms" }),
  userId: text("user_id").notNull().references(() => user.id, {
    onUpdate: "cascade",
    onDelete: "cascade"
  }),
  paymentId: text("payment_id").references(() => payment.id, {
    // TODO:
    // onUpdate: "cascade",
    // onDelete: "cascade",
  })
});
const userCardRelations = relations(userCard, ({ many }) => {
  return {
    plaidTransaction: many(plaidTransaction)
  };
});
const plaidTransaction = sqliteTable("plaid_transaction", {
  ...sharedFields,
  transaction_id: text().notNull(),
  //.unique(), // Plaid transaction ID
  amount: integer().notNull(),
  date: integer("date", { mode: "timestamp_ms" }).notNull(),
  // Plaid date formatted as 'YYYY-MM-DD'
  pending: integer("pending", { mode: "boolean" }),
  meta: text({ mode: "json" }).notNull(),
  cardId: text("card_id").notNull().references(() => userCard.id, {
    onUpdate: "cascade",
    onDelete: "cascade"
  })
  // Plaid Example Data:
  //
  // account_id: 'XPnVorV7RQf7GoxVZRV5fGR9KrPy8XsdZ8pLn',
  // account_owner: null,
  // amount: 500,
  // authorized_date: null,
  // authorized_datetime: null,
  // category: null,
  // category_id: null,
  // check_number: null,
  // counterparties: [],
  // date: '2025-10-25',
  // datetime: null,
  // iso_currency_code: 'USD',
  // location: {
  //   address: null,
  //   city: null,
  //   country: null,
  //   lat: null,
  //   lon: null,
  //   postal_code: null,
  //   region: null,
  //   store_number: null
  // },
  // logo_url: null,
  // merchant_entity_id: null,
  // merchant_name: null,
  // name: 'Madison Bicycle Shop',
  // payment_channel: 'in store',
  // payment_meta: {
  //   by_order_of: null,
  //   payee: null,
  //   payer: null,
  //   payment_method: null,
  //   payment_processor: null,
  //   ppd_id: null,
  //   reason: null,
  //   reference_number: null
  // },
  // pending: false,
  // pending_transaction_id: null,
  // personal_finance_category: {
  //   confidence_level: 'LOW',
  //   detailed: 'GENERAL_MERCHANDISE_SPORTING_GOODS',
  //   primary: 'GENERAL_MERCHANDISE',
  //   version: 'v1'
  // },
  // personal_finance_category_icon_url: 'https://plaid-category-icons.plaid.com/PFC_GENERAL_MERCHANDISE.png',
  // transaction_code: null,
  // transaction_id: 'QBoGzZGxA7txXV8gvZgzuRqQMpmnQAIpXRrDk',
  // transaction_type: 'place',
  // unofficial_currency_code: null,
  // website: null
});
const plaidTransactionRelations = relations(plaidTransaction, ({ one }) => {
  return {
    userCard: one(userCard, {
      fields: [plaidTransaction.cardId],
      references: [userCard.id]
    })
  };
});
const payment = sqliteTable("payment", {
  ...sharedFields,
  stripeCheckoutId: text("stripe_checkout_id").unique().notNull(),
  amount: integer().notNull(),
  // url
  // meta
  userId: text("user_id").notNull().references(() => user.id, {
    // TODO:
    // onUpdate: "cascade",
    // onDelete: "cascade",
  })
});
function withPagination(q, { page = 1, perPage = 10 } = {}) {
  return q.offset((page - 1) * perPage).limit(perPage);
}
const db = drizzle(
  {
    connection: {
      url: DATABASE_URL,
      authToken: DATABASE_AUTH_TOKEN
    }
  },
  {
    schema: {
      user,
      session,
      account,
      verification,
      userCard,
      userCardRelations,
      plaidTransaction,
      plaidTransactionRelations,
      payment
    }
  }
);

export { APP_NAME as A, BETTER_AUTH_SESSION_COOKIE as B, EMAIL_DEFAULT_FROM as E, NODE_ENV as N, ORIGIN as O, PLAID_SECRET as P, REGISTRATION_ALLOW_LIST as R, SMTP_PASS as S, user as a, PLAID_CLIENT_ID as b, BONUS_TYPES as c, db as d, PW_MIN_LENGTH as e, payment as f, account as g, SMTP_USER as h, SMTP_URL as i, SMTP_PORT as j, plaidTransaction as p, session as s, userCard as u, verification as v, withPagination as w };
//# sourceMappingURL=index3-Cipag7JS.js.map
