CREATE TABLE IF NOT EXISTS nodes (
  id SERIAL PRIMARY KEY,
  name TEXT UNIQUE NOT NULL,
  hostname TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS domains (
  id SERIAL PRIMARY KEY,
  domain TEXT UNIQUE NOT NULL,
  node_name TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'active',
  first_seen_at TIMESTAMPTZ DEFAULT now(),
  last_seen_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS mailboxes (
  id SERIAL PRIMARY KEY,
  email_address TEXT UNIQUE NOT NULL,
  domain TEXT NOT NULL,
  node_name TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'active',
  used_bytes BIGINT DEFAULT 0,
  last_usage_scan_at TIMESTAMPTZ,
  first_seen_at TIMESTAMPTZ DEFAULT now(),
  last_seen_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS admin_users (
  id SERIAL PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  password_hash TEXT NOT NULL,
  role TEXT NOT NULL DEFAULT 'super_admin',
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS audit_log (
  id SERIAL PRIMARY KEY,
  actor_email TEXT,
  action TEXT NOT NULL,
  target TEXT,
  details JSONB,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- ============================================================
-- Upgrade existing MVP database
-- ============================================================

ALTER TABLE nodes
  ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();

ALTER TABLE nodes
  ADD COLUMN IF NOT EXISTS is_current BOOLEAN DEFAULT false;

ALTER TABLE domains
  ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();

ALTER TABLE domains
  ADD COLUMN IF NOT EXISTS last_synced_at TIMESTAMPTZ;

ALTER TABLE domains
  ADD COLUMN IF NOT EXISTS notes TEXT DEFAULT '';

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS local_part TEXT;

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS quota_bytes BIGINT;

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS quota_percent NUMERIC(8,3);

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS message_count BIGINT;

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS message_limit BIGINT;

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS usage_scanned_at TIMESTAMPTZ;

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();

ALTER TABLE mailboxes
  ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;

ALTER TABLE admin_users
  ADD COLUMN IF NOT EXISTS allowed_domains TEXT[] NOT NULL DEFAULT '{}';

ALTER TABLE admin_users
  ADD COLUMN IF NOT EXISTS active BOOLEAN NOT NULL DEFAULT true;

ALTER TABLE admin_users
  ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT now();

ALTER TABLE audit_log
  ADD COLUMN IF NOT EXISTS target_type TEXT;

ALTER TABLE audit_log
  ADD COLUMN IF NOT EXISTS target_id TEXT;

ALTER TABLE audit_log
  ADD COLUMN IF NOT EXISTS ip_address TEXT;

-- details existed already, but make it safer for newer code
ALTER TABLE audit_log
  ALTER COLUMN details SET DEFAULT '{}';

-- Fill local_part for existing rows
UPDATE mailboxes
SET local_part = split_part(email_address, '@', 1)
WHERE local_part IS NULL
  AND email_address LIKE '%@%';

-- Keep old and new usage timestamp columns in sync initially
UPDATE mailboxes
SET usage_scanned_at = last_usage_scan_at
WHERE usage_scanned_at IS NULL
  AND last_usage_scan_at IS NOT NULL;

-- Backfill new audit target columns from old target column
UPDATE audit_log
SET target_id = target
WHERE target_id IS NULL
  AND target IS NOT NULL;

UPDATE audit_log
SET target_type = 'unknown'
WHERE target_type IS NULL;

-- Useful indexes
CREATE INDEX IF NOT EXISTS idx_domains_node_name
  ON domains(node_name);

CREATE INDEX IF NOT EXISTS idx_mailboxes_domain
  ON mailboxes(domain);

CREATE INDEX IF NOT EXISTS idx_mailboxes_node_name
  ON mailboxes(node_name);

CREATE INDEX IF NOT EXISTS idx_audit_created
  ON audit_log(created_at DESC);

CREATE INDEX IF NOT EXISTS idx_admin_users_allowed_domains
  ON admin_users USING GIN(allowed_domains);