module Client
  class ServiceRequestsController < ApplicationController
    before_action :authenticate_user!
    before_action -> { authenticate_role!(:client) }

    def index
      @service_requests = current_user.client_service_requests.inactive.order(created_at: :desc)
    end

    def show
      return unless service_request.in_progress? || service_request.waiting_for_answer?

      redirect_to call_client_service_request_path(service_request)
    end

    def new
      @service_request = ServiceRequest.new
    end

    def create
      if ServiceCenter.closed?
        flash.now[:info] = I18n.t("errors.messages.service_center_is_closed")
        return render turbo_stream: update_flash_messages_turbo_stream
      end

      @service_request = service_request = ServiceRequest.create(service_request_params.merge(client: current_user))

      if service_request.persisted?
        current_user.update(user_params)

        service_request.prepend_to_todays_requests_list
        service_request.prepend_to_all_service_requests_list

        redirect_to client_home_path, status: :see_other
      else
        render :new, status: :unprocessable_entity
      end
    end

    def accept
      service_request = current_user.client_service_requests.find(params[:id])
      if service_request.waiting_for_answer?
        service_request.update(status: :in_progress, call_started_at: Time.current)
        service_request.logs.create(type: :call_started)
      end

      other_requests = service_request.client.client_service_requests.where.not(id: service_request.id)

      service_request.broadcast_replace_to service_request.agent,
                                           target: helpers.dom_id(service_request, :agent_call_sidebar),
                                           partial: "agent/service_requests/call_sidebar",
                                           locals: {
                                             current_user: service_request.agent,
                                             service_request:,
                                             other_requests:
                                           }

      service_request.broadcast_replace_to service_request.agent,
                                           target: helpers.dom_id(service_request, :client_audio_mute_indicator),
                                           partial: "agent/service_requests/audio_mute_indicator",
                                           locals: { service_request: }

      service_request.broadcast_append_to service_request.client,
                                          target: "flash_messages",
                                          partial: "agent/service_requests/incoming_call",
                                          locals: { service_request: }
    end

    def decline
      service_request.update(status: :waiting)

      service_request.broadcast_append_to service_request.agent,
                                          target: helpers.dom_id(service_request, :call),
                                          partial: "client/service_requests/declined_call",
                                          locals: { service_request:, current_user: }

      service_request.broadcast_update_to_reserved_requests

      redirect_to client_home_path, status: :see_other
    end

    def call
      @nav_disabled = true
      @footer_disabled = true

      redirect_to client_home_path if service_request.cancelled? || service_request.finished?
    end

    def mute_video
      service_request.toggle!(:is_client_video_muted)
    end

    def mute_audio
      service_request.toggle!(:is_client_audio_muted)
      service_request.broadcast_replace_to service_request.agent,
                                           target: helpers.dom_id(service_request, :client_audio_mute_indicator),
                                           partial: "agent/service_requests/audio_mute_indicator",
                                           locals: { service_request: }
    end

    def cancel
      service_request = current_user.client_service_requests.find(params[:id])
      if service_request.waiting? || service_request.waiting_for_answer? || service_request.in_progress?
        service_request.update(status: :cancelled)
      end

      service_request.broadcast_update_to %i[agent todays_service_requests],
                                          target: helpers.dom_id(service_request),
                                          partial: "agent/service_requests/service_request",
                                          locals: {
                                            service_request:
                                          }

      service_request.broadcast_update_to %i[agent all_service_requests],
                                          target: helpers.dom_id(service_request),
                                          partial: "agent/service_requests/service_request",
                                          locals: {
                                            service_request:
                                          }

      service_request.broadcast_replace_to service_request.agent,
                                           target: helpers.dom_id(service_request, :call),
                                           partial: "agent/service_requests/call",
                                           locals: {
                                             current_user: service_request.agent,
                                             service_request:
                                           }

      service_request.broadcast_replace_to service_request,
                                           target: helpers.dom_id(service_request, :agent_sidebar),
                                           partial: "agent/service_requests/sidebar",
                                           locals: {
                                             current_user: service_request.agent,
                                             service_request:
                                           }

      redirect_to client_service_requests_path, status: :see_other
    end

    def finish
      call_duration = service_request.call_started_at ? Time.current - service_request.call_started_at : 0
      service_request.update(status: :finished, call_ended_at: Time.current,
                             call_duration:)

      service_request.broadcast_append_to service_request.agent,
                                          target: helpers.dom_id(service_request, :chat),
                                          partial: "client/service_requests/cancelled_call",
                                          locals: { service_request:, current_user: }

      service_request.broadcast_update_to_reserved_requests

      redirect_to client_service_request_path(service_request), status: :see_other
    end

    def reactivate
      return head :unprocessable_entity if ServiceCenter.closed?

      service_request.update(status: :waiting)

      service_request.broadcast_prepend_to %i[agent todays_service_requests],
                                           target: "agent_todays_service_requests",
                                           partial: "agent/service_requests/service_request",
                                           locals: {
                                             service_request:
                                           }

      service_request.broadcast_prepend_to %i[agent all_service_requests],
                                           target: "agent_all_service_requests",
                                           partial: "agent/service_requests/service_request",
                                           locals: {
                                             service_request:
                                           }

      service_request.broadcast_replace_to service_request,
                                           target: helpers.dom_id(service_request, :agent_sidebar),
                                           partial: "agent/service_requests/sidebar",
                                           locals: {
                                             current_user: service_request.agent,
                                             service_request:
                                           }

      redirect_to client_service_request_path(service_request)
    end

    private

    def user_params
      params.require(:user).permit(
        :first_name,
        :last_name,
        :address,
        :gender,
        :social_security_number,
        :license_plate,
        :phone_number,
        :place_name,
        :reschedule_contact_info,
        :editor_name,
        :reference_number,
        :shipment_id
      )
    end

    def service_request
      @service_request ||= current_user.client_service_requests.find(params[:id])
    end

    def waiting_service_requests
      current_user.client_service_requests.waiting
    end

    def service_requests
      current_user.client_service_requests.not_waiting
    end

    def service_request_params
      params.require(:service_request).permit(
        :title, :description, :category_id
      )
    end
  end
end
