-- Add fee payment model options to organizations table
-- This determines whether customers pay the platform fee on top of the ticket price
-- or if the fee is absorbed into the ticket price

ALTER TABLE organizations 
ADD COLUMN platform_fee_model VARCHAR(20) DEFAULT 'customer_pays',
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;

-- Update fee_structures table to include the fee model
ALTER TABLE fee_structures
ADD COLUMN fee_model VARCHAR(20) DEFAULT 'customer_pays',
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;

-- Add comments for clarity
COMMENT ON COLUMN organizations.platform_fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
COMMENT ON COLUMN organizations.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';
COMMENT ON COLUMN fee_structures.fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
COMMENT ON COLUMN fee_structures.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';

-- Update existing organizations with default fee model and actual BCT rates
UPDATE organizations 
SET 
  platform_fee_model = 'customer_pays',
  absorb_fee_in_price = false,
  platform_fee_percentage = 0.025, -- 2.5% BCT platform fee
  platform_fee_fixed = 150 -- $1.50 BCT platform fee
WHERE platform_fee_model IS NULL;

-- Update existing fee structure templates with actual rates
UPDATE fee_structures
SET 
  fee_model = 'customer_pays',
  absorb_fee_in_price = false
WHERE fee_model IS NULL;

-- Update the default template to reflect actual BCT rates
UPDATE fee_structures 
SET 
  fee_percentage = 0.025,
  fee_fixed = 150,
  description = 'BCT platform fee: 2.5% + $1.50 per transaction'
WHERE name = 'Standard Platform Fee' AND is_template = true;

-- Add new fee structure templates with absorbed fee model and correct BCT rates
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
('All-Inclusive BCT Standard', 'BCT platform fee 2.5% + $1.50 included in ticket price', 'percentage_plus_fixed', 0.025, 150, 'absorbed_in_price', true, true),
('All-Inclusive Percentage Only', '2.5% fee included in ticket price', 'percentage', 0.025, 0, 'absorbed_in_price', true, true),
('All-Inclusive Fixed Only', '$1.50 fee included in ticket price', 'fixed', 0.0000, 150, 'absorbed_in_price', true, true),
('Premium All-Inclusive', 'Premium 3% + $2.00 fee included in ticket price', 'percentage_plus_fixed', 0.030, 200, 'absorbed_in_price', true, true);

-- Add template for Stripe fee structure (for reference/calculation)
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
('Stripe Processing Fee', 'Stripe credit card processing: 2.99% + $0.30', 'percentage_plus_fixed', 0.0299, 30, 'customer_pays', false, true);

-- Add function to calculate the display price based on fee model
CREATE OR REPLACE FUNCTION calculate_display_price(
  base_price DECIMAL,
  fee_percentage DECIMAL DEFAULT 0.03,
  fee_fixed INTEGER DEFAULT 30,
  fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
  fee_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
  platform_fee DECIMAL;
  display_price DECIMAL;
BEGIN
  -- Calculate platform fee based on fee type
  CASE fee_type
    WHEN 'percentage' THEN
      platform_fee := base_price * fee_percentage;
    WHEN 'fixed' THEN
      platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
    WHEN 'percentage_plus_fixed' THEN
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
    ELSE
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
  END CASE;

  -- Calculate display price based on fee model
  CASE fee_model
    WHEN 'customer_pays' THEN
      -- Customer pays base price + platform fee
      display_price := base_price;
    WHEN 'absorbed_in_price' THEN
      -- Platform fee is absorbed into the display price
      -- To maintain the same net revenue for organizer,
      -- we need to increase the display price to cover the fee
      display_price := base_price + platform_fee;
    ELSE
      display_price := base_price;
  END CASE;

  RETURN ROUND(display_price, 2);
END;
$$ LANGUAGE plpgsql;

-- Add function to calculate the total amount customer pays
CREATE OR REPLACE FUNCTION calculate_customer_total(
  base_price DECIMAL,
  fee_percentage DECIMAL DEFAULT 0.03,
  fee_fixed INTEGER DEFAULT 30,
  fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
  fee_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
  platform_fee DECIMAL;
  customer_total DECIMAL;
BEGIN
  -- Calculate platform fee based on fee type
  CASE fee_type
    WHEN 'percentage' THEN
      platform_fee := base_price * fee_percentage;
    WHEN 'fixed' THEN
      platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
    WHEN 'percentage_plus_fixed' THEN
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
    ELSE
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
  END CASE;

  -- Calculate total amount customer pays
  CASE fee_model
    WHEN 'customer_pays' THEN
      -- Customer pays base price + platform fee separately
      customer_total := base_price + platform_fee;
    WHEN 'absorbed_in_price' THEN
      -- Customer pays only the display price (fee is included)
      customer_total := base_price;
    ELSE
      customer_total := base_price + platform_fee;
  END CASE;

  RETURN ROUND(customer_total, 2);
END;
$$ LANGUAGE plpgsql;

-- Add function to calculate organizer net with fee model
CREATE OR REPLACE FUNCTION calculate_organizer_net(
  base_price DECIMAL,
  fee_percentage DECIMAL DEFAULT 0.03,
  fee_fixed INTEGER DEFAULT 30,
  fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
  fee_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
  platform_fee DECIMAL;
  organizer_net DECIMAL;
BEGIN
  -- Calculate platform fee based on fee type
  CASE fee_type
    WHEN 'percentage' THEN
      platform_fee := base_price * fee_percentage;
    WHEN 'fixed' THEN
      platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
    WHEN 'percentage_plus_fixed' THEN
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
    ELSE
      platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
  END CASE;

  -- Calculate organizer net (what they receive)
  organizer_net := base_price - platform_fee;

  -- Ensure organizer net is never negative
  IF organizer_net < 0 THEN
    organizer_net := 0;
  END IF;

  RETURN ROUND(organizer_net, 2);
END;
$$ LANGUAGE plpgsql;

-- Add indexes for performance
CREATE INDEX idx_organizations_platform_fee_model ON organizations(platform_fee_model);
CREATE INDEX idx_fee_structures_fee_model ON fee_structures(fee_model);

-- Add check constraints to ensure valid fee models
ALTER TABLE organizations 
ADD CONSTRAINT check_platform_fee_model 
CHECK (platform_fee_model IN ('customer_pays', 'absorbed_in_price'));

ALTER TABLE fee_structures
ADD CONSTRAINT check_fee_model 
CHECK (fee_model IN ('customer_pays', 'absorbed_in_price'));