# Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/

class ChannelsMicrosoft365Controller < ApplicationController
  prepend_before_action :authenticate_and_authorize!

  def index
    system_online_service = Setting.get('system_online_service')

    assets = {}
    external_credential_ids = []
    ExternalCredential.where(name: 'microsoft365').each do |external_credential|
      assets = external_credential.assets(assets)
      external_credential_ids.push external_credential.id
    end

    channel_ids = []
    Channel.where(area: 'Microsoft365::Account').reorder(:id).each do |channel|
      assets = channel.assets(assets)
      channel_ids.push channel.id
    end

    not_used_email_address_ids = []
    EmailAddress.find_each do |email_address|
      next if system_online_service && email_address.preferences && email_address.preferences['online_service_disable']

      assets = email_address.assets(assets)
      if !email_address.channel_id || !email_address.active || !Channel.exists?(email_address.channel_id)
        not_used_email_address_ids.push email_address.id
      end
    end

    render json: {
      assets:                     assets,
      not_used_email_address_ids: not_used_email_address_ids,
      channel_ids:                channel_ids,
      external_credential_ids:    external_credential_ids,
      callback_url:               ExternalCredential.callback_url('microsoft365'),
    }
  end

  def enable
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')
    channel.active = true
    channel.save!
    render json: {}
  end

  def disable
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')
    channel.active = false
    channel.save!
    render json: {}
  end

  def destroy
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')
    email   = EmailAddress.find_by(channel_id: channel.id)
    email&.destroy!
    channel.destroy!
    render json: {}
  end

  def group
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')
    channel.group_id = params[:group_id]
    channel.save!
    render json: {}
  end

  def inbound
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')

    channel.refresh_xoauth2!(force: true)

    channel.options[:inbound] ||= {}
    channel.options[:inbound][:options] ||= {}

    %w[folder keep_on_server].each do |key|
      next if params.dig(:options, key).nil?

      channel.options[:inbound][:options][key] = params[:options][key]
    end

    result = EmailHelper::Probe.inbound(channel.options[:inbound])
    raise Exceptions::UnprocessableEntity, (result[:message_human] || result[:message]) if result[:result] == 'invalid'

    render json: result
  end

  def verify
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')

    verify_prepare_channel(channel, params)

    channel.save!

    render json: {}
  end

  def rollback_migration
    channel = Channel.find_by(id: params[:id], area: 'Microsoft365::Account')
    raise __('Failed to find backup on channel!') if !channel.options[:backup_imap_classic]

    channel.update!(channel.options[:backup_imap_classic][:attributes])
    render json: {}
  end

  private

  def verify_prepare_channel(channel, params)
    channel.group_id = params[:group_id] if params[:group_id].present?
    channel.active   = params[:active] if params.key?(:active)

    channel.options[:inbound] ||= {}
    channel.options[:inbound][:options] ||= {}

    %w[folder keep_on_server archive archive_before archive_state_id].each do |key|
      next if params.dig(:options, key).nil?

      channel.options[:inbound][:options][key] = params[:options][key]
    end

    channel.status_in    = 'ok'
    channel.status_out   = 'ok'
    channel.last_log_in  = nil
    channel.last_log_out = nil
  end
end