import {
  pgTable,
  uuid,
  varchar,
  text,
  jsonb,
  timestamp,
  boolean,
  integer,
  date,
  pgEnum,
} from 'drizzle-orm/pg-core'

export const billingModeEnum = pgEnum('billing_mode', ['consolidated', 'split'])
export const taxExemptStatusEnum = pgEnum('tax_exempt_status', ['none', 'pending', 'approved'])

export const accounts = pgTable('account', {
  id: uuid('id').primaryKey().defaultRandom(),
  accountNumber: varchar('account_number', { length: 50 }),
  name: varchar('name', { length: 255 }).notNull(),
  email: varchar('email', { length: 255 }),
  phone: varchar('phone', { length: 50 }),
  address: jsonb('address').$type<{
    street?: string
    city?: string
    state?: string
    zip?: string
  }>(),
  billingMode: billingModeEnum('billing_mode').notNull().default('consolidated'),
  primaryMemberId: uuid('primary_member_id'),
  notes: text('notes'),
  isActive: boolean('is_active').notNull().default(true),
  legacyId: varchar('legacy_id', { length: 255 }),
  legacySource: varchar('legacy_source', { length: 50 }),
  migratedAt: timestamp('migrated_at', { withTimezone: true }),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})

export const members = pgTable('member', {
  id: uuid('id').primaryKey().defaultRandom(),
  accountId: uuid('account_id')
    .notNull()
    .references(() => accounts.id),
  memberNumber: varchar('member_number', { length: 50 }),
  firstName: varchar('first_name', { length: 100 }).notNull(),
  lastName: varchar('last_name', { length: 100 }).notNull(),
  dateOfBirth: date('date_of_birth'),
  isMinor: boolean('is_minor').notNull().default(false),
  email: varchar('email', { length: 255 }),
  phone: varchar('phone', { length: 50 }),
  address: jsonb('address').$type<{
    street?: string
    city?: string
    state?: string
    zip?: string
  }>(),
  notes: text('notes'),
  legacyId: varchar('legacy_id', { length: 255 }),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})

export const memberIdentifiers = pgTable('member_identifier', {
  id: uuid('id').primaryKey().defaultRandom(),
  memberId: uuid('member_id')
    .notNull()
    .references(() => members.id),
  type: varchar('type', { length: 50 }).notNull(),
  label: varchar('label', { length: 100 }),
  value: varchar('value', { length: 255 }).notNull(),
  issuingAuthority: varchar('issuing_authority', { length: 255 }),
  issuedDate: date('issued_date'),
  expiresAt: date('expires_at'),
  imageFrontFileId: uuid('image_front_file_id'),
  imageBackFileId: uuid('image_back_file_id'),
  notes: text('notes'),
  isPrimary: boolean('is_primary').notNull().default(false),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})

export type MemberIdentifier = typeof memberIdentifiers.$inferSelect
export type MemberIdentifierInsert = typeof memberIdentifiers.$inferInsert

export const processorEnum = pgEnum('payment_processor', ['stripe', 'global_payments'])

export const accountProcessorLinks = pgTable('account_processor_link', {
  id: uuid('id').primaryKey().defaultRandom(),
  accountId: uuid('account_id')
    .notNull()
    .references(() => accounts.id),
  processor: processorEnum('processor').notNull(),
  processorCustomerId: varchar('processor_customer_id', { length: 255 }).notNull(),
  isActive: boolean('is_active').notNull().default(true),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
})

export type AccountProcessorLink = typeof accountProcessorLinks.$inferSelect
export type AccountProcessorLinkInsert = typeof accountProcessorLinks.$inferInsert

export const accountPaymentMethods = pgTable('account_payment_method', {
  id: uuid('id').primaryKey().defaultRandom(),
  accountId: uuid('account_id')
    .notNull()
    .references(() => accounts.id),
  processor: processorEnum('processor').notNull(),
  processorPaymentMethodId: varchar('processor_payment_method_id', { length: 255 }).notNull(),
  cardBrand: varchar('card_brand', { length: 50 }),
  lastFour: varchar('last_four', { length: 4 }),
  expMonth: integer('exp_month'),
  expYear: integer('exp_year'),
  isDefault: boolean('is_default').notNull().default(false),
  requiresUpdate: boolean('requires_update').notNull().default(false),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
})

export type AccountPaymentMethod = typeof accountPaymentMethods.$inferSelect
export type AccountPaymentMethodInsert = typeof accountPaymentMethods.$inferInsert

export const taxExemptions = pgTable('tax_exemption', {
  id: uuid('id').primaryKey().defaultRandom(),
  accountId: uuid('account_id')
    .notNull()
    .references(() => accounts.id),
  status: taxExemptStatusEnum('status').notNull().default('pending'),
  certificateNumber: varchar('certificate_number', { length: 255 }).notNull(),
  certificateType: varchar('certificate_type', { length: 100 }),
  issuingState: varchar('issuing_state', { length: 2 }),
  expiresAt: date('expires_at'),
  approvedBy: uuid('approved_by'),
  approvedAt: timestamp('approved_at', { withTimezone: true }),
  revokedBy: uuid('revoked_by'),
  revokedAt: timestamp('revoked_at', { withTimezone: true }),
  revokedReason: text('revoked_reason'),
  notes: text('notes'),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})

export type TaxExemption = typeof taxExemptions.$inferSelect
export type TaxExemptionInsert = typeof taxExemptions.$inferInsert

export type Account = typeof accounts.$inferSelect
export type AccountInsert = typeof accounts.$inferInsert
export type Member = typeof members.$inferSelect
export type MemberInsert = typeof members.$inferInsert
