class Google::Config < ApplicationRecord
  audited

  self.table_name = :google_configs

  attr_accessor :token

  belongs_to :school, inverse_of: :google_config
  belongs_to :student_domain, class_name: '::Google::Domain', optional: true
  belongs_to :employee_domain, class_name: '::Google::Domain', optional: true

  delegate :google_domains, to: :school

  validates :email, presence: true, format: /.+@.+\.{1}.{2,}/

  validate :user_is_super_admin, if: :new_record?
  validate :service_account_access, if: :active_changed?
  validate :config_active, if: :active?

  before_create :enable_if_service_account_accessible

  before_save :remove_classroom_module, unless: :active?

  def resfresh_domains
    domains = google_domains.index_by(&:name)
    service = ::Google::Workspace::DetailService.new(self)
    service.domains.each do |domain|
      next if domains.delete(domain[:domainName])

      google_domains.create(name: domain[:domainName], primary: domain[:isPrimary])
    end

    domains.each_value(&:destroy)
  end

  private
    def user_is_super_admin
      return if super_admin?

      errors.add(:email, 'User needs to be a Super Admin.')
    end

    def super_admin?
      response = RestClient.get(
        "https://admin.googleapis.com/admin/directory/v1/users/#{email}",
        Authorization: "Bearer #{token}"
      )
      JSON.parse(response.body)['isAdmin']
    rescue
    end

    def enable_if_service_account_accessible
      service = ::Google::Workspace::DetailService.new(self)
      return false unless service.access_token
      return true if customer_id

      self.customer_id = service.customer_id
      service.domains.each do |domain|
        google_domains.create(name: domain[:domainName], primary: domain[:isPrimary])
      end
    end

    def service_account_access
      return unless active?
      return if enable_if_service_account_accessible

      errors.add(:active, 'Service Account not configuration to Google Workspace.')
    end

    def remove_classroom_module
      modules = school.module_configs
      return if modules.empty?

      modules.update_all(classroom: false)
    end

    def config_active
      return if student_domain || employee_domain

      errors.add(:active, 'at least one domain must be selected in order to enable the integration')
    end
end
