# frozen_string_literal: true

require 'csv'

module Effective
  class DatatablesController < ApplicationController
    skip_log_page_views quiet: true if defined?(EffectiveLogging)

    # This will respond to both a GET and a POST
    def show
      begin
        @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
        @datatable.view = view_context

        EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)

        render json: @datatable.to_json
      rescue Exception => e
        EffectiveDatatables.authorized?(self, :index, @datatable.try(:collection_class))
        render json: error_json(e)

        ExceptionNotifier.notify_exception(e) if defined?(ExceptionNotifier)
        raise e if Rails.env.development?
      end
    end

    def download
      @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
      @datatable.view = view_context

      EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)

      respond_to do |format|
        format.csv do
          headers.delete('Content-Length')

          headers['X-Accel-Buffering'] = 'no'
          headers['Cache-Control'] = 'no-cache'
          headers["Content-Type"] = @datatable.csv_content_type
          headers["Content-Disposition"] = %(attachment; filename="#{@datatable.csv_filename}")
          headers['Last-Modified'] = Time.zone.now.ctime.to_s

          self.response_body = @datatable.csv_stream
          response.status = 200
        end

        # format.csv do
        #   send_data(@datatable.csv_file, filename: @datatable.csv_filename, type: @datatable.csv_content_type, disposition: 'attachment')
        # end

        format.all do
          render(status: :unauthorized, body: 'Access Denied')
        end
      end
    end

    def reorder
      begin
        @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
        @datatable.view = view_context

        EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)

        @resource = @datatable.collection.find(params[:reorder][:id])

        EffectiveDatatables.authorize!(self, :update, @resource)

        attribute = @datatable.columns[:_reorder][:reorder]
        old_index = params[:reorder][:old].to_i
        new_index = params[:reorder][:new].to_i

        @resource.class.transaction do
          if new_index > old_index
            @datatable.collection.where("#{attribute} > ? AND #{attribute} <= ?", old_index, new_index).update_all("#{attribute} = #{attribute} - 1")
            @resource.update_column(attribute, new_index)
            @resource.touch
          end

          if old_index > new_index
            @datatable.collection.where("#{attribute} >= ? AND #{attribute} < ?", new_index, old_index).update_all("#{attribute} = #{attribute} + 1")
            @resource.update_column(attribute, new_index)
            @resource.touch
          end
        end

        render status: :ok, body: :ok
      rescue Effective::AccessDenied => e
        render(status: :unauthorized, body: 'Access Denied')
      rescue Exception => e
        render(status: :error, body: 'Unexpected Error')
      end

    end

    private

    def error_json(e)
      {
        data: [],
        draw: params[:draw].to_i,
        effective_datatables_error: (e.message.presence unless e.class.name.include?('ActiveRecord::')) || 'unexpected operation',
        recordsTotal: 0,
        recordsFiltered: 0,
        aggregates: [],
        charts: {}
      }
    end

  end
end
