module Api
  module V1
    class MatchesController < BaseController
      before_action :set_team, only: %i[index create]
      before_action :set_match, only: %i[show update destroy]

      def index
        matches = @team.matches
          .includes(:team, :stream_sessions)
          .order(Arel.sql("scheduled_at ASC NULLS LAST"), created_at: :desc)
        render json: matches.map { |m| match_json(m) }
      end

      def create
        match = @team.matches.create!(match_params)
        render json: match_json(match), status: :created
      end

      def show
        render json: match_json(@match, detail: true)
      end

      def update
        @match.update!(match_params)
        render json: match_json(@match)
      end

      def destroy
        active = active_session_for(@match)
        if active&.resumable?
          return render json: {
            error: "Chiudi la diretta prima di eliminare questa partita"
          }, status: :unprocessable_entity
        end

        @match.destroy!
        head :no_content
      end

      private

      def set_team
        @team = current_user.streamable_teams.find { |t| t.id == params[:team_id] }
        raise ActiveRecord::RecordNotFound unless @team
      end

      def set_match
        team_ids = current_user.streamable_teams.map(&:id)
        @match = Match.where(team_id: team_ids).find(params[:id])
      end

      def match_params
        params.require(:match).permit(
          :opponent_name, :location, :scheduled_at, :sport, :sets_to_win,
          :category, :phase, roster_numbers: [],
          scoring_rules: %i[points_per_set points_deciding_set min_point_lead]
        )
      end

      def match_json(match, detail: false)
        active = active_session_for(match)
        {
          id: match.id,
          team_id: match.team_id,
          team_name: match.team.name,
          opponent_name: match.opponent_name,
          location: match.location,
          scheduled_at: match.scheduled_at,
          sport: match.sport,
          sets_to_win: match.sets_to_win,
          scoring_rules: match.scoring_rules.presence,
          roster_numbers: match.roster_numbers,
          category: match.category,
          phase: match.phase,
          active_session_id: active&.id,
          active_session_status: active&.status
        }
      end

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