# frozen_string_literal: true

# Site Controller
class SiteController < ApplicationController
  skip_before_action :verify_authenticity_token, only: :teams_webhook

  def up
    render plain: "OK"
  end

  def tasks
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    @tasks = SystemTask
             .includes(:user)
             .order(created_at: :desc)
             .limit(200)

    # Gather IDs from metadata in one pass
    respondent_ids = []
    category_ids = []
    question_ids = []
    highlight_ids = []

    @tasks.each do |task|
      meta = task.metadata&.with_indifferent_access || {}
      respondent_ids       << meta[:respondent_id] if meta[:respondent_id]
      category_ids         << meta[:respondent_category_id] if meta[:respondent_category_id]
      question_ids         << meta[:quantifiable_question_id] if meta[:quantifiable_question_id]
      highlight_ids        << meta[:transcript_highlight_id] if meta[:transcript_highlight_id]
    end

    # Load related records in bulk
    @respondents = Respondent.where(id: respondent_ids.compact.uniq).includes(:project, :respondent_category).index_by(&:id)
    @categories = RespondentCategory.where(id: category_ids.compact.uniq).includes(:project).index_by(&:id)
    @questions = QuantifiableQuestion.where(id: question_ids.compact.uniq).includes(respondent_category: :project).index_by(&:id)
    @highlights = TranscriptHighlight.where(id: highlight_ids.compact.uniq).includes(respondent: %i[project
                                                                                                    respondent_category]).index_by(&:id)

    gon.orgId = current_user.organization_id
  end

  def cancel_system_task
    @task = SystemTask.find(params[:id])
    @task.status = "cancelled"
    @task.running = false
    @task.save
    # TODO: 1) Only pick tasks in the same class 2) Use a background job ExecuteTaskJob (task.execute!)
    pending = SystemTask.where(status: "queued", task_class: @task.task_class).order(:created_at).first
    ExecuteTaskJob.perform_later(pending.id) if pending
    redirect_to "/tasks", notice: "Your task has been cancelled"
  end

  def requests_chart
    @data = InterviewInsight.group_by_minute(:created_at).count
    accumulator = 0
    @data.transform_values! do |val|
      val += accumulator
      accumulator = val
    end
  end

  def index
    redirect_to projects_path if user_signed_in?
  end

  def emergency_shutdown
    CloudServices.stop_instance
    flash[:notice] = "Shutting down transcriber, check back in a minute or two"
    redirect_to root_url
  end

  def toggle_account_state
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    user = User.find(params[:id])
    user.active = !user.active
    user.save!

    flash[:notice] = "#{user.first_name}'s account is now #{user.active ? 'activated' : 'deactivated'}!"
    redirect_to "/user_list"
  end

  def user_list
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    @grouped_users = User.joins(:organization)
                         .includes(:organization)
                         .order("organizations.name, users.first_name").group_by(&:organization)
  end

  def update_user
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    @user = User.find(params[:id])
    return unless request.put?

    if params[:user][:password].blank?
      @user.update!(first_name: params[:user][:first_name], last_name: params[:user][:last_name], email: params[:user][:email],
                    organization_id: params[:user][:organization_id])
    else
      @user.update!(first_name: params[:user][:first_name], last_name: params[:user][:last_name], email: params[:user][:email],
                    password: params[:user][:password], organization_id: params[:user][:organization_id])
    end

    flash[:notice] = "#{@user.first_name}'s account updated"
    redirect_to "/user_list"
  end

  def create_account
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    return unless request.post?

    user = User.new(
      first_name: params[:user][:first_name],
      last_name: params[:user][:last_name],
      email: params[:user][:email],
      password: params[:user][:password],
      organization_id: params[:user][:organization_id]
    )
    flash[:notice] = if user.save!
                       "Account created"
                     else
                       "Account could not be created"
                     end
    redirect_to "/user_list"
  end

  def delete_account
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    return unless request.delete?

    user = User.find(params[:id])
    name = user.name
    user.destroy
    params[:notice] = "#{name}'s account deleted"
  end

  def teams_webhook
    TeamsIncidentAlertJob.perform_later(params.to_unsafe_h)
    head :ok
  end

  def qual_alert
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    return unless request.post?

    message = params[:message]
    TeamsAlertJob.perform_later(message:)

    flash[:notice] = "Alert Sent"
    redirect_to "/qual_alert"
  end

  def manage
    redirect_to "/projects" unless current_user.sprint_user? && current_user.admin?

    @admin_views = [
      OpenStruct.new(
        title: "Task Management",
        description: "List of system tasks.",
        path: tasks_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "Organization Management",
        description: "Create, edit, and delete organization.",
        path: organizations_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "User Management",
        description: "Create, edit, and delete users.",
        path: user_list_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "Instruction Prompts",
        description: "Manage prompts for AI.",
        path: instructions_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "Feature Management",
        description: "Enable/Disable features for organizations.",
        path: features_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "Feature - Model Assignment",
        description: "Map app features to specific LLM models.",
        path: feature_model_maps_path,
        needs_attention: false
      ),
      OpenStruct.new(
        title: "Model-Language Management",
        description: "Manage models and associated languages",
        path: asr_models_path,
        needs_attention: false
      )
      # Add more views as needed
    ]
  end
end
