-- Standardize BCT platform fees across all organizations
-- Organizations can only customize HOW fees are applied, not the fee amounts

-- Remove fee amount columns from organizations table since fees are now standard
-- Keep only the fee application model (how fees are presented to customers)
ALTER TABLE organizations 
DROP COLUMN IF EXISTS platform_fee_type,
DROP COLUMN IF EXISTS platform_fee_percentage, 
DROP COLUMN IF EXISTS platform_fee_fixed;

-- Rename fee model column for clarity
ALTER TABLE organizations 
RENAME COLUMN platform_fee_model TO fee_display_model;

-- Add comment for clarity
COMMENT ON COLUMN organizations.fee_display_model IS 'How fees are displayed to customers: customer_pays (separate line) or absorbed_in_price (included)';
COMMENT ON COLUMN organizations.absorb_fee_in_price IS 'Whether to include BCT fee in displayed ticket price (true) or show separately (false)';

-- Create platform_settings table for system-wide configuration
CREATE TABLE platform_settings (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  setting_key TEXT UNIQUE NOT NULL,
  setting_value JSONB NOT NULL,
  description TEXT,
  is_public BOOLEAN DEFAULT false, -- Whether this setting can be viewed by organizers
  updated_by UUID REFERENCES users(id),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Insert standard BCT fee structure
INSERT INTO platform_settings (setting_key, setting_value, description, is_public) VALUES
('bct_platform_fee_percentage', '0.025', 'BCT platform fee percentage (2.5%)', true),
('bct_platform_fee_fixed', '150', 'BCT platform fee fixed amount in cents ($1.50)', true),
('stripe_fee_percentage', '0.0299', 'Stripe processing fee percentage (2.99%)', true),
('stripe_fee_fixed', '30', 'Stripe processing fee fixed amount in cents ($0.30)', true),
('platform_name', '"Black Canyon Tickets"', 'Platform display name', true),
('platform_email', '"support@blackcanyontickets.com"', 'Platform support email', true),
('max_events_per_organization', '100', 'Maximum events per organization', false);

-- Update all existing organizations to use standard fee display model
UPDATE organizations 
SET 
  fee_display_model = COALESCE(fee_display_model, 'customer_pays'),
  absorb_fee_in_price = COALESCE(absorb_fee_in_price, false);

-- Set default fee display model for new organizations
ALTER TABLE organizations 
ALTER COLUMN fee_display_model SET DEFAULT 'customer_pays',
ALTER COLUMN absorb_fee_in_price SET DEFAULT false;

-- Create function to get current BCT platform fees
CREATE OR REPLACE FUNCTION get_bct_platform_fees()
RETURNS TABLE(
  fee_percentage DECIMAL,
  fee_fixed INTEGER
) AS $$
BEGIN
  RETURN QUERY
  SELECT 
    (SELECT (setting_value#>>'{}')::DECIMAL FROM platform_settings WHERE setting_key = 'bct_platform_fee_percentage'),
    (SELECT (setting_value#>>'{}')::INTEGER FROM platform_settings WHERE setting_key = 'bct_platform_fee_fixed');
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Create function to get current Stripe fees
CREATE OR REPLACE FUNCTION get_stripe_fees()
RETURNS TABLE(
  fee_percentage DECIMAL,
  fee_fixed INTEGER
) AS $$
BEGIN
  RETURN QUERY
  SELECT 
    (SELECT (setting_value#>>'{}')::DECIMAL FROM platform_settings WHERE setting_key = 'stripe_fee_percentage'),
    (SELECT (setting_value#>>'{}')::INTEGER FROM platform_settings WHERE setting_key = 'stripe_fee_fixed');
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Update the display price calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_display_price_standard(
  base_price DECIMAL,
  fee_display_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
  bct_fee_percentage DECIMAL;
  bct_fee_fixed INTEGER;
  platform_fee DECIMAL;
  display_price DECIMAL;
BEGIN
  -- Get current BCT platform fees
  SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
  FROM get_bct_platform_fees();

  -- Calculate BCT platform fee
  platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);

  -- Calculate display price based on fee model
  CASE fee_display_model
    WHEN 'customer_pays' THEN
      -- Customer pays base price + platform fee separately
      display_price := base_price;
    WHEN 'absorbed_in_price' THEN
      -- Platform fee is absorbed into the display price
      display_price := base_price + platform_fee;
    ELSE
      display_price := base_price;
  END CASE;

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

-- Update the customer total calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_customer_total_standard(
  base_price DECIMAL,
  fee_display_model VARCHAR DEFAULT 'customer_pays'
) RETURNS DECIMAL AS $$
DECLARE
  bct_fee_percentage DECIMAL;
  bct_fee_fixed INTEGER;
  platform_fee DECIMAL;
  customer_total DECIMAL;
BEGIN
  -- Get current BCT platform fees
  SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
  FROM get_bct_platform_fees();

  -- Calculate BCT platform fee
  platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);

  -- Calculate total amount customer pays
  CASE fee_display_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;

-- Update the organizer net calculation function to use standard fees
CREATE OR REPLACE FUNCTION calculate_organizer_net_standard(
  base_price DECIMAL
) RETURNS DECIMAL AS $$
DECLARE
  bct_fee_percentage DECIMAL;
  bct_fee_fixed INTEGER;
  platform_fee DECIMAL;
  organizer_net DECIMAL;
BEGIN
  -- Get current BCT platform fees
  SELECT fee_percentage, fee_fixed INTO bct_fee_percentage, bct_fee_fixed
  FROM get_bct_platform_fees();

  -- Calculate BCT platform fee
  platform_fee := (base_price * bct_fee_percentage) + (bct_fee_fixed / 100.0);

  -- Calculate organizer net (what they receive before Stripe fees)
  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;

-- Enable RLS on platform_settings
ALTER TABLE platform_settings ENABLE ROW LEVEL SECURITY;

-- Public settings can be viewed by authenticated users
CREATE POLICY "Authenticated users can view public platform settings" ON platform_settings
  FOR SELECT USING (is_public = true AND auth.role() = 'authenticated');

-- Only admins can manage platform settings
CREATE POLICY "Admins can manage platform settings" ON platform_settings
  FOR ALL USING (auth.uid() IN (SELECT id FROM users WHERE role = 'admin'));

-- Add indexes for performance
CREATE INDEX idx_platform_settings_key ON platform_settings(setting_key);
CREATE INDEX idx_platform_settings_public ON platform_settings(is_public);
CREATE INDEX idx_organizations_fee_display_model ON organizations(fee_display_model);

-- Add check constraint to ensure valid fee display models
ALTER TABLE organizations 
DROP CONSTRAINT IF EXISTS check_platform_fee_model,
ADD CONSTRAINT check_fee_display_model 
CHECK (fee_display_model IN ('customer_pays', 'absorbed_in_price'));

-- Update fee_structures table to remove custom fee amounts (since fees are now standard)
-- Keep only for reference and templates
ALTER TABLE fee_structures
ADD COLUMN is_deprecated BOOLEAN DEFAULT false;

-- Mark old custom fee structures as deprecated
UPDATE fee_structures 
SET is_deprecated = true 
WHERE is_template = false;

-- Clean up old fee structure templates and add new standard ones
DELETE FROM fee_structures WHERE is_template = true;

INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
('BCT Standard - Customer Pays', 'Customer pays BCT fee (2.5% + $1.50) as separate line item', 'percentage_plus_fixed', 0.025, 150, 'customer_pays', false, true),
('BCT Standard - All Inclusive', 'BCT fee (2.5% + $1.50) included in ticket price', 'percentage_plus_fixed', 0.025, 150, 'absorbed_in_price', true, true),
('Stripe Processing Fee', 'Stripe credit card processing: 2.99% + $0.30', 'percentage_plus_fixed', 0.0299, 30, 'customer_pays', false, true);

-- Add audit logging for platform settings changes
CREATE OR REPLACE FUNCTION log_platform_settings_change()
RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'UPDATE' THEN
    INSERT INTO audit_logs (user_id, action, resource_type, resource_id, old_values, new_values)
    VALUES (
      auth.uid(),
      'update',
      'platform_settings',
      NEW.id,
      row_to_json(OLD),
      row_to_json(NEW)
    );
  ELSIF TG_OP = 'INSERT' THEN
    INSERT INTO audit_logs (user_id, action, resource_type, resource_id, new_values)
    VALUES (
      auth.uid(),
      'create',
      'platform_settings',
      NEW.id,
      row_to_json(NEW)
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER platform_settings_audit_trigger
  AFTER INSERT OR UPDATE ON platform_settings
  FOR EACH ROW EXECUTE FUNCTION log_platform_settings_change();