-- Migration 159: Repair SAG email threading schema (idempotent)
-- Purpose:
-- 1) Ensure sag_emails link table exists and is constrained correctly.
-- 2) Ensure email_messages has threading columns used by SAG email tab.
-- 3) Backfill thread_key where missing.

-- Ensure link table exists
CREATE TABLE IF NOT EXISTS sag_emails (
    sag_id INTEGER REFERENCES sag_sager(id) ON DELETE CASCADE,
    email_id INTEGER REFERENCES email_messages(id) ON DELETE CASCADE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Ensure required columns on email_messages exist
ALTER TABLE email_messages
    ADD COLUMN IF NOT EXISTS in_reply_to VARCHAR(500),
    ADD COLUMN IF NOT EXISTS email_references TEXT,
    ADD COLUMN IF NOT EXISTS thread_key VARCHAR(500);

-- Cleanup duplicates before adding unique constraint/PK
WITH ranked AS (
    SELECT ctid,
           ROW_NUMBER() OVER (PARTITION BY sag_id, email_id ORDER BY created_at NULLS LAST, ctid) AS rn
    FROM sag_emails
)
DELETE FROM sag_emails se
USING ranked r
WHERE se.ctid = r.ctid
  AND r.rn > 1;

-- Ensure PK exists
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1
        FROM pg_constraint
        WHERE conname = 'sag_emails_pkey'
          AND conrelid = 'sag_emails'::regclass
    ) THEN
        ALTER TABLE sag_emails
            ADD CONSTRAINT sag_emails_pkey PRIMARY KEY (sag_id, email_id);
    END IF;
END $$;

-- Ensure FKs exist
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1
        FROM pg_constraint
        WHERE conname = 'sag_emails_sag_id_fkey'
          AND conrelid = 'sag_emails'::regclass
    ) THEN
        ALTER TABLE sag_emails
            ADD CONSTRAINT sag_emails_sag_id_fkey
            FOREIGN KEY (sag_id) REFERENCES sag_sager(id) ON DELETE CASCADE;
    END IF;

    IF NOT EXISTS (
        SELECT 1
        FROM pg_constraint
        WHERE conname = 'sag_emails_email_id_fkey'
          AND conrelid = 'sag_emails'::regclass
    ) THEN
        ALTER TABLE sag_emails
            ADD CONSTRAINT sag_emails_email_id_fkey
            FOREIGN KEY (email_id) REFERENCES email_messages(id) ON DELETE CASCADE;
    END IF;
END $$;

-- Helpful indexes for case email tab
CREATE INDEX IF NOT EXISTS idx_sag_emails_sag_id ON sag_emails(sag_id);
CREATE INDEX IF NOT EXISTS idx_sag_emails_email_id ON sag_emails(email_id);
CREATE INDEX IF NOT EXISTS idx_email_messages_thread_key ON email_messages(thread_key) WHERE thread_key IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_email_messages_in_reply_to ON email_messages(in_reply_to) WHERE in_reply_to IS NOT NULL;

-- Backfill thread_key for rows where it is missing
UPDATE email_messages
SET thread_key = LOWER(
    REGEXP_REPLACE(
        COALESCE(
            NULLIF(
                SPLIT_PART(
                    REGEXP_REPLACE(COALESCE(email_references, ''), '^[\s<>,]+', ''),
                    ' ',
                    1
                ),
                ''
            ),
            NULLIF(in_reply_to, ''),
            NULLIF(message_id, '')
        ),
        '[<>\s]',
        '',
        'g'
    )
)
WHERE (thread_key IS NULL OR TRIM(thread_key) = '')
  AND COALESCE(NULLIF(email_references, ''), NULLIF(in_reply_to, ''), NULLIF(message_id, '')) IS NOT NULL;

COMMENT ON TABLE sag_emails IS 'Emails linked to the Case (SAG).';
COMMENT ON COLUMN email_messages.in_reply_to IS 'Raw In-Reply-To header used for SAG threading lookup';
COMMENT ON COLUMN email_messages.email_references IS 'Raw References header used for SAG threading lookup';
COMMENT ON COLUMN email_messages.thread_key IS 'Stable normalized thread key for grouping email conversations';
