require 'icalendar/tzinfo'

class AssignmentsController < ApplicationController
  before_action :set_session, :set_users

  def index
    @assignments = Assignment.all
    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.'
      Turbo::StreamsChannel.broadcast_replace_later_to(
        @session,
        target: 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 }), status: :unprocessable_entity }
        format.html { redirect_to conference_session_path(@session.conference, @session), alert: 'Please select a user to assign.' }
      end
      return
    end
    @session = Session.find_by(ref_id: params[:session_ref_id])
    @conference = Conference.find_by(slug: params[:conference_slug])
    @user = User.find(params[:user_id])
    @assignment = Assignment.new(user: @user, session: @session)

    if @assignment.save
      Turbo::StreamsChannel.broadcast_replace_later_to(
        @session,
        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
      Turbo::StreamsChannel.broadcast_replace_later_to(
        @session,
        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
          other_users = session.assignments.map { |a| a.user.name }
          other_users = other_users - [ @user.name ]

          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 = other_users.join(', ') + "\n\n" + helpers.strip_tags(session.description)
          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", other_users.join(', ') + "\n\n" + session.description)
          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
    @session = Session.find_by(ref_id: params[:session_ref_id])
  end

  def set_users
    @users = User.all
  end
end