--
-- This file is part of TALER
-- Copyright (C) 2024, 2025 Taler Systems SA
--
-- TALER is free software; you can redistribute it and/or modify it under the
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; either version 3, or (at your option) any later version.
--
-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with
-- TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
--

-- NOTE: do not use DROP, that would remove the TRIGGER!
CREATE OR REPLACE FUNCTION handle_category_changes()
RETURNS TRIGGER AS $$
DECLARE
  my_merchant_serial BIGINT;
  resolved_body TEXT;
  webhook RECORD; -- To iterate over all webhooks matching the event type
BEGIN
  -- Fetch the merchant_serial directly from the NEW or OLD row
  my_merchant_serial := COALESCE(OLD.merchant_serial, NEW.merchant_serial);

  -- INSERT case: Add a webhook for category addition
  IF TG_OP = 'INSERT' THEN
    FOR webhook IN
      SELECT webhook_serial,
             merchant_serial,
	     url,
	     http_method,
	     body_template
      FROM merchant.merchant_webhook
      WHERE event_type = 'category_added'
        AND merchant_serial = my_merchant_serial
    LOOP
      -- Resolve placeholders for the current webhook
      resolved_body := webhook.body_template;
      resolved_body := replace_placeholder(resolved_body,
                                           'webhook_type',
                                           'category_added');
      resolved_body := replace_placeholder(resolved_body,
                                           'category_serial',
                                           NEW.category_serial::TEXT);
      resolved_body := replace_placeholder(resolved_body,
                                           'category_name',
                                           NEW.category_name);
      resolved_body := replace_placeholder(resolved_body,
                                           'merchant_serial',
                                           my_merchant_serial::TEXT);

      -- Insert into pending webhooks for this webhook
      INSERT INTO merchant.merchant_pending_webhooks
      (merchant_serial, webhook_serial, url, http_method, body)
      VALUES
      (webhook.merchant_serial,
       webhook.webhook_serial,
       webhook.url,
       webhook.http_method,
       resolved_body);
    END LOOP;

    -- Notify the webhook service for the TALER_DBEVENT_MERCHANT_WEBHOOK_PENDING
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  -- UPDATE case: Add a webhook for category update
  IF TG_OP = 'UPDATE' THEN
    FOR webhook IN
      SELECT webhook_serial,
             merchant_serial,
	     url,
	     http_method,
	     body_template
      FROM merchant.merchant_webhook
      WHERE event_type = 'category_updated'
        AND merchant_serial = my_merchant_serial
    LOOP
      -- Resolve placeholders for the current webhook
      resolved_body := webhook.body_template;
      resolved_body := replace_placeholder(resolved_body,
                                           'webhook_type',
                                           'category_updated');
      resolved_body := replace_placeholder(resolved_body,
                                           'category_serial',
                                           NEW.category_serial::TEXT);
      resolved_body := replace_placeholder(resolved_body,
                                           'old_category_name',
                                           OLD.category_name);
      resolved_body := replace_placeholder(resolved_body,
                                           'category_name',
                                           NEW.category_name);
      resolved_body := replace_placeholder(resolved_body,
                                           'category_name_i18n',
                                           NEW.category_name_i18n::TEXT);
      resolved_body := replace_placeholder(resolved_body,
                                           'old_category_name_i18n',
                                           OLD.category_name_i18n::TEXT);

      -- Insert into pending webhooks for this webhook
      INSERT INTO merchant.merchant_pending_webhooks
        (merchant_serial, webhook_serial, url, http_method, body)
      VALUES
        (webhook.merchant_serial,
         webhook.webhook_serial,
         webhook.url,
         webhook.http_method,
         resolved_body);
    END LOOP;

    -- Notify the webhook service for the TALER_DBEVENT_MERCHANT_WEBHOOK_PENDING
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  -- DELETE case: Add a webhook for category deletion
  IF TG_OP = 'DELETE' THEN
    FOR webhook IN
      SELECT webhook_serial,
             merchant_serial,
	     url,
	     http_method,
	     body_template
      FROM merchant.merchant_webhook
      WHERE event_type = 'category_deleted'
        AND merchant_serial = my_merchant_serial
    LOOP
      -- Resolve placeholders for the current webhook
      resolved_body := webhook.body_template;
      resolved_body := replace_placeholder(resolved_body,
                                           'webhook_type',
                                           'category_deleted');
      resolved_body := replace_placeholder(resolved_body,
                                           'category_serial',
                                           OLD.category_serial::TEXT);
      resolved_body := replace_placeholder(resolved_body,
                                           'category_name',
                                           OLD.category_name);

      -- Insert into pending webhooks for this webhook
      INSERT INTO merchant.merchant_pending_webhooks
      (merchant_serial, webhook_serial, url, http_method, body)
      VALUES
      (webhook.merchant_serial,
       webhook.webhook_serial,
       webhook.url,
       webhook.http_method,
       resolved_body);
    END LOOP;

    -- Notify the webhook service for the TALER_DBEVENT_MERCHANT_WEBHOOK_PENDING
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION handle_category_changes
  IS 'Trigger function to handle pending webhooks for category changes';
