# frozen_string_literal: true

class CreateFavorites < ActiveRecord::Migration[7.0]
  STATE_NAMES = %w(ProjectList_active_state ProjectList_archived_state ExperimentList_active_state
                   ExperimentList_archived_state MyModuleList_active_state MyModuleList_archived_state).freeze
  def change
    create_table :favorites do |t|
      t.references :user, null: false, foreign_key: true
      t.references :team, null: false, foreign_key: true
      t.references :item, polymorphic: true, null: false

      t.timestamps
    end

    add_index(
      :favorites,
      %i(user_id team_id item_id item_type),
      unique: true,
      name: :index_favorites_on_user_and_item_and_team
    )

    User.reset_column_information

    reversible do |dir|
      dir.up do
        User.find_each do |user|
          update = false
          STATE_NAMES.each do |state_name|
            state = user.settings.dig(state_name, 'columnsState')
            next if state.blank?

            update = true

            # get number of pinned columns
            pinned_items_count = state.count { |el| el['pinned'].present? }

            # update position of columns if they are not pinned
            state.each do |el|
              el['position'] += 1 if el['pinned'].blank? && el['position'].present?
            end

            # create new state of favorite column
            new_element = {
              colId: 'favorite',
              hide: false,
              pinned: nil
            }

            # add only position if other columns have positions. Position only get columns for which user at least once change settings
            new_element[:position] = pinned_items_count if state.dig(0, 'position').present?
            state.insert(pinned_items_count, new_element)
          end
          user.save! if update
        end
      end

      dir.down do
        User.find_each do |user|
          update = false
          STATE_NAMES.each do |state_name|
            state = user.settings.dig(state_name, 'columnsState')
            next if state.blank?

            update = true

            favorite = state.find { |el| el['colId'] == 'favorite' }

            next unless favorite

            state.reject! { |el| el['colId'] == 'favorite' }

            next if favorite['position'].blank?

            state.each do |el|
              el['position'] -= 1 if el['position'].present? && el['position'] > favorite['position']
            end
          end
          user.save! if update
        end
      end
    end
  end
end
