-- =====================================================================================
-- notify_queue + trigger: platform_express_tracking_events -> notify_queue
--
-- 目的：把“轨迹事件入库”和“消息生成/推送”解耦。
-- - Webhook/轮询/手工写入 tracking_events 后，由触发器把关键事件入队到 notify_queue。
-- - 常驻 worker 消费 notify_queue，生成 express_notifications（消息中心/推送任务）。
-- - push-server consumer 轮询 express_notifications 并调用 CLOUD_FUNC_URL 进行实际下发。
--
-- 创建日期：2026-03-09
-- =====================================================================================

BEGIN;

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- 队列表：仅做“轻量入队”，避免触发器做外部 IO
CREATE TABLE IF NOT EXISTS public.notify_queue (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

  waybill_id UUID NOT NULL,
  carrier VARCHAR(32) NULL,
  tracking_no VARCHAR(64) NULL,

  event_id VARCHAR(128) NULL,
  status_code VARCHAR(32) NOT NULL,
  event_time TIMESTAMP WITH TIME ZONE NOT NULL,
  event_text TEXT NULL,
  source VARCHAR(16) NULL,

  -- 与 platform_express_tracking_events 对齐的幂等键
  dedupe_key VARCHAR(256) NOT NULL,
  raw_payload JSONB NULL,

  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  processed_at TIMESTAMP WITH TIME ZONE NULL,
  process_status VARCHAR(32) NULL,
  last_error TEXT NULL,

  CONSTRAINT uk_notify_queue_dedupe UNIQUE (waybill_id, dedupe_key)
);

CREATE INDEX IF NOT EXISTS idx_notify_queue_processed_at ON public.notify_queue(processed_at);
CREATE INDEX IF NOT EXISTS idx_notify_queue_created_at ON public.notify_queue(created_at);
CREATE INDEX IF NOT EXISTS idx_notify_queue_status_code ON public.notify_queue(status_code);

-- 触发器函数：入队关键状态事件
CREATE OR REPLACE FUNCTION public.notify_new_tracking_event()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $func$
DECLARE
  should_enqueue BOOLEAN := FALSE;
BEGIN
  -- 推送策略（MVP）：只对关键状态入队
  IF NEW.status_code IN ('SHIPPED','OUT_FOR_DELIVERY','READY_FOR_PICKUP','DELIVERED','EXCEPTION','RETURNED') THEN
    should_enqueue := TRUE;
  END IF;

  IF should_enqueue THEN
    INSERT INTO public.notify_queue(
      waybill_id,
      carrier,
      tracking_no,
      event_id,
      status_code,
      event_time,
      event_text,
      source,
      dedupe_key,
      raw_payload
    ) VALUES (
      NEW.waybill_id,
      NEW.carrier,
      NEW.tracking_no,
      NEW.event_id,
      NEW.status_code,
      NEW.event_time,
      NEW.event_text,
      NEW.source,
      NEW.dedupe_key,
      NEW.raw_payload
    )
    ON CONFLICT (waybill_id, dedupe_key) DO NOTHING;
  END IF;

  RETURN NEW;
END;
$func$;

-- 触发器：tracking_events 写入后入队
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'trigger_notify_new_tracking_event'
  ) THEN
    CREATE TRIGGER trigger_notify_new_tracking_event
    AFTER INSERT ON public.platform_express_tracking_events
    FOR EACH ROW EXECUTE FUNCTION public.notify_new_tracking_event();
  END IF;
END $$;

COMMIT;
