const byte PEATONAL_A_BLANCO = 2;
const byte PEATONAL_A_ROJO = 3;
const byte PEATONAL_B_BLANCO = 8;
const byte PEATONAL_B_ROJO = 7;

const byte VEHICULAR_A_ROJO = 6;
const byte VEHICULAR_A_AMARILLO = 5;
const byte VEHICULAR_A_VERDE = 4;
const byte VEHICULAR_B_ROJO = 11;
const byte VEHICULAR_B_AMARILLO = 10;
const byte VEHICULAR_B_VERDE = 9;

const unsigned long TIEMPO_ROAM = 2000; // tiempo rojo + amarillo
const unsigned long TIEMPO_VERDE = 35000; // tiempo verde
const unsigned long TIEMPO_AMARILLO = 3000; // tiempo amarillo
const unsigned long TIEMPO_ROJO = TIEMPO_VERDE + TIEMPO_AMARILLO; // tiempo rojo

const unsigned long T1_A = TIEMPO_VERDE;
const unsigned long T2_A = T1_A + TIEMPO_AMARILLO;
const unsigned long T3_A = T2_A + TIEMPO_ROJO + TIEMPO_ROAM;
const unsigned long T4_A = T3_A + TIEMPO_ROAM;
/*
const unsigned long T1_B = TIEMPO_ROJO;
const unsigned long T2_B = T1_B + TIEMPO_ROAM;
const unsigned long T3_B = T2_B + TIEMPO_VERDE;
const unsigned long T4_B = T3_B + TIEMPO_AMARILLO;
const unsigned long T5_B = T4_B + TIEMPO_ROAM;
*/
const unsigned long TIEMPO_PARPADEO = 10000UL;

const unsigned long P1_A = TIEMPO_VERDE;
const unsigned long P2_A = P1_A + TIEMPO_AMARILLO;
const unsigned long P3_A = P2_A + TIEMPO_ROJO - TIEMPO_PARPADEO;
const unsigned long P4_A = P2_A + TIEMPO_ROJO;
const unsigned long P5_A = P4_A + TIEMPO_ROAM;

unsigned long oldTime_A;
unsigned long oldTime_B;
unsigned long time_A;
unsigned long time_B;
unsigned long time_C;

void iniciar() {
  digitalWrite(VEHICULAR_A_VERDE, 0);
  digitalWrite(VEHICULAR_A_AMARILLO, 1);
  digitalWrite(VEHICULAR_A_ROJO, 1);

  digitalWrite(VEHICULAR_B_VERDE, 0);
  digitalWrite(VEHICULAR_B_AMARILLO, 0);
  digitalWrite(VEHICULAR_B_ROJO, 1);

  digitalWrite(PEATONAL_A_BLANCO, 0);
  digitalWrite(PEATONAL_A_ROJO, 1);

  digitalWrite(PEATONAL_B_BLANCO, 0);
  digitalWrite(PEATONAL_B_ROJO, 1);

  delay(2000);

  digitalWrite(VEHICULAR_A_AMARILLO, 0);
  digitalWrite(VEHICULAR_A_ROJO, 0);
  digitalWrite(VEHICULAR_A_VERDE, 1);

  digitalWrite(VEHICULAR_B_VERDE, 0);
  digitalWrite(VEHICULAR_B_AMARILLO, 0);
  digitalWrite(VEHICULAR_B_ROJO, 1);

  digitalWrite(PEATONAL_A_BLANCO, 0);
  digitalWrite(PEATONAL_A_ROJO, 1);

  digitalWrite(PEATONAL_B_ROJO, 0);
  digitalWrite(PEATONAL_B_BLANCO, 1);

}


void semaforo_A() {
  if (time_A >= T4_A) {   // A -> verde
    digitalWrite(VEHICULAR_A_AMARILLO, 0);
    digitalWrite(VEHICULAR_A_ROJO, 0);
    digitalWrite(VEHICULAR_A_VERDE, 1);
    time_A = 0;
  }
  else if (time_A >= T3_A) {  // A -> rojo y amarillo
    digitalWrite(VEHICULAR_A_VERDE, 0);
    digitalWrite(VEHICULAR_A_AMARILLO, 1);
    digitalWrite(VEHICULAR_A_ROJO, 1);
  }
  else if (time_A >= T2_A) {  // A -> rojo
    digitalWrite(VEHICULAR_A_VERDE, 0);
    digitalWrite(VEHICULAR_A_AMARILLO, 0);
    digitalWrite(VEHICULAR_A_ROJO, 1);
  }
  else if (time_A  >= T1_A) {  // A -> amarillo
    digitalWrite(VEHICULAR_A_ROJO, 0);
    digitalWrite(VEHICULAR_A_VERDE, 0);
    digitalWrite(VEHICULAR_A_AMARILLO, 1);
  }
}

void semaforo_B() {
  if (time_B >= T4_A) {   // B -> verde
    digitalWrite(VEHICULAR_B_AMARILLO, 0);
    digitalWrite(VEHICULAR_B_ROJO, 0);
    digitalWrite(VEHICULAR_B_VERDE, 1);
    time_B = 0;
  }
  else if (time_B >= T3_A) {  // B -> rojo y amarillo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 1);
    digitalWrite(VEHICULAR_B_ROJO, 1);
  }
  else if (time_B >= T2_A) {  // B -> rojo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 0);
    digitalWrite(VEHICULAR_B_ROJO, 1);
  }
  else if (time_B  >= T1_A) {  // B -> amarillo
    digitalWrite(VEHICULAR_B_ROJO, 0);
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 1);
  }
}

/*
void semaforo_B() {
  if (time_B - oldTime_B >= T5_B) {   // B -> rojo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 0);
    digitalWrite(VEHICULAR_B_ROJO, 1);
    oldTime_B = time_B;
  }
  else if (time_B - oldTime_B >= T4_B) {   // B -> rojo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 0);
    digitalWrite(VEHICULAR_B_ROJO, 1);

  }
  else if (time_B - oldTime_B >= T3_B) {  // A -> amarillo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_ROJO, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 1);
  }
  else if (time_B - oldTime_B >= T2_B) {  // A -> verde
    digitalWrite(VEHICULAR_B_ROJO, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 0);
    digitalWrite(VEHICULAR_B_VERDE, 1);
  }
  else if (time_B - oldTime_B >= T1_B) {  // A -> rojo y amarillo
    digitalWrite(VEHICULAR_B_VERDE, 0);
    digitalWrite(VEHICULAR_B_AMARILLO, 1);
    digitalWrite(VEHICULAR_B_ROJO, 1);
  }
}
*/

void peatonal_A() {
  static uint32_t parpadeo = time_A;

  if (time_A >= P5_A) {   // A -> verde
    digitalWrite(PEATONAL_A_BLANCO, 0);
    digitalWrite(PEATONAL_A_ROJO, 1);
  }
  else if (time_A >= P4_A) {  // A -> rojo y amarillo
    digitalWrite(PEATONAL_A_BLANCO, 0);
    digitalWrite(PEATONAL_A_ROJO, 1);
    }
  else if (time_A >= P3_A) {  // A -> rojo y amarillo
    digitalWrite(PEATONAL_A_BLANCO, 0);
    if (time_A - parpadeo >= 500UL) {
      digitalWrite(PEATONAL_A_ROJO, !digitalRead(PEATONAL_A_ROJO));
      parpadeo = time_A;
    }
  }
  else if (time_A >= P2_A) {  // A -> rojo
    digitalWrite(PEATONAL_A_BLANCO, 1);
    digitalWrite(PEATONAL_A_ROJO, 0);
  }
  else if (time_A >= P1_A) {  // A -> amarillo
    digitalWrite(PEATONAL_A_BLANCO, 0);
    digitalWrite(PEATONAL_A_ROJO, 1);
  }
}

void peatonal_B() {
  static uint32_t parpadeo = time_B;

  if (time_B >= P5_A) {   // A -> verde
    digitalWrite(PEATONAL_B_BLANCO, 0);
    digitalWrite(PEATONAL_B_ROJO, 1);
  }
  else if (time_B >= P4_A) {  // A -> rojo y amarillo
    digitalWrite(PEATONAL_B_BLANCO, 0);
    digitalWrite(PEATONAL_B_ROJO, 1);
    }
  else if (time_B >= P3_A) {  // A -> rojo y amarillo
    digitalWrite(PEATONAL_B_BLANCO, 0);
    if (time_B - parpadeo >= 500UL) {
      digitalWrite(PEATONAL_B_ROJO, !digitalRead(PEATONAL_B_ROJO));
      parpadeo = time_B;
    }
  }
  else if (time_B >= P2_A) {  // A -> rojo
    digitalWrite(PEATONAL_B_BLANCO, 1);
    digitalWrite(PEATONAL_B_ROJO, 0);
  }
  else if (time_B >= P1_A) {  // A -> amarillo
    digitalWrite(PEATONAL_B_BLANCO, 0);
    digitalWrite(PEATONAL_B_ROJO, 1);
  }
}

void setup() {
//  Serial.begin(9600);
  pinMode(VEHICULAR_A_ROJO, OUTPUT);
  pinMode(VEHICULAR_A_VERDE, OUTPUT);
  pinMode(VEHICULAR_A_AMARILLO, OUTPUT);

  pinMode(VEHICULAR_B_ROJO, OUTPUT);
  pinMode(VEHICULAR_B_VERDE, OUTPUT);
  pinMode(VEHICULAR_B_AMARILLO, OUTPUT);

  pinMode(PEATONAL_A_BLANCO, OUTPUT);
  pinMode(PEATONAL_A_ROJO, OUTPUT);
  pinMode(PEATONAL_B_BLANCO, OUTPUT);
  pinMode(PEATONAL_B_ROJO, OUTPUT);

  pinMode(13, OUTPUT);

  // --- Inicia con semáforo verde ---
  iniciar();
  time_B = T2_A + TIEMPO_ROAM;
}

void loop() {
  time_C = millis();
  time_A = time_A + (time_C - oldTime_A);
  time_B = time_B + (time_C - oldTime_A);
  oldTime_A = time_C;

  semaforo_A();
  semaforo_B();
  peatonal_A();
  peatonal_B();
  delay(10);
}