-- Migration: LISTEN/NOTIFY Triggers
-- Description: Consolidated PostgreSQL LISTEN/NOTIFY triggers for real-time event notifications
-- Version: 20250101000008

-- ============================================================================
-- EXECUTION CHANGE NOTIFICATION
-- ============================================================================

-- Function to notify on execution creation
CREATE OR REPLACE FUNCTION notify_execution_created()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
    enforcement_rule_ref TEXT;
    enforcement_trigger_ref TEXT;
BEGIN
    -- Lookup enforcement details if this execution is linked to an enforcement
    IF NEW.enforcement IS NOT NULL THEN
        SELECT rule_ref, trigger_ref
        INTO enforcement_rule_ref, enforcement_trigger_ref
        FROM enforcement
        WHERE id = NEW.enforcement;
    END IF;

    payload := json_build_object(
        'entity_type', 'execution',
        'entity_id', NEW.id,
        'id', NEW.id,
        'action_id', NEW.action,
        'action_ref', NEW.action_ref,
        'status', NEW.status,
        'enforcement', NEW.enforcement,
        'rule_ref', enforcement_rule_ref,
        'trigger_ref', enforcement_trigger_ref,
        'parent', NEW.parent,
        'result', NEW.result,
        'created', NEW.created,
        'updated', NEW.updated
    );

    PERFORM pg_notify('execution_created', payload::text);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Function to notify on execution status changes
CREATE OR REPLACE FUNCTION notify_execution_status_changed()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
    enforcement_rule_ref TEXT;
    enforcement_trigger_ref TEXT;
BEGIN
    -- Only notify on updates, not inserts
    IF TG_OP = 'UPDATE' AND OLD.status IS DISTINCT FROM NEW.status THEN
        -- Lookup enforcement details if this execution is linked to an enforcement
        IF NEW.enforcement IS NOT NULL THEN
            SELECT rule_ref, trigger_ref
            INTO enforcement_rule_ref, enforcement_trigger_ref
            FROM enforcement
            WHERE id = NEW.enforcement;
        END IF;

        payload := json_build_object(
            'entity_type', 'execution',
            'entity_id', NEW.id,
            'id', NEW.id,
            'action_id', NEW.action,
            'action_ref', NEW.action_ref,
            'status', NEW.status,
            'old_status', OLD.status,
            'enforcement', NEW.enforcement,
            'rule_ref', enforcement_rule_ref,
            'trigger_ref', enforcement_trigger_ref,
            'parent', NEW.parent,
            'result', NEW.result,
            'created', NEW.created,
            'updated', NEW.updated
        );

        PERFORM pg_notify('execution_status_changed', payload::text);
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger on execution table for creation
CREATE TRIGGER execution_created_notify
    AFTER INSERT ON execution
    FOR EACH ROW
    EXECUTE FUNCTION notify_execution_created();

-- Trigger on execution table for status changes
CREATE TRIGGER execution_status_changed_notify
    AFTER UPDATE ON execution
    FOR EACH ROW
    EXECUTE FUNCTION notify_execution_status_changed();

COMMENT ON FUNCTION notify_execution_created() IS 'Sends execution creation notifications via PostgreSQL LISTEN/NOTIFY';
COMMENT ON FUNCTION notify_execution_status_changed() IS 'Sends execution status change notifications via PostgreSQL LISTEN/NOTIFY';

-- ============================================================================
-- EVENT CREATION NOTIFICATION
-- ============================================================================

-- Function to notify on event creation
CREATE OR REPLACE FUNCTION notify_event_created()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
BEGIN
    payload := json_build_object(
        'entity_type', 'event',
        'entity_id', NEW.id,
        'id', NEW.id,
        'trigger', NEW.trigger,
        'trigger_ref', NEW.trigger_ref,
        'source', NEW.source,
        'source_ref', NEW.source_ref,
        'rule', NEW.rule,
        'rule_ref', NEW.rule_ref,
        'payload', NEW.payload,
        'created', NEW.created
    );

    PERFORM pg_notify('event_created', payload::text);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger on event table
CREATE TRIGGER event_created_notify
    AFTER INSERT ON event
    FOR EACH ROW
    EXECUTE FUNCTION notify_event_created();

COMMENT ON FUNCTION notify_event_created() IS 'Sends event creation notifications via PostgreSQL LISTEN/NOTIFY';

-- ============================================================================
-- ENFORCEMENT CHANGE NOTIFICATION
-- ============================================================================

-- Function to notify on enforcement creation
CREATE OR REPLACE FUNCTION notify_enforcement_created()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
BEGIN
    payload := json_build_object(
        'entity_type', 'enforcement',
        'entity_id', NEW.id,
        'id', NEW.id,
        'rule', NEW.rule,
        'rule_ref', NEW.rule_ref,
        'trigger_ref', NEW.trigger_ref,
        'event', NEW.event,
        'status', NEW.status,
        'condition', NEW.condition,
        'conditions', NEW.conditions,
        'config', NEW.config,
        'payload', NEW.payload,
        'created', NEW.created,
        'updated', NEW.updated
    );

    PERFORM pg_notify('enforcement_created', payload::text);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger on enforcement table
CREATE TRIGGER enforcement_created_notify
    AFTER INSERT ON enforcement
    FOR EACH ROW
    EXECUTE FUNCTION notify_enforcement_created();

COMMENT ON FUNCTION notify_enforcement_created() IS 'Sends enforcement creation notifications via PostgreSQL LISTEN/NOTIFY';

-- ============================================================================
-- INQUIRY NOTIFICATIONS
-- ============================================================================

-- Function to notify on inquiry creation
CREATE OR REPLACE FUNCTION notify_inquiry_created()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
BEGIN
    payload := json_build_object(
        'entity_type', 'inquiry',
        'entity_id', NEW.id,
        'id', NEW.id,
        'execution', NEW.execution,
        'status', NEW.status,
        'ttl', NEW.ttl,
        'created', NEW.created
    );

    PERFORM pg_notify('inquiry_created', payload::text);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Function to notify on inquiry response
CREATE OR REPLACE FUNCTION notify_inquiry_responded()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
BEGIN
    -- Only notify when status changes to 'responded'
    IF TG_OP = 'UPDATE' AND NEW.status = 'responded' AND OLD.status != 'responded' THEN
        payload := json_build_object(
            'entity_type', 'inquiry',
            'entity_id', NEW.id,
            'id', NEW.id,
            'execution', NEW.execution,
            'status', NEW.status,
            'response', NEW.response,
            'updated', NEW.updated
        );

        PERFORM pg_notify('inquiry_responded', payload::text);
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger on inquiry table for creation
CREATE TRIGGER inquiry_created_notify
    AFTER INSERT ON inquiry
    FOR EACH ROW
    EXECUTE FUNCTION notify_inquiry_created();

-- Trigger on inquiry table for responses
CREATE TRIGGER inquiry_responded_notify
    AFTER UPDATE ON inquiry
    FOR EACH ROW
    EXECUTE FUNCTION notify_inquiry_responded();

COMMENT ON FUNCTION notify_inquiry_created() IS 'Sends inquiry creation notifications via PostgreSQL LISTEN/NOTIFY';
COMMENT ON FUNCTION notify_inquiry_responded() IS 'Sends inquiry response notifications via PostgreSQL LISTEN/NOTIFY';

-- ============================================================================
-- WORKFLOW EXECUTION NOTIFICATIONS
-- ============================================================================

-- Function to notify on workflow execution status changes
CREATE OR REPLACE FUNCTION notify_workflow_execution_status_changed()
RETURNS TRIGGER AS $$
DECLARE
    payload JSON;
BEGIN
    -- Only notify for workflow executions when status changes
    IF TG_OP = 'UPDATE' AND NEW.is_workflow = true AND OLD.status IS DISTINCT FROM NEW.status THEN
        payload := json_build_object(
            'entity_type', 'execution',
            'entity_id', NEW.id,
            'id', NEW.id,
            'action_ref', NEW.action_ref,
            'status', NEW.status,
            'old_status', OLD.status,
            'workflow_def', NEW.workflow_def,
            'parent', NEW.parent,
            'created', NEW.created,
            'updated', NEW.updated
        );

        PERFORM pg_notify('workflow_execution_status_changed', payload::text);
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger on execution table for workflow status changes
CREATE TRIGGER workflow_execution_status_changed_notify
    AFTER UPDATE ON execution
    FOR EACH ROW
    WHEN (NEW.is_workflow = true)
    EXECUTE FUNCTION notify_workflow_execution_status_changed();

COMMENT ON FUNCTION notify_workflow_execution_status_changed() IS 'Sends workflow execution status change notifications via PostgreSQL LISTEN/NOTIFY';
