# frozen_string_literal: true

class FormFieldsController < ApplicationController
  include ApplicationHelper
  before_action :check_forms_enabled
  before_action :load_form
  before_action :load_form_field, only: %i(update destroy duplicate)
  before_action :check_manage_permissions, only: %i(create update destroy reorder duplicate)

  def create
    ActiveRecord::Base.transaction do
      @form_field = FormField.new(
        form_field_params.merge(
          {
            form: @form,
            created_by: current_user,
            last_modified_by: current_user,
            position: @form.form_fields.length
          }
        )
      )

      if @form_field.save
        log_activity(:form_block_added, block_name: @form_field.name)
        form_field_annotation
        render json: @form_field, serializer: FormFieldSerializer, user: current_user
      else
        render json: { error: @form_field.errors.full_messages }, status: :unprocessable_entity
      end
    end
  end

  def update
    ActiveRecord::Base.transaction do
      if @form_field.update(form_field_params.merge({ last_modified_by: current_user }))
        form_field_annotation
        log_activity(:form_block_edited, block_name: @form_field.name)
        render json: @form_field, serializer: FormFieldSerializer, user: current_user
      else
        render json: { error: @form_field.errors.full_messages }, status: :unprocessable_entity
      end
    end
  end

  def duplicate
    ActiveRecord::Base.transaction do
      new_form_field = @form_field.duplicate!(current_user)
      log_activity(:form_block_duplicated, block_name: @form_field.name)
      render json: new_form_field, serializer: FormFieldSerializer, user: current_user
    rescue ActiveRecord::RecordInvalid => e
      render json: { error: e.errors.full_messages }, status: :unprocessable_entity
      raise ActiveRecord::Rollback
    rescue StandardError => e
      render json: { message: I18n.t('errors.general') }, status: :unprocessable_entity
      Rails.logger.error e.message
      raise ActiveRecord::Rollback
    end
  end

  def destroy
    ActiveRecord::Base.transaction do
      if @form_field.destroy
        log_activity(:form_block_deleted, block_name: @form_field.name)
        render json: {}
      else
        render json: { error: @form_field.errors.full_messages }, status: :unprocessable_entity
      end
    end
  end

  def reorder
    ActiveRecord::Base.transaction do
      params.permit(form_field_positions: %i(position id))[:form_field_positions].each do |data|
        @form_field = @form.form_fields.find(data[:id])
        @form_field.insert_at!(data[:position].to_i)
      end
      log_activity(:form_block_rearranged)
    end

    render json: params[:form_field_positions], status: :ok
  rescue ActiveRecord::RecordInvalid
    render json: { errors: @form_field.errors }, status: :unprocessable_entity
  end

  private

  def load_form
    @form = Form.find_by(id: params[:form_id])

    render_404 unless @form
  end

  def load_form_field
    @form_field = @form.form_fields.find_by(id: params[:id])

    render_404 unless @form_field
  end

  def check_manage_permissions
    render_403 unless @form && can_manage_form_draft?(@form)
  end

  def form_field_annotation
    smart_annotation_notification(
      old_text: @form_field.description_previously_was,
      new_text: @form_field.description,
      subject: @form,
      title: t('notifications.form_field_title',
               user: current_user.full_name,
               field: @form_field.name,
               form: @form.name)
    )
  end

  def form_field_params
    params.require(:form_field).permit(:name, :description, { data: [:type, :unit, :time, :range, validations: {}, options: []] }, :required, :allow_not_applicable, :uid)
  end

  def check_forms_enabled
    render_404 unless Form.forms_enabled?
  end

  def log_activity(type_of, message_items = {})
    Activities::CreateActivityService
      .call(activity_type: type_of,
            owner: current_user,
            team: @form.team,
            subject: @form,
            message_items: {
              form: @form.id,
              user: current_user.id
            }.merge(message_items))
  end
end
