-- Forms system
--
-- Expands the Forms feature from a single flat submissions table into a real
-- submission workflow with schema versioning, per-submission file attachments,
-- and per-form webhooks.
--
--   * actuate_form_submissions: new workflow columns (entryNumber, sender*,
--     unread/starred/archived, spamStatus, attribution metadata, schema version
--     link, normalizedData, read/archived timestamps, updatedAt).
--   * actuate_form_schema_versions: versioned field-schema snapshots so old
--     submissions always render against the schema they were captured with.
--   * actuate_form_submission_files: file-upload metadata (storage keys, not
--     blobs) with cascade delete from its submission.
--   * actuate_form_webhooks: per-form signed outbound webhooks.
--
-- Safe to apply to a populated database:
--   * Every new column on actuate_form_submissions is nullable or has a default.
--   * updatedAt is backfilled from createdAt for existing rows before the NOT
--     NULL default takes over for new rows.
--   * No existing column is dropped or retyped. formId stays a loose string
--     (no new FK) so historical rows with orphaned formIds are not rejected.

-- ---------------------------------------------------------------------------
-- actuate_form_submissions new columns
-- ---------------------------------------------------------------------------
ALTER TABLE "actuate_form_submissions"
  ADD COLUMN "entryNumber"     INTEGER,
  ADD COLUMN "schemaVersionId" TEXT,
  ADD COLUMN "normalizedData"  JSONB,
  ADD COLUMN "senderName"      TEXT,
  ADD COLUMN "senderEmail"     TEXT,
  ADD COLUMN "senderPhone"     TEXT,
  ADD COLUMN "preview"         TEXT,
  ADD COLUMN "unread"          BOOLEAN NOT NULL DEFAULT true,
  ADD COLUMN "starred"         BOOLEAN NOT NULL DEFAULT false,
  ADD COLUMN "archived"        BOOLEAN NOT NULL DEFAULT false,
  ADD COLUMN "spamStatus"      TEXT NOT NULL DEFAULT 'clean',
  ADD COLUMN "ipAddressHash"   TEXT,
  ADD COLUMN "userAgent"       TEXT,
  ADD COLUMN "referrer"        TEXT,
  ADD COLUMN "pageUrl"         TEXT,
  ADD COLUMN "utmSource"       TEXT,
  ADD COLUMN "utmMedium"       TEXT,
  ADD COLUMN "utmCampaign"     TEXT,
  ADD COLUMN "readAt"          TIMESTAMP(3),
  ADD COLUMN "archivedAt"      TIMESTAMP(3),
  ADD COLUMN "updatedAt"       TIMESTAMP(3);

-- Backfill updatedAt for existing rows, then enforce NOT NULL with a default
-- so new inserts (and Prisma's @updatedAt) always have a value.
UPDATE "actuate_form_submissions" SET "updatedAt" = "createdAt" WHERE "updatedAt" IS NULL;
ALTER TABLE "actuate_form_submissions"
  ALTER COLUMN "updatedAt" SET NOT NULL,
  ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;

-- Existing rows predate the read/unread workflow; treat them as already read so
-- they don't all light up as unread in the new inbox.
UPDATE "actuate_form_submissions" SET "unread" = false WHERE "status" <> 'new';

CREATE INDEX "actuate_form_submissions_unread_idx"      ON "actuate_form_submissions" ("unread");
CREATE INDEX "actuate_form_submissions_starred_idx"     ON "actuate_form_submissions" ("starred");
CREATE INDEX "actuate_form_submissions_archived_idx"    ON "actuate_form_submissions" ("archived");
CREATE INDEX "actuate_form_submissions_spamStatus_idx"  ON "actuate_form_submissions" ("spamStatus");
CREATE INDEX "actuate_form_submissions_submittedAt_idx" ON "actuate_form_submissions" ("submittedAt");
CREATE INDEX "actuate_form_submissions_senderEmail_idx" ON "actuate_form_submissions" ("senderEmail");

-- ---------------------------------------------------------------------------
-- actuate_form_schema_versions
-- ---------------------------------------------------------------------------
CREATE TABLE "actuate_form_schema_versions" (
  "id"          TEXT NOT NULL,
  "formId"      TEXT NOT NULL,
  "version"     INTEGER NOT NULL,
  "fields"      JSONB NOT NULL,
  "notes"       TEXT,
  "createdById" TEXT,
  "createdAt"   TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT "actuate_form_schema_versions_pkey" PRIMARY KEY ("id")
);

CREATE UNIQUE INDEX "actuate_form_schema_versions_formId_version_key"
  ON "actuate_form_schema_versions" ("formId", "version");
CREATE INDEX "actuate_form_schema_versions_formId_idx"
  ON "actuate_form_schema_versions" ("formId");

-- ---------------------------------------------------------------------------
-- actuate_form_submission_files
-- ---------------------------------------------------------------------------
CREATE TABLE "actuate_form_submission_files" (
  "id"                TEXT NOT NULL,
  "submissionId"      TEXT NOT NULL,
  "fieldKey"          TEXT NOT NULL,
  "mediaAssetId"      TEXT,
  "fileName"          TEXT NOT NULL,
  "mimeType"          TEXT NOT NULL,
  "sizeBytes"         INTEGER NOT NULL,
  "storageKey"        TEXT NOT NULL,
  "publicUrl"         TEXT,
  "secureDownloadUrl" TEXT,
  "createdAt"         TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT "actuate_form_submission_files_pkey" PRIMARY KEY ("id")
);

CREATE INDEX "actuate_form_submission_files_submissionId_idx"
  ON "actuate_form_submission_files" ("submissionId");

ALTER TABLE "actuate_form_submission_files"
  ADD CONSTRAINT "actuate_form_submission_files_submissionId_fkey"
  FOREIGN KEY ("submissionId") REFERENCES "actuate_form_submissions"("id")
  ON DELETE CASCADE ON UPDATE CASCADE;

-- ---------------------------------------------------------------------------
-- actuate_form_webhooks
-- ---------------------------------------------------------------------------
CREATE TABLE "actuate_form_webhooks" (
  "id"                 TEXT NOT NULL,
  "formId"             TEXT NOT NULL,
  "url"                TEXT NOT NULL,
  "secret"             TEXT NOT NULL,
  "enabled"            BOOLEAN NOT NULL DEFAULT true,
  "events"             JSONB NOT NULL,
  "retryCount"         INTEGER NOT NULL DEFAULT 0,
  "lastDeliveryAt"     TIMESTAMP(3),
  "lastDeliveryStatus" TEXT,
  "createdAt"          TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "updatedAt"          TIMESTAMP(3) NOT NULL,
  CONSTRAINT "actuate_form_webhooks_pkey" PRIMARY KEY ("id")
);

CREATE INDEX "actuate_form_webhooks_formId_idx" ON "actuate_form_webhooks" ("formId");
