-- ============================================================================
-- Schema: trading
-- Function: calculate_position_pnl
-- Description: Calcula el PnL (realized y unrealized) de una posición
-- Parameters:
--   p_position_id: ID de la posición
--   p_current_price: Precio actual del mercado (para unrealized PnL)
-- Returns: JSONB con realized_pnl, unrealized_pnl, pnl_percentage
-- ============================================================================

CREATE OR REPLACE FUNCTION trading.calculate_position_pnl(
  p_position_id UUID,
  p_current_price DECIMAL(20,8) DEFAULT NULL
)
RETURNS JSONB
LANGUAGE plpgsql
AS $$
DECLARE
  v_position RECORD;
  v_realized_pnl DECIMAL(20,8) := 0;
  v_unrealized_pnl DECIMAL(20,8) := 0;
  v_pnl_percentage DECIMAL(10,4) := 0;
  v_total_commission DECIMAL(20,8) := 0;
  v_current_value DECIMAL(20,8);
BEGIN
  -- Obtener datos de la posición
  SELECT
    p.position_side,
    p.status,
    p.entry_price,
    p.entry_quantity,
    p.entry_value,
    p.entry_commission,
    p.exit_price,
    p.exit_quantity,
    p.exit_value,
    p.exit_commission
  INTO v_position
  FROM trading.positions p
  WHERE p.id = p_position_id;

  IF NOT FOUND THEN
    RAISE EXCEPTION 'Position % not found', p_position_id;
  END IF;

  -- Calcular comisiones totales
  v_total_commission := COALESCE(v_position.entry_commission, 0) + COALESCE(v_position.exit_commission, 0);

  -- Calcular PnL según el estado
  IF v_position.status = 'closed' OR v_position.status = 'liquidated' THEN
    -- Posición cerrada: calcular realized PnL
    IF v_position.position_side = 'buy' THEN
      -- Long position: profit = (exit_price - entry_price) * quantity - commissions
      v_realized_pnl := (v_position.exit_value - v_position.entry_value) - v_total_commission;
    ELSE
      -- Short position: profit = (entry_price - exit_price) * quantity - commissions
      v_realized_pnl := (v_position.entry_value - v_position.exit_value) - v_total_commission;
    END IF;

    -- Calcular porcentaje
    IF v_position.entry_value > 0 THEN
      v_pnl_percentage := (v_realized_pnl / v_position.entry_value) * 100;
    END IF;

  ELSIF v_position.status = 'open' AND p_current_price IS NOT NULL THEN
    -- Posición abierta: calcular unrealized PnL
    v_current_value := p_current_price * v_position.entry_quantity;

    IF v_position.position_side = 'buy' THEN
      -- Long position
      v_unrealized_pnl := (v_current_value - v_position.entry_value) - v_position.entry_commission;
    ELSE
      -- Short position
      v_unrealized_pnl := (v_position.entry_value - v_current_value) - v_position.entry_commission;
    END IF;

    -- Calcular porcentaje
    IF v_position.entry_value > 0 THEN
      v_pnl_percentage := (v_unrealized_pnl / v_position.entry_value) * 100;
    END IF;
  END IF;

  -- Retornar resultado
  RETURN jsonb_build_object(
    'position_id', p_position_id,
    'status', v_position.status,
    'realized_pnl', v_realized_pnl,
    'unrealized_pnl', v_unrealized_pnl,
    'pnl_percentage', v_pnl_percentage,
    'total_commission', v_total_commission
  );
END;
$$;

-- Comentarios
COMMENT ON FUNCTION trading.calculate_position_pnl IS 'Calcula el PnL realizado y no realizado de una posición';
