class RepositoryColumnsController < ApplicationController
  include InputSanitizeHelper
  include RepositoryColumnsHelper

  before_action :load_repository
  before_action :load_column, only: %i(edit update destroy_html destroy items)
  before_action :check_create_permissions, only: %i(new create)
  before_action :check_manage_permissions, only: %i(edit update destroy_html destroy)
  before_action :load_asset_type_columns, only: :available_asset_type_columns

  def index
    render json: {
      id: @repository.id,
      html: render_to_string(
        partial: 'repository_columns/manage_column_modal_index.html.erb'
      )
    }
  end

  def new
    @repository_column = RepositoryColumn.new
    respond_to do |format|
      format.json do
        render json: {
          html: render_to_string(
            partial: 'repository_columns/manage_column_modal_content.html.erb'
          )
        }
      end
    end
  end

  def create
    raise NotImplementedError
  end

  def edit
    render json: {
      html: render_to_string(
        partial: 'repository_columns/manage_column_modal_content.html.erb'
      )
    }
  end

  def update
    raise NotImplementedError
  end

  def destroy_html
    respond_to do |format|
      format.json do
        render json: {
          html: render_to_string(
            partial: 'repository_columns/delete_column_modal_body.html.erb'
          )
        }
      end
    end
  end

  def destroy
    column_id = @repository_column.id
    column_name = @repository_column.name

    log_activity(:delete_column_inventory) # Should we move this call somewhere?
    respond_to do |format|
      format.json do
        if @repository_column.destroy
          render json: {
            message: t('libraries.repository_columns.destroy.success_flash',
                       name: escape_input(column_name)),
            id: column_id,
            status: :ok
          }
        else
          render json: {
            message: t('libraries.repository_columns.destroy.error_flash'),
            status: :unprocessable_entity
          }
        end
      end
    end
  end

  def items
    raise NotImplementedError
  end

  def available_asset_type_columns
    if @asset_columns.empty?
      render json: {
        no_items: t(
          'projects.reports.new.save_PDF_to_inventory_modal.no_columns'
        )
        }, status: :ok
    else
      render json: { results: @asset_columns }, status: :ok
    end
  end

  def available_columns
    render json: { columns: @repository.repository_columns.pluck(:id) }, status: :ok
  end

  private

  include StringUtility
  AvailableRepositoryColumn = Struct.new(:id, :name)

  def load_repository
    @repository = Repository.accessible_by_teams(current_team).find_by(id: params[:repository_id])
    render_404 unless @repository
  end

  def load_column
    @repository_column = @repository.repository_columns.find_by(id: params[:id])
    render_404 unless @repository_column
  end

  def load_asset_type_columns
    render_403 unless can_read_repository?(@repository)
    @asset_columns = load_asset_columns(search_params[:q])
  end

  def check_create_permissions
    render_403 unless can_create_repository_columns?(@repository)
  end

  def check_manage_permissions
    render_403 unless can_manage_repository_column?(@repository_column)
  end

  def search_params
    params.permit(:q, :repository_id)
  end

  def load_asset_columns(query)
    @repository.repository_columns
               .asset_type.name_like(query)
               .limit(Constants::SEARCH_LIMIT)
               .select(:id, :name)
               .collect do |column|
                 AvailableRepositoryColumn.new(
                   column.id,
                   ellipsize(column.name, 75, 50)
                 )
               end
  end

  def log_activity(type_of)
    Activities::CreateActivityService
      .call(activity_type: type_of,
            owner: current_user,
            subject: @repository,
            team: current_team,
            message_items: {
              repository_column: @repository_column.id,
              repository: @repository.id
            })
  end
end
