BEGIN;

-- Fix lot auto-switch when current lot reaches zero:
-- if the next open lot has no lot_number yet, assign one before switching to status=current.
-- This avoids violating chk_stock_lot_number_required_for_non_open.

CREATE OR REPLACE FUNCTION fn_auto_switch_lot_when_depleted()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
  v_product_id BIGINT;
  v_open_lot_id BIGINT;
  v_current_net NUMERIC;
  v_event_key TEXT;
BEGIN
  -- only relevant when the updated lot is currently active
  SELECT product_id
  INTO v_product_id
  FROM stock_lot
  WHERE id = NEW.lot_id;

  -- if lot is not current anymore, nothing to do
  IF NOT EXISTS (
    SELECT 1 FROM stock_lot WHERE id = NEW.lot_id AND status = 'current'
  ) THEN
    RETURN NEW;
  END IF;

  SELECT qty_net
  INTO v_current_net
  FROM v_stock_lot_balance
  WHERE stock_lot_id = NEW.lot_id;

  IF COALESCE(v_current_net, 0) > 0 THEN
    RETURN NEW;
  END IF;

  -- lock all lots for this product to avoid race conditions
  PERFORM 1
  FROM stock_lot
  WHERE product_id = v_product_id
  FOR UPDATE;

  -- confirm current lot is still current after lock
  IF NOT EXISTS (
    SELECT 1 FROM stock_lot WHERE id = NEW.lot_id AND status = 'current'
  ) THEN
    RETURN NEW;
  END IF;

  UPDATE stock_lot
  SET status = 'closed', updated_at = NOW()
  WHERE id = NEW.lot_id;

  SELECT id
  INTO v_open_lot_id
  FROM stock_lot
  WHERE product_id = v_product_id
    AND status = 'open'
  ORDER BY id
  LIMIT 1
  FOR UPDATE;

  IF v_open_lot_id IS NULL THEN
    RAISE EXCEPTION 'No open lot available for product % during auto switch', v_product_id;
  END IF;

  -- current/closed lots must have a lot_number due to chk_stock_lot_number_required_for_non_open.
  UPDATE stock_lot
  SET
    status = 'current',
    lot_number = COALESCE(lot_number, format('AUTO-%s-%s', v_product_id, v_open_lot_id)),
    updated_at = NOW()
  WHERE id = v_open_lot_id;

  INSERT INTO stock_lot (product_id, lot_number, status)
  VALUES (v_product_id, NULL, 'open');

  v_event_key := format('lot.auto_switched:%s:%s', v_product_id, txid_current());

  PERFORM fn_enqueue_event(
    'lot.auto_switched',
    v_event_key,
    'stock_lot',
    NEW.lot_id::TEXT,
    jsonb_build_object(
      'productId', v_product_id,
      'closedLotId', NEW.lot_id,
      'newCurrentLotId', v_open_lot_id,
      'occurredAt', NOW()
    )
  );

  RETURN NEW;
END;
$$;

COMMIT;
