-- Migration: mail_blocked_stats_aggregation
-- Permanente Aggregat-Tabelle für blockierte Mails (counts/dates only, KEINE Inhalte).
-- Löst das DSGVO-Spannungsfeld: mail_blocked wird nach 24h gelöscht (Datenminimierung
-- Art. 5 Abs. 1 lit. e), während Stats-Charts weiterhin historische Daten zeigen können.
--
-- Stats enthalten ausschließlich: userId, date (UTC), connectionId, provider-host, count.
-- Kein Subject, kein Sender, kein Mail-Inhalt — Aggregat ist unbedenklich i.S. Art. 9.
--
-- Lösch-Verhalten: ON DELETE CASCADE wenn MailConnection gelöscht wird.
-- Begründung: User-initiierter Disconnect = Art. 17-Löschanfrage; Stats sind an
-- diese Connection geknüpft; Cascade hält DB konsistent ohne nullable foreign-key.
-- Hans-Müller-Note: Aggregat-Stats sind kein "Personenbezug zur Mail" mehr, aber
-- der Bezug zur Connection-ID bleibt — Cascade ist DSGVO-konservativere Wahl.
--
-- Backfill: Einmalig aus bestehenden mail_blocked-Rows der letzten 30 Tage.
-- provider-Spalte speichert imap_host als rohen String; resolveProviderMeta()
-- wird zur Read-Zeit im Stats-Endpoint aufgerufen (TypeScript, nicht SQL).
-- Für den Backfill wird imap_host doppelt als providerLabel eingetragen —
-- der Live-Scan-Code schreibt ab jetzt den korrekten resolved Label.
-- Ein separater Script (backend/scripts/backfill-stats-provider.ts) kann nachgezogen
-- werden wenn die Labels im Chart sauber sein sollen; für MVP nicht kritisch.
--
-- Deploy: automatisch via GitHub Actions (pnpm prisma migrate deploy)

CREATE TABLE "rebreak"."mail_blocked_stats" (
  "id"                   TEXT         NOT NULL,
  "user_id"              UUID         NOT NULL,
  "date"                 DATE         NOT NULL,
  "mail_connection_id"   UUID         NOT NULL,
  "provider"             TEXT         NOT NULL,
  "provider_label"       TEXT         NOT NULL,
  "count"                INTEGER      NOT NULL DEFAULT 0,

  CONSTRAINT "mail_blocked_stats_pkey" PRIMARY KEY ("id"),
  CONSTRAINT "mail_blocked_stats_unique_day"
    UNIQUE ("user_id", "date", "mail_connection_id"),
  CONSTRAINT "mail_blocked_stats_connection_fkey"
    FOREIGN KEY ("mail_connection_id")
    REFERENCES "rebreak"."mail_connections" ("id")
    ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE INDEX "mail_blocked_stats_user_date_idx"
  ON "rebreak"."mail_blocked_stats" ("user_id", "date");

CREATE INDEX "mail_blocked_stats_user_connection_idx"
  ON "rebreak"."mail_blocked_stats" ("user_id", "mail_connection_id");

-- Backfill: bestehende mail_blocked-Rows der letzten 30 Tage aggregieren.
-- imap_host wird als provider UND provider_label gespeichert (rohes Datum).
-- Live-Scan schreibt ab jetzt resolved labels via resolveProviderMeta().
INSERT INTO "rebreak"."mail_blocked_stats"
  ("id", "user_id", "date", "mail_connection_id", "provider", "provider_label", "count")
SELECT
  gen_random_uuid()::text,
  mb."user_id",
  DATE(mb."created_at" AT TIME ZONE 'UTC') AS "date",
  mb."connection_id",
  mc."imap_host",
  mc."imap_host",
  COUNT(*)::integer
FROM "rebreak"."mail_blocked" mb
JOIN "rebreak"."mail_connections" mc ON mc."id" = mb."connection_id"
WHERE mb."created_at" > NOW() - INTERVAL '30 days'
GROUP BY mb."user_id", DATE(mb."created_at" AT TIME ZONE 'UTC'), mb."connection_id", mc."imap_host"
ON CONFLICT ("user_id", "date", "mail_connection_id") DO NOTHING;
