require "icalendar/tzinfo"

class AssignmentsController < ApplicationController
  before_action :authorize_shiftcoordinator, except: [ :index, :by_user ]
  before_action :set_session, :set_users

  def index
    @assignments = Assignment.all.joins(:session, :user).order("sessions.starts_at")
    if params[:user_id]
      @assignments = @assignments.where(user_id: params[:user_id])
    end
  end

  def create
    params[:user_id] ||= params[:assignment][:user_id]
    if params[:user_id].nil? or params[:user_id].empty?
      flash.now[:alert] = "Please select a user to assign."
      respond_to do |format|
        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }), status: :unprocessable_entity }
        format.html { redirect_to conference_session_path(@session.conference, @session), alert: "Please select a user to assign." }
      end
      return
    end

    @conference = Conference.find_by(slug: params[:conference_slug])
    @session = Session.find_by(conference: @conference, ref_id: params[:session_ref_id])
    @user = User.find(params[:user_id])
    @assignment = Assignment.new(user: @user, session: @session)

    if @assignment.save
      Rails.logger.debug("Saved assignment #{@assignment.inspect}")
      Turbo::StreamsChannel.broadcast_replace_to(
        @session.conference,
        target: helpers.dom_id(@session),
        partial: "sessions/session",
        locals: { session: @session }
      )
      flash.now[:success] = "User assigned successfully."
      respond_to do |format|
        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }) }
        format.html { redirect_to conference_session_path(@session.conference, @session), success: "User assigned successfully." }
      end
    else
      flash.now[:alert] = "Failed to assign user."
      respond_to do |format|
        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }), status: :unprocessable_entity }
        format.html { render :show, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @assignment = Assignment.find(params[:id])
    @session = @assignment.session

    if @assignment&.destroy
      Rails.logger.debug("destroyed assignment")
      Turbo::StreamsChannel.broadcast_replace_later_to(
        @session.conference,
        target: helpers.dom_id(@session),
        partial: "sessions/session",
        locals: { session: @session }
      )
      respond_to do |format|
        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }) }
        format.html { redirect_to conference_session_path(@session.conference, @session), notice: "User removed successfully." }
      end
    else
      respond_to do |format|
        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }), status: :unprocessable_entity }
        format.html { redirect_to conference_session_path(@session.conference, @session), alert: "Failed to remove user." }
      end
    end
  end

  def by_user
    @user = User.includes(:assignments).find(params[:user_id])
    respond_to do |format|
      format.html # This will render the existing HTML view (assignments/by_user.html.erb)

      format.ics do
        calendar = Icalendar::Calendar.new
        tz = TZInfo::Timezone.get("UTC")
        calendar.add_timezone tz.ical_timezone Time.now

        @user.assignments.each do |assignment|
          session = assignment.session
          assignees = session.assignments.map { |a| a.user.name }
          desc = [
            "Assignees: #{assignees.join(', ')}",
            "Speakers: #{session.speakers.map(&:name).join(', ')}",
            session.description
          ]
          desc.unshift("Filedrop has data for this session!<br>\n" + conference_session_url(session.conference, session)) if session.filedrop?

          event = Icalendar::Event.new
          event.dtstart = Icalendar::Values::DateTime.new(session.starts_at, tzid: session.starts_at.time_zone.tzinfo.name)
          event.dtend = Icalendar::Values::DateTime.new(session.ends_at, tzid: session.ends_at.time_zone.tzinfo.name)
          event.summary = [ session.title, session.stage.name ].join(" @ ")
          event.description = desc.map { |l| helpers.strip_tags(l) }.join("\n\n")
          event.location = [ session.stage.name, session.conference.name ].join(" @ ")
          event.created = Icalendar::Values::DateTime.new(session.created_at)
          event.last_modified = Icalendar::Values::DateTime.new(session.updated_at)
          event.uid = [ session.conference.slug, session.ref_id ].join("-")
          event.append_custom_property("X-ALT-DESC;FMTTYPE=text/html", desc.join("<hr>"))
          calendar.add_event(event)
        end

        calendar.publish
        headers["Content-Type"] = "text/calendar; charset=UTF-8"
        render plain: calendar.to_ical
      end
    end
  end

  private

  def set_session
    conference = Conference.find_by(slug: params[:conference_slug])
    @session = Session.find_by(conference:, ref_id: params[:session_ref_id])
  end

  def set_users
    @users = User.all
  end
end