# Copyright (C) 2024 Manuel Bustillo

# Copyright (C) 2024-2025 LibreWeddingPlanner contributors

# frozen_string_literal: true

require 'rails_helper'
module Tables
  RSpec.describe DiscomfortCalculator do
    let(:calculator) { described_class.new(table:) }

    let(:family) { create(:group, name: 'family') }
    let(:friends) { create(:group, name: 'friends') }
    let(:work) { create(:group, name: 'work') }
    let(:school) { create(:group, name: 'school') }

    describe '#calculate' do
      before do
        allow(calculator).to receive_messages(table_size_penalty: 2, cohesion_discomfort: 3)
      end

      let(:table) { Table.new(create_list(:guest, 6)) }

      it 'returns the sum of the table size penalty and the average cohesion penalty', :aggregate_failures do
        expect(calculator.calculate).to eq(7)
        expect(calculator.breakdown).to eq(table_size_penalty: 2, cohesion_penalty: 5)
      end
    end

    describe '#table_size_penalty' do
      before do
        table.min_per_table = 5
        table.max_per_table = 7
      end

      context 'when the number of guests is in the lower bound' do
        let(:table) { Table.new(create_list(:guest, 5)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(0) }
      end

      context 'when the number of guests is within the table size limits' do
        let(:table) { Table.new(create_list(:guest, 6)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(0) }
      end

      context 'when the number of guests is in the upper bound' do
        let(:table) { Table.new(create_list(:guest, 7)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(0) }
      end

      context 'when the number of guests is one unit below the lower bound' do
        let(:table) { Table.new(create_list(:guest, 4)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(5) }
      end

      context 'when the number of guests is two units below the lower bound' do
        let(:table) { Table.new(create_list(:guest, 3)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(10) }
      end

      context 'when the number of guests is one unit above the upper bound' do
        let(:table) { Table.new(create_list(:guest, 8)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(5) }
      end

      context 'when the number of guests is two units above the upper bound' do
        let(:table) { Table.new(create_list(:guest, 9)) }

        it { expect(calculator.send(:table_size_penalty)).to eq(10) }
      end
    end
  end
end