--
-- 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_inventory_changes()
  RETURNS TRIGGER AS $$
DECLARE
  my_merchant_serial BIGINT;
  resolved_body TEXT;
  webhook RECORD; -- To iterate over all matching webhooks
BEGIN
  -- Fetch the merchant_serial directly from the NEW or OLD row
  my_merchant_serial := COALESCE(OLD.merchant_serial, NEW.merchant_serial);

  -- INSERT case: Notify webhooks for inventory 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 = 'inventory_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',
                                             'inventory_added');
        resolved_body := replace_placeholder(resolved_body,
                                             'product_serial',
                                             NEW.product_serial::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'product_id',
                                             NEW.product_id);
        resolved_body := replace_placeholder(resolved_body,
                                             'description',
                                             NEW.description);
        resolved_body := replace_placeholder(resolved_body,
                                             'description_i18n',
                                             NEW.description_i18n::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'unit',
                                             NEW.unit);
        resolved_body := replace_placeholder(resolved_body,
                                             'image',
                                             NEW.image);
        resolved_body := replace_placeholder(resolved_body,
                                             'taxes',
                                             NEW.taxes::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'price',
                                             NEW.price::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_stock',
                                             NEW.total_stock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_sold',
                                             NEW.total_sold::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_lost',
                                             NEW.total_lost::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'address',
                                             NEW.address::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'next_restock',
                                             NEW.next_restock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'minimum_age',
                                             NEW.minimum_age::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
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  -- UPDATE case: Notify webhooks for inventory 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 = 'inventory_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',
                                             'inventory_updated');
        resolved_body := replace_placeholder(resolved_body,
                                             'product_serial',
                                             NEW.product_serial::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'product_id',
                                             NEW.product_id);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_description',
                                             OLD.description);
        resolved_body := replace_placeholder(resolved_body,
                                             'description',
                                             NEW.description);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_description_i18n',
                                             OLD.description_i18n::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'description_i18n',
                                             NEW.description_i18n::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_unit',
                                             OLD.unit);
        resolved_body := replace_placeholder(resolved_body,
                                             'unit',
                                             NEW.unit);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_image',
                                             OLD.image);
        resolved_body := replace_placeholder(resolved_body,
                                             'image',
                                             NEW.image);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_taxes',
                                             OLD.taxes::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'taxes',
                                             NEW.taxes::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_price',
                                             OLD.price::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'price',
                                             NEW.price::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_total_stock',
                                             OLD.total_stock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_stock',
                                             NEW.total_stock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_total_sold',
                                             OLD.total_sold::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_sold',
                                             NEW.total_sold::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_total_lost',
                                             OLD.total_lost::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_lost',
                                             NEW.total_lost::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_address',
                                             OLD.address::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'address',
                                             NEW.address::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_next_restock',
                                             OLD.next_restock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'next_restock',
                                             NEW.next_restock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'old_minimum_age',
                                             OLD.minimum_age::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'minimum_age',
                                             NEW.minimum_age::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
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  -- DELETE case: Notify webhooks for inventory 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 = 'inventory_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',
                                             'inventory_deleted');
        resolved_body := replace_placeholder(resolved_body,
                                             'product_serial',
                                             OLD.product_serial::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'product_id',
                                             OLD.product_id);
        resolved_body := replace_placeholder(resolved_body,
                                             'description',
                                             OLD.description);
        resolved_body := replace_placeholder(resolved_body,
                                             'description_i18n',
                                             OLD.description_i18n::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'unit',
                                             OLD.unit);
        resolved_body := replace_placeholder(resolved_body,
                                             'image',
                                             OLD.image);
        resolved_body := replace_placeholder(resolved_body,
                                             'taxes',
                                             OLD.taxes::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'price',
                                             OLD.price::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_stock',
                                             OLD.total_stock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_sold',
                                             OLD.total_sold::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'total_lost',
                                             OLD.total_lost::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'address',
                                             OLD.address::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'next_restock',
                                             OLD.next_restock::TEXT);
        resolved_body := replace_placeholder(resolved_body,
                                             'minimum_age',
                                             OLD.minimum_age::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
    NOTIFY XXJWF6C1DCS1255RJH7GQ1EK16J8DMRSQ6K9EDKNKCP7HRVWAJPKG;
  END IF;

  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

COMMENT ON FUNCTION handle_inventory_changes
  IS 'Function to handle inventory changes and notify webhooks';
