import { relations } from 'drizzle-orm'
import {
  boolean, pgEnum, pgTable, primaryKey, text, timestamp, uuid, unique,
} from 'drizzle-orm/pg-core'

/**
 * Tenancy and identity. Fixed by #11.
 *
 * Two entity types, deliberately: a roster entry is retailer-scoped and has
 * no account; a vendor org is global and exists only once a vendor has a
 * reason to care. Claiming links them — see #24.
 */

/**
 * Permissions never resolve against an org alone, always against
 * (org, capability, resource). An org may hold both.
 */
export const capability = pgEnum('capability', ['issuer', 'vendor'])

export const organization = pgTable('organization', {
  id: uuid('id').primaryKey().defaultRandom(),
  legalName: text('legal_name').notNull(),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
})

/** An org holds each capability explicitly. Holding both is the dual-role case. */
export const orgCapability = pgTable('org_capability', {
  orgId: uuid('org_id').notNull().references(() => organization.id),
  capability: capability('capability').notNull(),
  grantedAt: timestamp('granted_at', { withTimezone: true }).notNull().defaultNow(),
}, (t) => [primaryKey({ columns: [t.orgId, t.capability] })])

export const actor = pgTable('actor', {
  id: uuid('id').primaryKey().defaultRandom(),
  email: text('email').notNull().unique(),
  displayName: text('display_name').notNull(),
})

export const membership = pgTable('membership', {
  actorId: uuid('actor_id').notNull().references(() => actor.id),
  orgId: uuid('org_id').notNull().references(() => organization.id),
}, (t) => [primaryKey({ columns: [t.actorId, t.orgId] })])

/**
 * A retailer's import creates roster entries. They are owned by the retailer,
 * carry no account, and most are never claimed. #11 decision 1.
 */
export const rosterEntry = pgTable('roster_entry', {
  id: uuid('id').primaryKey().defaultRandom(),
  retailerOrgId: uuid('retailer_org_id').notNull().references(() => organization.id),
  name: text('name').notNull(),
  contactEmail: text('contact_email'),
  duns: text('duns'),
  /** Null until claimed. Claiming is #24. */
  claimedVendorOrgId: uuid('claimed_vendor_org_id').references(() => organization.id),
  claimedAt: timestamp('claimed_at', { withTimezone: true }),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
}, (t) => [unique().on(t.retailerOrgId, t.name)])

export const organizationRelations = relations(organization, ({ many }) => ({
  capabilities: many(orgCapability),
  members: many(membership),
}))
