module CmAdmin::ViewHelpers::FormFieldHelper

def attachment_list(form_obj, cm_field, _value, _required_class, _target_action)

def attachment_list(form_obj, cm_field, _value, _required_class, _target_action)
  attached = form_obj.object.send(cm_field.field_name)
  attachment_name = "#{form_obj.object_name}_#{cm_field.field_name}_attachments"
  return if defined?(::Paperclip) && attached.instance_of?(::Paperclip::Attachment)
  content_tag(:div, data: { section: 'image-preview'}) do
    if attached.class == ActiveStorage::Attached::Many
      attached.each do |attachment|
        concat attachment_with_icon(cm_field, attachment, attachment_name:)
      end
    elsif attached.attached?
      concat attachment_with_icon(cm_field, attached, attachment_name:)
    end
  end
end

def attachment_with_icon(cm_field, attachment, attachment_name:)

def attachment_with_icon(cm_field, attachment, attachment_name:)
  content_tag(:div, data: { section: 'destroy-attachment', ar_id: attachment.id, attachment_name: }) do
    concat(content_tag(:a, href: attachment.url, target: '_blank') do
      if attachment.content_type.include?('image')
        image_tag(attachment.url, height: 50, width: 50, class: "rounded")
      end
    end) if cm_field.image_preview
    concat content_tag(:span, attachment.filename.to_s, class: 'btn-link')
    concat(content_tag(:button, '', class: 'btn-ghost') do
      concat tag.i(class: 'fa-regular fa-trash-can')
    end) if cm_field.input_type == :single_file_upload
  end
end

def cm_check_box_field(form_obj, cm_field, _value, required_class, target_action, _ajax_url)

def cm_check_box_field(form_obj, cm_field, _value, required_class, target_action, _ajax_url)
  content_tag :div, class: 'form-check' do
    concat form_obj.check_box cm_field.field_name,
                              merge_wrapper_options(
                                {
                                  class: "form-check-input #{required_class} #{target_action.present? ? 'linked-field-request' : ''}",
                                  disabled: cm_field.disabled.call(form_obj.object),
                                  data: {
                                    field_name: cm_field.field_name,
                                    target_action: target_action&.name,
                                    target_url: target_action&.name ? cm_admin.send("cm_#{target_action&.name}_#{@model.name.underscore}_path") : ''
                                  }
                                }, cm_field.html_attrs
                              )
    concat content_tag(:div, cm_field.label, class: 'cm-checkbox-label')
  end
end

def cm_checkbox_group_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_checkbox_group_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  original_value = form_obj.object.send(cm_field.field_name)
  content_tag :div do
    concat form_obj.text_field cm_field.field_name, name: "#{@model.name.underscore}[#{cm_field.field_name}][]",
                                                    value: nil, hidden: true
    value.each do |key, val|
      is_checked = original_value.include?(val)
      concat format_check_box(val || key, key, form_obj, cm_field, required_class, is_checked)
    end
  end
end

def cm_custom_date_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_custom_date_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  text_field_tag cm_field.html_attrs[:name] || cm_field.field_name, value&.strftime('%d-%m-%Y'),
                 merge_wrapper_options(
                   {
                     class: "field-control #{required_class}",
                     disabled: cm_field.disabled.call(form_obj.object),
                     value: value&.strftime('%d-%m-%Y'),
                     placeholder: cm_field.placeholder,
                     data: { behaviour: 'date-only' }
                   }, cm_field.html_attrs
                 )
end

def cm_custom_single_select_field(form_obj, cm_field, _value, required_class, target_action, _ajax_url)

def cm_custom_single_select_field(form_obj, cm_field, _value, required_class, target_action, _ajax_url)
  select_tag cm_field.html_attrs[:name] || cm_field.field_name,
             options_for_select(select_collection_value(form_obj.object, cm_field)),
             { include_blank: cm_field.placeholder },
             merge_wrapper_options(
               {
                 class: "field-control #{required_class} select-2",
                 disabled: cm_field.disabled.call(form_obj.object),
                 data: {
                   field_name: cm_field.field_name,
                   field_type: 'linked-field',
                   target_action: target_action&.name,
                   target_url: target_action&.name ? cm_admin.send("cm_#{target_action&.name}_#{@model.name.underscore}_path") : ''
                 }
               }, cm_field.html_attrs
             )
end

def cm_custom_string_field(form_obj, cm_field, value, required_class, _target_action_ajax_url)

def cm_custom_string_field(form_obj, cm_field, value, required_class, _target_action_ajax_url)
  text_field_tag cm_field.html_attrs[:name] || cm_field.field_name,
                 merge_wrapper_options(
                   {
                     value:,
                     class: "field-control #{required_class}",
                     disabled: cm_field.disabled.call(form_obj.object),
                     placeholder: cm_field.placeholder
                   }, cm_field.html_attrs
                 )
end

def cm_date_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_date_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  form_obj.text_field cm_field.field_name,
                      merge_wrapper_options(
                        {
                          class: "field-control #{required_class}",
                          disabled: cm_field.disabled.call(form_obj.object),
                          value: value&.strftime('%d-%m-%Y'),
                          placeholder: cm_field.placeholder,
                          data: { behaviour: 'date-only' }
                        }, cm_field.html_attrs
                      )
end

def cm_date_time_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_date_time_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  form_obj.text_field cm_field.field_name,
                      merge_wrapper_options(
                        {
                          class: "field-control #{required_class}",
                          disabled: cm_field.disabled.call(form_obj.object),
                          value:,
                          placeholder: cm_field.placeholder,
                          data: { behaviour: 'date-time' }
                        }, cm_field.html_attrs
                      )
end

def cm_decimal_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_decimal_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  form_obj.text_field cm_field.field_name,
                      merge_wrapper_options({
                                              class: "field-control #{required_class}",
                                              disabled: cm_field.disabled.call(form_obj.object),
                                              value:,
                                              placeholder: cm_field.placeholder,
                                              data: { behaviour: 'decimal-only' }
                                            }, cm_field.html_attrs)
end

def cm_hidden_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)

def cm_hidden_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)
  form_obj.hidden_field cm_field.field_name,
                        merge_wrapper_options(
                          {
                            value:,
                            name: cm_field.html_attrs[:name] || "#{form_obj.object_name}[#{cm_field.field_name}]"
                          }, cm_field.html_attrs
                        )
end

def cm_integer_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_integer_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  form_obj.text_field cm_field.field_name,
                      merge_wrapper_options(
                        {
                          class: "field-control #{required_class}",
                          disabled: cm_field.disabled.call(form_obj.object),
                          value:,
                          placeholder: cm_field.placeholder,
                          data: { behaviour: 'integer-only' }
                        }, cm_field.html_attrs
                      )
end

def cm_multi_file_upload_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)

def cm_multi_file_upload_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)
  content_tag(:div, data: { 'field-type': 'multi_file_upload' }) do
    concat attachment_list(form_obj, cm_field, _value, required_class, _target_action)
    concat form_obj.file_field cm_field.field_name,
                               merge_wrapper_options(
                                 {
                                   multiple: true, class: "field-control #{required_class}}",
                                   disabled: cm_field.disabled.call(form_obj.object)
                                 }, cm_field.html_attrs
                               )
  end
end

def cm_multi_select_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)

def cm_multi_select_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)
  form_obj.select cm_field.field_name,
                  options_for_select(select_collection_value(form_obj.object, cm_field), form_obj.object.send(cm_field.field_name)),
                  { include_blank: cm_field.placeholder },
                  merge_wrapper_options(
                    {
                      class: "field-control #{required_class} select-2",
                      disabled: cm_field.disabled.call(form_obj.object), multiple: true
                    }, cm_field.html_attrs
                  )
end

def cm_radio_button_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)

def cm_radio_button_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)
  content_tag :div do
    value.each do |key, val|
      concat format_radio_option(val || key, key, cm_field, form_obj)
    end
  end
end

def cm_radio_button_group_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)

def cm_radio_button_group_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)
  content_tag :div, class: 'btn-group', role: 'group' do
    value.each do |key, val|
      format_radio_button_group_option(val || key, key, cm_field, form_obj)
    end
  end
end

def cm_rich_text_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)

def cm_rich_text_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)
  form_obj.rich_text_area cm_field.field_name,
                          merge_wrapper_options(
                            {
                              class: "field-control #{required_class}",
                              placeholder: cm_field.placeholder
                            }, cm_field.html_attrs
                          )
end

def cm_single_file_upload_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)

def cm_single_file_upload_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)
  content_tag(:div, data: { 'field-type': 'single_file_upload' }) do
    concat attachment_list(form_obj, cm_field, _value, required_class, _target_action)
    concat form_obj.file_field cm_field.field_name,
                               merge_wrapper_options(
                                 {
                                   class: "field-control #{required_class} #{form_obj.object.send(cm_field.field_name).attached? ? 'hidden' : ''}",
                                   disabled: cm_field.disabled.call(form_obj.object)
                                 }, cm_field.html_attrs
                               )
  end
end

def cm_single_select_field(form_obj, cm_field, _value, required_class, target_action, ajax_url)

def cm_single_select_field(form_obj, cm_field, _value, required_class, target_action, ajax_url)
  class_name = ajax_url.present? ? 'select-2-ajax' : 'select-2'
  form_obj.select cm_field.field_name, options_for_select(select_collection_value(form_obj.object, cm_field), form_obj.object.send(cm_field.field_name)),
                  { include_blank: cm_field.placeholder },
                  merge_wrapper_options(
                    {
                      class: "field-control #{required_class} #{class_name}",
                      disabled: cm_field.disabled.call(form_obj.object),
                      data: {
                        field_name: cm_field.field_name,
                        field_type: 'linked-field',
                        target_action: target_action&.name,
                        target_url: target_action&.name ? cm_admin.send("cm_#{target_action&.name}_#{@model.name.underscore}_path") : '',
                        ajax_url:
                      }
                    }, cm_field.html_attrs
                  )
end

def cm_string_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)

def cm_string_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)
  form_obj.text_field cm_field.field_name,
                      merge_wrapper_options(
                        {
                          class: "field-control #{required_class}",
                          disabled: cm_field.disabled.call(form_obj.object),
                          value:,
                          placeholder: cm_field.placeholder
                        }, cm_field.html_attrs
                      )
end

def cm_switch_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)\

def cm_switch_field(form_obj, cm_field, value, required_class, _target_action, _ajax_url)\
  content_tag :div, class: 'form-check form-switch' do
    concat form_obj.check_box cm_field.field_name,
                              merge_wrapper_options(
                                {
                                  class: "field-control form-check-input #{required_class}",
                                  disabled: cm_field.disabled.call(form_obj.object),
                                  value:,
                                  role: 'switch'
                                }, cm_field.html_attrs
                              )
    concat content_tag(:div, cm_field.label, class: 'cm-switch-label')
  end
end

def cm_text_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)

def cm_text_field(form_obj, cm_field, _value, required_class, _target_action, _ajax_url)
  form_obj.text_area cm_field.field_name,
                     merge_wrapper_options(
                       {
                         class: "field-control #{required_class}",
                         placeholder: cm_field.placeholder
                       }, cm_field.html_attrs
                     )
end

def format_check_box(val, key, form_obj, cm_field, required_class, is_checked)

def format_check_box(val, key, form_obj, cm_field, required_class, is_checked)
  content_tag :div, class: 'form-check' do
    concat check_box_tag "#{@model.name.underscore}[#{cm_field.field_name}][]", val, is_checked,
                         merge_wrapper_options(
                           {
                             class: "form-check-input #{required_class}",
                             disabled: cm_field.disabled.call(form_obj.object)
                           }, cm_field.html_attrs
                         )
    concat content_tag(:div, key, class: 'cm-checkbox-label')
  end
end

def format_radio_button_group_option(val, key, cm_field, form_obj)

def format_radio_button_group_option(val, key, cm_field, form_obj)
  id = "#{cm_field.field_name}_#{val}"
  concat form_obj.radio_button cm_field.field_name, val, merge_wrapper_options({ id:, class: 'btn-check' },
                                                                               cm_field.html_attrs)
  concat content_tag(:label, key, class: 'btn btn-outline-dark btn-sm', for: id)
end

def format_radio_option(val, key, cm_field, form_obj)

def format_radio_option(val, key, cm_field, form_obj)
  content_tag :div, class: 'form-check' do
    concat form_obj.radio_button cm_field.field_name, val, merge_wrapper_options({ class: 'form-check-input' }, cm_field.html_attrs)
    concat content_tag(:div, key, class: 'form-check-label')
  end
end

def input_field_for_column(form_obj, cm_field, is_required: nil)

def input_field_for_column(form_obj, cm_field, is_required: nil)
  return unless cm_field.display_if.call(form_obj.object)
  value = if cm_field.helper_method
            send(cm_field.helper_method, form_obj.object, cm_field.field_name)
          elsif cm_field.input_type.to_s.include?('custom')
            nil
          else
            form_obj.object.send(cm_field.field_name)
          end
  is_required = is_field_presence_validated?(form_obj, cm_field) if is_required.nil?
  required_class = is_required ? 'required' : ''
  target_action = @model.available_actions.select { |x| x.name == cm_field.target[:action_name].to_s }.first if cm_field.target.present?
  send("cm_#{cm_field.input_type}_field", form_obj, cm_field, value, required_class, target_action, cm_field.ajax_url)
end

def merge_wrapper_options(options, html_attrs)

def merge_wrapper_options(options, html_attrs)
  if html_attrs
    options.merge(html_attrs) do |key, oldval, newval|
      case key.to_s
      when 'class'
        oldval + ' ' + newval
      when 'data', 'aria'
        oldval.merge(newval)
      else
        newval
      end
    end
  else
    options
  end
end

def select_collection_value(object, cm_field)

helper_method argument will accept a method where value can be passed.
Refactor: Collection argument can be removed.
def select_collection_value(object, cm_field)
  if cm_field.helper_method
    send(cm_field.helper_method, object, cm_field.field_name)
  elsif cm_field.collection
    cm_field.collection
  else
    []
  end
end