module EasyPatch
  module CustomFieldValuePatch

    def self.included(base)
      base.send(:include, InstanceMethods)

      base.class_eval do

        alias_method_chain :visible?, :easy_extensions

        def cast_value(cf = nil)
          cf ||= self.custom_field
          cf.cast_value(self.value)
        end

        def validate_value_with_custom_field_value
          if self.custom_field.field_format == 'autoincrement' && !self.autoincrement_number_valid?
            self.customized.errors.add(:base, self.custom_field.name + ' ' + ::I18n.t('activerecord.errors.messages.taken'))
          end
        end

        def autoincrement_number_valid?
          return false if self.value.blank?

          return true if CustomValue.where(:customized_type => self.customized.class.name).
            where(:customized_id => self.customized.id).
            where(:custom_field_id => self.custom_field.id).
            where(:value => self.value).count == 1

          settings = self.custom_field.settings || {}
          scope = CustomValue.joins(:custom_field).where(["#{CustomValue.table_name}.custom_field_id = ?", self.custom_field.id]).
            where(["#{CustomField.table_name}.type = ?", self.custom_field.type])

          if self.custom_field.type == 'IssueCustomField' && (settings['per_project'] == '1' || settings['per_tracker'] == '1')
            scope = scope.joins("INNER JOIN #{Issue.table_name} ON #{Issue.table_name}.id = #{CustomValue.table_name}.customized_id")
            if settings['per_project'] == '1'
              scope = scope.where(["#{Issue.table_name}.project_id = ?", self.customized.project_id])
            end
            if settings['per_tracker'] == '1'
              scope = scope.where(["#{Issue.table_name}.tracker_id = ?", self.customized.tracker_id])
            end
          end

          scope = scope.where(["#{CustomValue.table_name}.value = ?", self.value])
          scope.count == 0
        end

        # editable tested on: custom_field, entity, workflow
        def inline_editable?
          return true unless customized.present? &&
                             customized.respond_to?(:editable_custom_field_values) &&
                             customized.respond_to?(:editable?)
          !!(editable? && customized.editable? && customized.editable_custom_field_values.detect {|cfv| cfv.custom_field == custom_field })
        end

      end
    end

    module InstanceMethods

      def visible_with_easy_extensions?
        if self.custom_field.field_format == 'easy_rating'
          User.current && User.current.admin?
        else
          visible_without_easy_extensions?
        end
      end

    end
  end
end
EasyExtensions::PatchManager.register_model_patch 'CustomFieldValue', 'EasyPatch::CustomFieldValuePatch'
