import { sql } from 'drizzle-orm'
import {
  boolean, integer, jsonb, numeric, pgEnum, pgPolicy, pgTable, text, timestamp, uuid,
} from 'drizzle-orm/pg-core'
import { organization } from './org.js'
import { evaluationScenario, priceLine, requirement, solicitation } from './solicitation.js'

/**
 * The response side. #10 established the central inversion: the artifact worth
 * standardizing is the response, not the RFP.
 *
 * Every sensitive table here carries an RLS policy keyed to a disclosure class.
 * The lifecycle lives in `release_level`, written once — see src/db/schema/release.ts
 * and migrations/custom.
 */

export const participationState = pgEnum('participation_state', [
  'invited', 'opened', 'acknowledged', 'intends_to_bid', 'submitted', 'withdrawn',
])

/** The audience, materialised as an explicit list at issue (#12 decision 3). */
export const participation = pgTable('participation', {
  id: uuid('id').primaryKey().defaultRandom(),
  solicitationId: uuid('solicitation_id').notNull().references(() => solicitation.id),
  vendorOrgId: uuid('vendor_org_id').notNull().references(() => organization.id),
  state: participationState('state').notNull().default('invited'),
  acknowledgedAt: timestamp('acknowledged_at', { withTimezone: true }),
}).enableRLS()

export const response = pgTable('response', {
  id: uuid('id').primaryKey().defaultRandom(),
  solicitationId: uuid('solicitation_id').notNull().references(() => solicitation.id),
  vendorOrgId: uuid('vendor_org_id').notNull().references(() => organization.id),
  submittedAt: timestamp('submitted_at', { withTimezone: true }),
  attestedBy: uuid('attested_by'),
  attestedAt: timestamp('attested_at', { withTimezone: true }),
}).enableRLS()

export const responseDocument = pgTable('response_document', {
  id: uuid('id').primaryKey().defaultRandom(),
  responseId: uuid('response_id').notNull().references(() => response.id),
  blobRef: text('blob_ref').notNull(),
  sha256: text('sha256').notNull(),
}).enableRLS()

/** Three-state, per #10. Absence is representable, which is the whole point. */
export const coverage = pgEnum('coverage', ['answered', 'not_answered', 'indeterminate'])

export const answer = pgTable('answer', {
  id: uuid('id').primaryKey().defaultRandom(),
  responseId: uuid('response_id').notNull().references(() => response.id),
  requirementId: uuid('requirement_id').notNull().references(() => requirement.id),
  coverage: coverage('coverage').notNull(),
  text: text('text'),
  provenanceDocumentId: uuid('provenance_document_id').references(() => responseDocument.id),
  provenancePage: integer('provenance_page'),
  provenanceSpan: jsonb('provenance_span').$type<{ start: number; end: number }>(),
  /** The vendor attests to their own indeterminates at submit (#10, #16 decision 4). */
  vendorAttested: boolean('vendor_attested').notNull().default(false),
  /** Reopened by a substantive amendment, one answer at a time (#16 decision 3). */
  reopenedByAmendmentId: uuid('reopened_by_amendment_id'),
}, () => [
  pgPolicy('answer_read', {
    for: 'select',
    using: sql`class_released(release_level_for_response(response_id), 'answer_text')`,
  }),
]).enableRLS()

/** Simultaneously a risk flag and a pricing line (#22). */
export const exception = pgTable('exception', {
  id: uuid('id').primaryKey().defaultRandom(),
  responseId: uuid('response_id').notNull().references(() => response.id),
  requirementId: uuid('requirement_id').references(() => requirement.id),
  text: text('text').notNull(),
  priceDelta: numeric('price_delta', { precision: 14, scale: 2 }),
}, () => [
  pgPolicy('exception_read', {
    for: 'select',
    using: sql`class_released(release_level_for_response(response_id), 'exception_text')`,
  }),
]).enableRLS()

/**
 * Price is a rate function, not a scalar (#22). The shape is closed by #29 —
 * it must be computable, because #15 decision 2 bars any model fallback.
 */
export const priceQuote = pgTable('price_quote', {
  id: uuid('id').primaryKey().defaultRandom(),
  responseId: uuid('response_id').notNull().references(() => response.id),
  priceLineId: uuid('price_line_id').notNull().references(() => priceLine.id),
  rateStructure: jsonb('rate_structure').notNull(),
}, () => [
  pgPolicy('price_quote_read', {
    for: 'select',
    using: sql`class_released(release_level_for_response(response_id), 'price_quote')`,
  }),
]).enableRLS()

/**
 * A comparison figure against the declared scenario — NOT contract value.
 * Requirements contracts carry estimate-only quantities (#22), so anything
 * presenting this as contract value misrepresents comparability (#15).
 */
export const derivedCost = pgTable('derived_cost', {
  id: uuid('id').primaryKey().defaultRandom(),
  responseId: uuid('response_id').notNull().references(() => response.id),
  scenarioId: uuid('scenario_id').notNull().references(() => evaluationScenario.id),
  amount: numeric('amount', { precision: 16, scale: 2 }).notNull(),
  computedAt: timestamp('computed_at', { withTimezone: true }).notNull().defaultNow(),
}, () => [
  pgPolicy('derived_cost_read', {
    for: 'select',
    using: sql`class_released(release_level_for_response(response_id), 'derived_cost')`,
  }),
]).enableRLS()
