class CsatSurveyService
  pattr_initialize [:conversation!]

  def perform
    return unless should_send_csat_survey?

    if whatsapp_channel? && template_available_and_approved?
      send_whatsapp_template_survey
    elsif inbox.twilio_whatsapp? && twilio_template_available_and_approved?
      send_twilio_whatsapp_template_survey
    elsif within_messaging_window?
      ::MessageTemplates::Template::CsatSurvey.new(conversation: conversation).perform
    else
      create_csat_not_sent_activity_message
    end
  end

  private

  delegate :inbox, :contact, to: :conversation

  def should_send_csat_survey?
    conversation_allows_csat? && csat_enabled? && !csat_already_sent? && csat_allowed_by_survey_rules?
  end

  def conversation_allows_csat?
    conversation.resolved? && !conversation.tweet?
  end

  def csat_enabled?
    inbox.csat_survey_enabled?
  end

  def csat_already_sent?
    conversation.messages.where(content_type: :input_csat).present?
  end

  def within_messaging_window?
    conversation.can_reply?
  end

  def csat_allowed_by_survey_rules?
    return true unless survey_rules_configured?

    labels = conversation.label_list
    return true if rule_values.empty?

    case rule_operator
    when 'contains'
      rule_values.any? { |label| labels.include?(label) }
    when 'does_not_contain'
      rule_values.none? { |label| labels.include?(label) }
    else
      true
    end
  end

  def survey_rules_configured?
    return false if csat_config.blank?
    return false if csat_config['survey_rules'].blank?

    rule_values.any?
  end

  def rule_operator
    csat_config.dig('survey_rules', 'operator') || 'contains'
  end

  def rule_values
    csat_config.dig('survey_rules', 'values') || []
  end

  def whatsapp_channel?
    inbox.channel_type == 'Channel::Whatsapp'
  end

  def template_available_and_approved?
    template_config = inbox.csat_config&.dig('template')
    return false unless template_config

    template_name = template_config['name'] || CsatTemplateNameService.csat_template_name(inbox.id)

    status_result = inbox.channel.provider_service.get_template_status(template_name)

    status_result[:success] && status_result[:template][:status] == 'APPROVED'
  rescue StandardError => e
    Rails.logger.error "Error checking CSAT template status: #{e.message}"
    false
  end

  def twilio_template_available_and_approved?
    template_config = inbox.csat_config&.dig('template')
    return false unless template_config

    content_sid = template_config['content_sid']
    return false unless content_sid

    template_service = Twilio::CsatTemplateService.new(inbox.channel)
    status_result = template_service.get_template_status(content_sid)

    status_result[:success] && status_result[:template][:status] == 'approved'
  rescue StandardError => e
    Rails.logger.error "Error checking Twilio CSAT template status: #{e.message}"
    false
  end

  def send_whatsapp_template_survey
    template_config = inbox.csat_config&.dig('template')
    template_name = template_config['name'] || CsatTemplateNameService.csat_template_name(inbox.id)

    phone_number = conversation.contact_inbox.source_id
    template_info = build_template_info(template_name, template_config)
    message = build_csat_message

    message_id = inbox.channel.provider_service.send_template(phone_number, template_info, message)

    message.update!(source_id: message_id) if message_id.present?
  rescue StandardError => e
    Rails.logger.error "Error sending WhatsApp CSAT template for conversation #{conversation.id}: #{e.message}"
  end

  def build_template_info(template_name, template_config)
    {
      name: template_name,
      lang_code: template_config['language'] || 'en',
      parameters: [
        {
          type: 'button',
          sub_type: 'url',
          index: '0',
          parameters: [{ type: 'text', text: conversation.uuid }]
        }
      ]
    }
  end

  def build_csat_message
    conversation.messages.build(
      account: conversation.account,
      inbox: inbox,
      message_type: :outgoing,
      content: inbox.csat_config&.dig('message') || 'Please rate this conversation',
      content_type: :input_csat
    )
  end

  def csat_config
    inbox.csat_config || {}
  end

  def send_twilio_whatsapp_template_survey
    template_config = inbox.csat_config&.dig('template')
    content_sid = template_config['content_sid']

    phone_number = conversation.contact_inbox.source_id
    content_variables = { '1' => conversation.uuid }
    message = build_csat_message

    send_service = Twilio::SendOnTwilioService.new(message: message)
    result = send_service.send_csat_template_message(
      phone_number: phone_number,
      content_sid: content_sid,
      content_variables: content_variables
    )

    message.update!(source_id: result[:message_id]) if result[:success] && result[:message_id].present?
  rescue StandardError => e
    Rails.logger.error "Error sending Twilio WhatsApp CSAT template for conversation #{conversation.id}: #{e.message}"
  end

  def create_csat_not_sent_activity_message
    content = I18n.t('conversations.activity.csat.not_sent_due_to_messaging_window')
    activity_message_params = {
      account_id: conversation.account_id,
      inbox_id: conversation.inbox_id,
      message_type: :activity,
      content: content
    }
    ::Conversations::ActivityMessageJob.perform_later(conversation, activity_message_params) if content
  end
end
