module Enterprise::MessageTemplates::HookExecutionService
  MAX_ATTACHMENT_WAIT_SECONDS = 4

  def trigger_templates
    super
    return unless should_process_captain_response?
    return perform_handoff unless inbox.captain_active?

    schedule_captain_response
  end

  def should_send_greeting?
    return false if captain_handling_conversation?

    super
  end

  def should_send_out_of_office_message?
    return false if captain_handling_conversation?

    super
  end

  def should_send_email_collect?
    return false if captain_handling_conversation?

    super
  end

  private

  def schedule_captain_response
    job_args = [conversation, conversation.inbox.captain_assistant]

    if message.attachments.blank?
      Captain::Conversation::ResponseBuilderJob.perform_later(*job_args)
    else
      wait_time = calculate_attachment_wait_time
      Captain::Conversation::ResponseBuilderJob.set(wait: wait_time).perform_later(*job_args)
    end
  end

  def calculate_attachment_wait_time
    attachment_count = message.attachments.size
    base_wait = 1.second

    # Wait longer for more attachments or larger files
    additional_wait = [attachment_count * 1, MAX_ATTACHMENT_WAIT_SECONDS].min.seconds
    base_wait + additional_wait
  end

  def should_process_captain_response?
    # Regra do Usuário: "Não responder APENAS se estiver atribuído E tiver a etiqueta"
    # Assim, se estiver apenas atribuído (sem etiqueta), ele ainda responde.
    # Se tiver apenas a etiqueta (sem atribuição), ele ainda responde (a menos que a etiqueta signifique desligar total).

    is_assigned_to_human = conversation.assignee.present? && !conversation.assignee.is_a?(AgentBot)
    has_disable_label = conversation.labels.pluck(:name).include?('desligar_ia') || conversation.contact.labels.pluck(:name).include?('desligar_ia')

    # Para segurança, vamos manter que se tiver a etiqueta, o humano assume total controle.
    # Mas seguindo a regra literal pedida:
    return false if is_assigned_to_human || has_disable_label

    # Se estiver atribuído a um humano, geralmente não queremos que a IA interfira A MENOS que o usuário queira.
    # Como o usuário disse "responda igual no playground", vou permitir enquanto não houver o combo (Assigned + Label).

    message.incoming? && inbox.captain_assistant.present?
  end

  def perform_handoff
    return unless conversation.pending?

    Rails.logger.info("Captain limit exceeded, performing handoff mid-conversation for conversation: #{conversation.id}")
    conversation.messages.create!(
      message_type: :outgoing,
      account_id: conversation.account.id,
      inbox_id: conversation.inbox.id,
      content: 'Transferring to another agent for further assistance.'
    )
    conversation.bot_handoff!
    send_out_of_office_message_after_handoff
  end

  def send_out_of_office_message_after_handoff
    ::MessageTemplates::Template::OutOfOffice.perform_if_applicable(conversation)
  end

  def captain_handling_conversation?
    conversation.pending? && inbox.respond_to?(:captain_assistant) && inbox.captain_assistant.present?
  end
end
