-- Production pre-requisite — run BEFORE applying this migration:
--   docker exec familienarchiv-db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" \
--     -c "SELECT COUNT(DISTINCT (geschichte_id, document_id)) FROM geschichten_documents;"'
--   docker exec familienarchiv-db sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" \
--     --table=geschichten_documents \
--     -f /tmp/pre_v72_backup_'"$(date +%Y%m%d)"'.sql'
-- Take the dump even if geschichten_documents is empty — it captures the table DEFINITION
-- for emergency reconstruction. The DROP TABLE is the only irreversible step; the
-- INSERT...SELECT is a no-op when there is no data. No DDL rollback path exists after commit.
--
-- REVERSE PROCEDURE (if V72 must be rolled back): restore the pre-V72 dump, then re-derive
-- the junction from the new table:
--   INSERT INTO geschichten_documents (geschichte_id, document_id)
--     SELECT geschichte_id, document_id FROM journey_items WHERE document_id IS NOT NULL;
-- Note: the reconstructed junction FK is ON DELETE CASCADE per the original V58
-- (NOT the new SET NULL of journey_items). Domain FKs target app_users (post-V60) —
-- do NOT hand-type V58's verbatim "REFERENCES users" DDL nor copy journey_items' SET NULL
-- into the reconstructed junction.
--
-- ASSUMPTION AS-001: The old geschichten_documents was an unordered Set — no curator order
-- existed. Ordering by meta_date is a plausible default a Lesereise lets curators
-- re-sequence. This is not a requirement; it is the best available approximation.
--
-- ASSUMPTION AS-002: Existing published Geschichten (STORYs) render the related-letters block;
-- this block visibly degrades to generic links (loss of per-document title AND date) for ALL
-- current readers during the stub window. Accepted because the reader follow-on is the
-- next-priority blocking dependency.

-- Step 1: Add type discriminator column to geschichten
ALTER TABLE geschichten
    ADD COLUMN type VARCHAR(50) DEFAULT 'STORY' NOT NULL;

-- Step 2: Create journey_items table
CREATE TABLE journey_items (
    id            UUID        NOT NULL DEFAULT gen_random_uuid(),
    geschichte_id UUID        NOT NULL,
    position      INT         NOT NULL,
    document_id   UUID,
    note          TEXT,
    CONSTRAINT pk_journey_items PRIMARY KEY (id),
    CONSTRAINT fk_journey_items_geschichte
        FOREIGN KEY (geschichte_id) REFERENCES geschichten(id) ON DELETE CASCADE,
    CONSTRAINT fk_journey_items_document
        FOREIGN KEY (document_id) REFERENCES documents(id) ON DELETE SET NULL,
    CONSTRAINT chk_journey_item_not_empty
        CHECK (document_id IS NOT NULL OR note IS NOT NULL)
);

-- Step 3: Index for ordered retrieval by geschichte + position
CREATE INDEX idx_journey_items_geschichte_position
    ON journey_items (geschichte_id, position ASC);

-- Step 4: Migrate geschichten_documents → journey_items
-- Positions are multiples of 1000 (headroom for drag-reorder).
-- Ordered by meta_date ASC NULLS LAST, then documents.id ASC as deterministic tiebreaker.
-- SELECT DISTINCT guards against duplicate junction rows producing duplicate journey items.
INSERT INTO journey_items (id, geschichte_id, position, document_id)
SELECT
    gen_random_uuid(),
    gd.geschichte_id,
    (ROW_NUMBER() OVER (
        PARTITION BY gd.geschichte_id
        ORDER BY d.meta_date ASC NULLS LAST, d.id ASC
    ) * 1000)::INT AS position,
    gd.document_id
FROM (
    SELECT DISTINCT geschichte_id, document_id
    FROM geschichten_documents
) gd
LEFT JOIN documents d ON d.id = gd.document_id;

-- Step 5: Drop the old junction table (irreversible — take the pg_dump first)
DROP TABLE geschichten_documents;
