# frozen_string_literal: true

class DsnsController < ApplicationController
  before_action :require_authentication
  before_action :set_dsn, only: [:show, :edit, :update, :disable, :enable]
  before_action :authorize_dsn_management, except: [:index, :show]

  # GET /dsns
  def index
    @dsns = policy_scope(Dsn).order(created_at: :desc)

    # Generate environment DSNs using default DSN key or first enabled DSN
    default_dsn = Dsn.enabled.first
    if default_dsn
      @external_dsn = generate_external_dsn(default_dsn.key)
      @internal_dsn = generate_internal_dsn(default_dsn.key)
    end
  end

  # GET /dsns/new
  def new
    authorize Dsn
    @dsn = Dsn.new
  end

  # POST /dsns
  def create
    authorize Dsn
    @dsn = Dsn.new(dsn_params)

    if @dsn.save
      redirect_to @dsn, notice: 'DSN was successfully created.'
    else
      render :new, status: :unprocessable_entity
    end
  end

  # GET /dsns/:id
  def show
  end

  # GET /dsns/:id/edit
  def edit
  end

  # PATCH/PUT /dsns/:id
  def update
    if @dsn.update(dsn_params)
      redirect_to @dsn, notice: 'DSN was successfully updated.'
    else
      render :edit, status: :unprocessable_entity
    end
  end

  # POST /dsns/:id/disable
  def disable
    @dsn.update!(enabled: false)
    redirect_to @dsn, notice: 'DSN was disabled.'
  end

  # POST /dsns/:id/enable
  def enable
    @dsn.update!(enabled: true)
    redirect_to @dsn, notice: 'DSN was enabled.'
  end

  private

  def set_dsn
    @dsn = Dsn.find(params[:id])
  end

  def dsn_params
    params.require(:dsn).permit(:name, :enabled)
  end

  def authorize_dsn_management
    # Only allow admins to manage DSNs
    redirect_to root_path, alert: 'Access denied' unless Current.user&.admin?
  end

  def generate_external_dsn(key)
    host = ENV.fetch("BAFFLE_HOST", "localhost:3000")
    protocol = host.include?("localhost") ? "http" : "https"
    "#{protocol}://#{key}@#{host}"
  end

  def generate_internal_dsn(key)
    internal_host = ENV.fetch("BAFFLE_INTERNAL_HOST", nil)
    return nil unless internal_host.present?

    protocol = "http"  # Internal connections use HTTP
    "#{protocol}://#{key}@#{internal_host}"
  end
end