class LnurlpayController < ApplicationController
  before_action :check_service_available
  before_action :find_user

  MIN_SATS = 10
  MAX_SATS = 1_000_000
  MAX_COMMENT_CHARS = 100

  def index
    render json: {
      status: "OK",
      callback: "https://#{Setting.accounts_domain}/lnurlpay/#{@user.cn}/invoice",
      tag: "payRequest",
      maxSendable: MAX_SATS * 1000, # msat
      minSendable: MIN_SATS * 1000, # msat
      metadata: metadata(@user.address),
      commentAllowed: MAX_COMMENT_CHARS
    }
  end

  def keysend
    http_status :not_found and return unless Setting.lndhub_keysend_enabled?

    render json: {
      status: "OK",
      tag: "keysend",
      pubkey: Setting.lndhub_public_key,
      customData: [{
        customKey: "696969",
        customValue: @user.ln_account
      }]
    }
  end

  def invoice
    amount = params[:amount].to_i / 1000 # msats
    comment = params[:comment] || ""
    address = @user.address

    if !valid_amount?(amount)
      render json: { status: "ERROR", reason: "Invalid amount" }
      return
    end

    if !valid_comment?(comment)
      render json: { status: "ERROR", reason: "Comment too long" }
      return
    end

    memo = "To #{address}"
    memo = "#{memo}: \"#{comment}\"" if comment.present?

    payment_request = @user.ln_create_invoice({
      amount: amount, # we create invoices in sats
      memo: memo,
      description_hash: Digest::SHA2.hexdigest(metadata(address)),
    })

    render json: {
      status: "OK",
      successAction: {
        tag: "message",
        message: "Sats received. Thank you!"
      },
      routes: [],
      pr: payment_request
    }
  end

  private

  def find_user
    @user = User.where(cn: params[:username], ou: Setting.primary_domain).first
    http_status :not_found if @user.nil?
  end

  def metadata(address)
    "[[\"text/identifier\", \"#{address}\"], [\"text/plain\", \"Send sats, receive thanks.\"]]"
  end

  def valid_amount?(amount_in_sats)
    amount_in_sats <= MAX_SATS && amount_in_sats >= MIN_SATS
  end

  def valid_comment?(comment)
    comment.length <= MAX_COMMENT_CHARS
  end

  private

  def check_service_available
    http_status :not_found unless Setting.lndhub_enabled?
  end
end
