module Public
  class MatchesController < WebBaseController
    before_action :require_login!
    before_action :set_team
    before_action :require_can_schedule!
    before_action :set_match, only: %i[edit update destroy]

    def index
      @matches = @team.matches
        .includes(:stream_sessions)
        .order(Arel.sql("scheduled_at ASC NULLS LAST"), created_at: :desc)
      @can_manage = @team.club.owned_by?(current_user)
    end

    def new
      @match = @team.matches.build(
        sport: @team.sport,
        sets_to_win: 3,
        scheduled_at: default_scheduled_at
      )
    end

    def create
      @match = @team.matches.create!(
        match_params.merge(sport: @team.sport, sets_to_win: match_params[:sets_to_win].presence || 3)
      )
      redirect_to public_team_matches_path(@team),
                  notice: "Partita programmata: #{@match.opponent_name}. Avvia lo streaming dall’app quando sei in palestra."
    rescue ActiveRecord::RecordInvalid => e
      @match = @team.matches.build(match_params)
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :new, status: :unprocessable_entity
    end

    def edit
    end

    def update
      @match.update!(match_params)
      redirect_to public_team_matches_path(@team), notice: "Partita aggiornata."
    rescue ActiveRecord::RecordInvalid => e
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :edit, status: :unprocessable_entity
    end

    def destroy
      active = active_session_for(@match)
      if active&.resumable?
        redirect_to public_team_matches_path(@team),
                    alert: "Chiudi la diretta prima di eliminare questa partita."
        return
      end

      @match.destroy!
      redirect_to public_team_matches_path(@team), notice: "Partita eliminata."
    end

    private

    def set_team
      @team = current_user.manageable_teams.find(params[:team_id])
      @club = @team.club
    end

    def require_can_schedule!
      return if current_user.can_schedule_for?(@team)

      redirect_to public_team_details_path(@team),
                  alert: "Solo un responsabile trasmissione o il titolare della società possono programmare le partite."
    end

    def set_match
      @match = @team.matches.find(params[:id])
    end

    def match_params
      p = params.require(:match).permit(:opponent_name, :location, :scheduled_at, :sport, :sets_to_win)
      p[:scheduled_at] = parse_scheduled_at(p[:scheduled_at]) if p[:scheduled_at].present?
      p
    end

    def parse_scheduled_at(value)
      raw = value.to_s.strip
      return nil if raw.blank?

      Time.zone.strptime(raw, "%Y-%m-%dT%H:%M")
    rescue ArgumentError
      Time.zone.parse(raw)
    end

    def default_scheduled_at
      t = Time.current + 2.hours
      Time.zone.local(t.year, t.month, t.day, t.hour, 0, 0)
    end

    def active_session_for(match)
      match.stream_sessions
           .order(created_at: :desc)
           .find { |s| !%w[ended error].include?(s.status) }
    end
  end
end
