#include <FastLED.h>

#define FASTLED_VERSION 3001000 // Ensure FastLED version is at least 3.1

#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    11
#define LED_TYPE    WS2812B
#define COLOR_ORDER RGB
#define NUM_LEDS    20

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  fill_solid(leds, NUM_LEDS, CRGB::White);
  FastLED.show();
  delay(2000); // Wait for 2 seconds
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
  delay(2000); // Wait for 2 seconds
}

void fadeUpDownGroupToColor(int ledsGroup1[], int groupSize1, int ledsGroup2[], int groupSize2, CRGB color1, CRGB color2) {
  // Fade up
  for (int brightness = 0; brightness <= 255; brightness++) {
    for (int i = 0; i < groupSize1; i++) {
      int ledIndex1 = ledsGroup1[i];
      leds[ledIndex1] = color1;
    }
    for (int j = 0; j < groupSize2; j++) {
      int ledIndex2 = ledsGroup2[j];
      leds[ledIndex2] = color2;
    }
    FastLED.setBrightness(brightness);
    FastLED.show();
    delay(10);
  }
  // Fade down
  for (int brightness = 255; brightness >= 0; brightness--) {
    for (int i = 0; i < groupSize1; i++) {
      int ledIndex1 = ledsGroup1[i];
      leds[ledIndex1] = color1;
    }
    for (int j = 0; j < groupSize2; j++) {
      int ledIndex2 = ledsGroup2[j];
      leds[ledIndex2] = color2;
    }
    FastLED.setBrightness(brightness);
    FastLED.show();
    delay(10);
  }
}

void loop() {
  int blueLedsGroup[] = {0, 1, 2, 3};
  fadeUpDownGroupToColor(blueLedsGroup, sizeof(blueLedsGroup) / sizeof(blueLedsGroup[0]), {}, 0, CRGB::Blue, CRGB::Blue);
  delay(2000); // Wait for 2 seconds

  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
  delay(2000); // Wait for 2 seconds

  int greenLedsGroup[] = {4, 5, 6, 7};
  int redLedsGroup[] = {8, 9, 10, 11};
  fadeUpDownGroupToColor(greenLedsGroup, sizeof(greenLedsGroup) / sizeof(greenLedsGroup[0]), redLedsGroup, sizeof(redLedsGroup) / sizeof(redLedsGroup[0]), CRGB::Green, CRGB::Red);

  delay(2000); // Wait for 2 seconds

  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
  delay(2000); // Wait for 2 seconds
}