module ForestLiana
  describe LineStatGetter do
    let(:rendering_id) { 13 }
    let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
    let(:scopes) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }

    before(:each) do
      ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
      allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
    end

    describe 'with not allowed aggregator' do
      it 'should raise an error' do
        expect {
          LineStatGetter.new(Owner, {
            timezone: "Europe/Paris",
            aggregator: "eval",
            timeRange: "Week",
            groupByFieldName: "`ls`",
          }, user)
        }.to raise_error(ForestLiana::Errors::HTTP422Error, 'Invalid aggregate function')
      end
    end

    describe 'Check client_timezone function' do
      describe 'with a SQLite database' do
        it 'should return false' do
          expect(LineStatGetter.new(Owner, {
            timezone: "Europe/Paris",
            aggregator: "Count",
          }, user).client_timezone).to eq(false)
        end
      end

      describe 'with a non-SQLite database' do
        before do
          allow(ActiveRecord::Base.connection).to receive(:adapter_name).and_return('NotSQLite')
        end

        it 'should return the timezone' do
          expect(LineStatGetter.new(Owner, {
            timezone: "Europe/Paris",
            aggregator: "Count",
          }, user).client_timezone).to eq('Europe/Paris')
        end
      end
    end

    describe 'Check perform function' do
      describe 'Using a Count aggregation' do
        describe 'Using a Week time range' do
          it 'should return consistent data based on monday as week_start ' do
            # Week should start on monday
            # 08-05-2021 was a Saturday
            Owner.delete_all
            Owner.create(name: 'Michel', hired_at: Date.parse('08-05-2021'));
            Owner.create(name: 'Robert', hired_at: Date.parse('09-05-2021'));
            Owner.create(name: 'José', hired_at: Date.parse('10-05-2021'));
            Owner.create(name: 'Yves', hired_at: Date.parse('11-05-2021'));

            stat = LineStatGetter.new(Owner, {
              timezone: "Europe/Paris",
              aggregator: "Count",
              timeRange: "Week",
              groupByFieldName: "hired_at",
            }, user).perform

            expect(stat.value.find { |item| item[:label] == "W18-2021" }[:values][:value]).to eq(2)
            expect(stat.value.find { |item| item[:label] == "W19-2021" }[:values][:value]).to eq(2)
          end

          it 'should return consistent data for a leap year with week transition' do
            Owner.delete_all
            Owner.create(name: 'Michel', hired_at: Date.parse('23-12-2024'));
            Owner.create(name: 'Robert', hired_at: Date.parse('23-12-2024'));
            Owner.create(name: 'José', hired_at: Date.parse('30-12-2024'));
            Owner.create(name: 'Yves', hired_at: Date.parse('06-01-2025'));

            stat = LineStatGetter.new(Owner, {
              timezone: "Europe/Paris",
              aggregator: "Count",
              timeRange: "Week",
              groupByFieldName: "hired_at",
            }, user).perform

            expect(stat.value.find { |item| item[:label] == "W52-2024" }[:values][:value]).to eq(2)
            expect(stat.value.find { |item| item[:label] == "W01-2025" }[:values][:value]).to eq(1)
            expect(stat.value.find { |item| item[:label] == "W02-2025" }[:values][:value]).to eq(1)
          end
        end
      end
    end

    describe 'Check new instance function' do
      describe 'Using a Count aggregation' do
        it 'should remove any order to the resource' do
          Owner.create(name: 'Shuri', hired_at: Date.parse('09-11-2022'));
          stat = LineStatGetter.new(Owner, {
            timezone: "Europe/Paris",
            aggregator: "Count",
            timeRange: "Day",
            groupByFieldName: "hired_at",
          }, user)

          expect(stat.get_resource.where(name: "Shuri").to_sql.downcase.exclude? "order by").to be true
        end
      end
    end
  end
end
