module Twitch
  class TeamsController < Twitch::BaseController
    before_action -> { authorize Team }
    before_action :set_team, only: [:show, :edit, :update, :delete, :destroy]
    before_action :set_user, only: [:show, :edit, :update]
    before_action :set_search_name, only: :search

    def index
      @teams = Team.page(params[:page].try(:to_i) || 1)
      @user_map = map_ids_to_users(@teams.map(&:user_id).uniq)
    end

    def show
    end

    def new
      @team = Team.new
    end

    def create
      login = user_login_param
      @user = User.find_by_login(login)
      @team = Team.new(team_params)

      if @user.nil?
        flash.now[:error] = "Invalid team owner: user '#{login}' not found"
        render :new
        return
      end

      if @user.deleted_on || @user.dmca_violation || @user.terms_of_service_violation
        flash.now[:error] = "Invalid team owner: user '#{login}' not allowed"
        render :new
        return
      end

      @team.user_id = @user.id

      if @team.save
        flash[:success] = "Team '#{@team.name}' successfully created!"

        track_action! trackable_request
          .assemble_an
          .admin_panel_teams_create(
            team_name: params[:name],
            team_display_name: params[:display_name],
            team_owner_login: params[:user_login],
            team_owner_id: @user.id,
            team_description: params[:description_markdown]
          )

        redirect_to twitch_team_path(@team)
      else
        flash.now[:error] = @team.errors.full_messages
        render :new
      end
    end

    def edit
    end

    def update
      submitted_login = user_login_param
      attributes = update_params

      if submitted_login != @user.login
        @user = User.find_by_login(submitted_login)

        if @user.nil?
          flash.now[:error] = "Invalid team owner: user '#{submitted_login}' not found"
          render :edit
          return
        end

        if @user.deleted_on || @user.dmca_violation || @user.terms_of_service_violation
          flash.now[:error] = "Invalid team owner: user '#{submitted_login}' not allowed"
          render :edit
          return
        end

        attributes[:user_id] = @user.id.to_s
      end

      if @team.update(attributes)
        flash[:success] = "Team '#{@team.name}' successfully updated!"
        redirect_to twitch_team_path(@team)
      else
        flash.now[:error] = @team.errors.full_messages
        render :edit
      end
    end

    def delete
    end

    def destroy
      if @team.destroy
        flash[:notice] = "Team '#{@team.name}' has been deleted"
        redirect_to twitch_teams_path
      else
        flash.now[:error] = @team.errors.full_messages
        render :edit
      end
    end

    def search
      @teams = Team.search(
        name: @search_name,
        page: params[:page].try(:to_i) || 1
      )

      track_action! trackable_request
        .assemble_an
        .admin_panel_teams_search(
          query: params[:name]
        )

      @user_map = map_ids_to_users(@teams.map(&:user_id).uniq)
    end

    private

    def map_ids_to_users(ids)
      users = User.all(where: { id: ids })

      users.each_with_object({}) { |user, map| map[user.id.to_s] = user }
    end

    def set_search_name
      @search_name = params[:name].try(:downcase)

      redirect_to twitch_teams_path if @search_name.blank?
    end

    def set_team
      @team = Team.find_by_name(params[:name])

      return true if @team

      flash[:error] = "Team '#{params[:name]}' not found"
      redirect_to twitch_teams_path
    end

    def set_user
      @user = User.find(@team.user_id)
    end

    def team_params
      params.require(:twitch_team).permit(:name, :display_name, :description_markdown)
    end

    def update_params
      team_params.slice(:display_name, :description_markdown).merge(user_id: @team.user_id)
    end

    def user_login_param
      params.require(:user_login).downcase
    end
  end
end
