# frozen_string_literal: true

class CommunicateCdrWhatsappJob < ApplicationJob
  retry_on StandardError, attempts: 4, wait: lambda { |executions|
    executions * 120.seconds
  }

  def perform(article_id)
    article = Ticket::Article.find(article_id)

    # set retry count
    article.preferences['delivery_retry'] ||= 0
    article.preferences['delivery_retry'] += 1

    ticket = Ticket.lookup(id: article.ticket_id)
    unless ticket.preferences
      log_error(article,
                "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})")
    end
    unless ticket.preferences['cdr_whatsapp']
      log_error(article,
                "Can't find ticket.preferences['cdr_whatsapp'] for Ticket.find(#{article.ticket_id})")
    end
    unless ticket.preferences['cdr_whatsapp']['bot_token']
      log_error(article,
                "Can't find ticket.preferences['cdr_whatsapp']['bot_token'] for Ticket.find(#{article.ticket_id})")
    end
    unless ticket.preferences['cdr_whatsapp']['chat_id']
      log_error(article,
                "Can't find ticket.preferences['cdr_whatsapp']['chat_id'] for Ticket.find(#{article.ticket_id})")
    end
    channel = ::CdrSignal.bot_by_bot_token(ticket.preferences['cdr_whatsapp']['bot_token'])
    channel ||= ::Channel.lookup(id: ticket.preferences['channel_id'])
    unless channel
      log_error(article,
                "No such channel for bot #{ticket.preferences['cdr_whatsapp']['bot_token']} or channel id #{ticket.preferences['channel_id']}")
    end
    if channel.options[:bot_token].blank?
      log_error(article,
                "Channel.find(#{channel.id}) has no cdr whatsapp api token!")
    end

    has_error = false

    begin
      result = channel.deliver(
        to: ticket.preferences[:cdr_whatsapp][:chat_id],
        body: article.body
      )
    rescue StandardError => e
      log_error(article, e.message)
      has_error = true
    end

    Rails.logger.debug { "send result: #{result}" }

    if result.nil? || result[:error].present?
      log_error(article, 'Delivering whatsapp message failed!')
      has_error = true
    end

    return if has_error

    article.to = result['result']['to']
    article.from = result['result']['from']

    message_id = format('%<from>s@%<timestamp>s', from: result['result']['from'],
                                                    timestamp: result['result']['timestamp'])
    article.preferences['cdr_whatsapp'] = {
      timestamp: result['result']['timestamp'],
      message_id: message_id,
      from: result['result']['from'],
      to: result['result']['to']
    }

    # set delivery status
    article.preferences['delivery_status_message'] = nil
    article.preferences['delivery_status'] = 'success'
    article.preferences['delivery_status_date'] = Time.zone.now

    article.message_id = "cdr_whatsapp.#{message_id}"

    article.save!

    Rails.logger.info "Sent whatsapp message to: '#{article.to}' (from #{article.from})"

    article
  end

  def log_error(local_record, message)
    local_record.preferences['delivery_status'] = 'fail'
    local_record.preferences['delivery_status_message'] =
      message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
    local_record.preferences['delivery_status_date'] = Time.zone.now
    local_record.save
    Rails.logger.error message

    if local_record.preferences['delivery_retry'] > 3
      Ticket::Article.create(
        ticket_id: local_record.ticket_id,
        content_type: 'text/plain',
        body: "Unable to send cdr whatsapp message: #{message}",
        internal: true,
        sender: Ticket::Article::Sender.find_by(name: 'System'),
        type: Ticket::Article::Type.find_by(name: 'note'),
        preferences: {
          delivery_article_id_related: local_record.id,
          delivery_message: true
        },
        updated_by_id: 1,
        created_by_id: 1
      )
    end

    raise message
  end
end
