-- IHF Phase 12 — Platform Memory and Continuous Learning
-- Workplan: IHUB-WP-0013

-- outcome_correlations
CREATE TABLE outcome_correlations (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    hub_id UUID NOT NULL REFERENCES hubs(id),
    annotation_category TEXT NOT NULL REFERENCES annotation_category_registry(name),
    correlation_type TEXT NOT NULL DEFAULT 'annotation_predictor',
    correlation_score DOUBLE PRECISION NOT NULL,
    sample_count INTEGER NOT NULL DEFAULT 0,
    computed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
    CHECK (correlation_type IN ('annotation_predictor', 'routing_quality', 'pattern_quality'))
);

CREATE INDEX outcome_correlations_hub_idx ON outcome_correlations (hub_id);
CREATE INDEX outcome_correlations_score_idx ON outcome_correlations (correlation_score DESC);

-- pattern_performance_records
CREATE TABLE pattern_performance_records (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    widget_pattern_id UUID NOT NULL REFERENCES widget_patterns(id),
    hub_id UUID NOT NULL REFERENCES hubs(id),
    adoption_count INTEGER NOT NULL DEFAULT 0,
    positive_outcome_count INTEGER NOT NULL DEFAULT 0,
    total_outcome_count INTEGER NOT NULL DEFAULT 0,
    mean_outcome_value DOUBLE PRECISION,
    outcome_rank INTEGER,
    calibrated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
    UNIQUE (widget_pattern_id, hub_id)
);

CREATE INDEX pattern_performance_pattern_idx ON pattern_performance_records (widget_pattern_id);
CREATE INDEX pattern_performance_rank_idx ON pattern_performance_records (hub_id, outcome_rank);

-- adaptive_threshold_configs
CREATE TABLE adaptive_threshold_configs (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    hub_id UUID NOT NULL REFERENCES hubs(id) UNIQUE,
    weight_overrides JSONB NOT NULL DEFAULT '{}',
    bottleneck_threshold_override DOUBLE PRECISION,
    calibration_date TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
    notes TEXT
);

CREATE INDEX adaptive_threshold_hub_idx ON adaptive_threshold_configs (hub_id);

-- institutional_knowledge_entries
CREATE TABLE institutional_knowledge_entries (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    hub_id UUID NOT NULL REFERENCES hubs(id),
    decision_record_id UUID REFERENCES decision_records(id),
    summary TEXT NOT NULL,
    summary_tsv TSVECTOR GENERATED ALWAYS AS (to_tsvector('english', summary)) STORED,
    tags JSONB NOT NULL DEFAULT '[]',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
);

CREATE INDEX institutional_knowledge_hub_idx ON institutional_knowledge_entries (hub_id);
CREATE INDEX institutional_knowledge_fts_idx ON institutional_knowledge_entries USING GIN (summary_tsv);

-- learning_insights
CREATE TABLE learning_insights (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
    hub_id UUID NOT NULL REFERENCES hubs(id),
    insight_type TEXT NOT NULL,
    title TEXT NOT NULL,
    body TEXT NOT NULL,
    evidence_links JSONB NOT NULL DEFAULT '[]',
    is_actioned BOOLEAN NOT NULL DEFAULT FALSE,
    computed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
    CHECK (insight_type IN (
        'annotation_predictor',
        'threshold_calibration',
        'pattern_ranking',
        'routing_improvement'
    ))
);

CREATE INDEX learning_insights_hub_idx ON learning_insights (hub_id);
CREATE INDEX learning_insights_type_idx ON learning_insights (insight_type);

-- Extend core tables — outcome_summary for retroactive lineage enrichment
-- GAAF rule 3: contracts/core/ updated separately
ALTER TABLE decision_records
    ADD COLUMN outcome_summary JSONB NULL;

ALTER TABLE requirement_candidates
    ADD COLUMN outcome_summary JSONB NULL;

-- Retroactive lineage enrichment trigger (T06)
CREATE OR REPLACE FUNCTION enrich_lineage_on_outcome()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
DECLARE
    v_dec_id  UUID;
    v_req_id  UUID;
    v_cand_id UUID;
    v_summary JSONB;
BEGIN
    -- Walk chain upward from the new outcome_signal
    SELECT decision_id INTO v_dec_id
    FROM deployment_records WHERE id = NEW.deployment_id;

    IF v_dec_id IS NOT NULL THEN
        v_summary := jsonb_build_object(
            'signal_type', NEW.signal_type,
            'value',       NEW.value,
            'observed_at', NEW.observed_at
        );

        -- Append to decision_records.outcome_summary (non-append-only column)
        UPDATE decision_records
        SET outcome_summary = COALESCE(outcome_summary, '[]'::jsonb) || v_summary
        WHERE id = v_dec_id;

        SELECT requirement_id INTO v_req_id
        FROM decision_records WHERE id = v_dec_id;

        IF v_req_id IS NOT NULL THEN
            SELECT candidate_id INTO v_cand_id
            FROM requirements WHERE id = v_req_id;

            IF v_cand_id IS NOT NULL THEN
                UPDATE requirement_candidates
                SET outcome_summary = COALESCE(outcome_summary, '[]'::jsonb) || v_summary
                WHERE id = v_cand_id;
            END IF;
        END IF;
    END IF;

    RETURN NEW;
END;
$$;

CREATE TRIGGER trg_enrich_lineage
AFTER INSERT ON outcome_signals
FOR EACH ROW EXECUTE FUNCTION enrich_lineage_on_outcome();

-- Batch enrichment helper: called on-demand by EnrichLineageAction
-- Applies the same logic as enrich_lineage_on_outcome() for a given signal id
CREATE OR REPLACE FUNCTION enrich_lineage_on_outcome_batch(p_signal_id UUID)
RETURNS VOID LANGUAGE plpgsql AS $$
DECLARE
    v_sig     RECORD;
    v_dec_id  UUID;
    v_req_id  UUID;
    v_cand_id UUID;
    v_summary JSONB;
BEGIN
    SELECT * INTO v_sig FROM outcome_signals WHERE id = p_signal_id;

    SELECT decision_id INTO v_dec_id
    FROM deployment_records WHERE id = v_sig.deployment_id;

    IF v_dec_id IS NOT NULL THEN
        v_summary := jsonb_build_object(
            'signal_type', v_sig.signal_type,
            'value',       v_sig.value,
            'observed_at', v_sig.observed_at
        );

        UPDATE decision_records
        SET outcome_summary = COALESCE(outcome_summary, '[]'::jsonb) || v_summary
        WHERE id = v_dec_id;

        SELECT requirement_id INTO v_req_id
        FROM decision_records WHERE id = v_dec_id;

        IF v_req_id IS NOT NULL THEN
            SELECT candidate_id INTO v_cand_id
            FROM requirements WHERE id = v_req_id;

            IF v_cand_id IS NOT NULL THEN
                UPDATE requirement_candidates
                SET outcome_summary = COALESCE(outcome_summary, '[]'::jsonb) || v_summary
                WHERE id = v_cand_id;
            END IF;
        END IF;
    END IF;
END;
$$;
