TM1637 in a timer sketch produces strange values after specific time

Hey guys i need some help here. i have been hacking away at a code for a timer countdown posted on the inter webs here is the original code..

#include <avr/sleep.h>

#include <TM1637Display.h>
#include <ClickEncoder.h>
#include <TimerOne.h>

#define SLEEP_INTERRUPT_1 2
#define SLEEP_INTERRUPT_2 3
#define SPEAKER 5
#define LIGHT 6
#define ENCODER_BUTTON 2
#define ENCODER_A 3
#define ENCODER_B 4
#define MAX_SECONDS 10 * 60
#define SLEEP_TIMEOUT 60 * 1000;

#define CLK 12
#define DIO 11

ClickEncoder *encoder;
TM1637Display display(CLK, DIO);

uint8_t data[] = {0, 0, 0, 0};
int16_t last, left, milli, sleepTimer;
bool running, showEnd, lightOn;

void timerIsr() {
  encoder->service();
  if(running) {
    milli -= 1;
  }
  sleepTimer -= 1;
}

void feedSleepTimer() {
  sleepTimer = SLEEP_TIMEOUT;
}

void goToSleep() {
  displayOff();

  Timer1.detachInterrupt();

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT_1), wakeUp, CHANGE);
  attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT_2), wakeUp, CHANGE);
  sleep_mode();
  // Zzzzz. When we wake, we resume here...
  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT_2));
  detachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT_1));

  // Run setup again, so everything is back to the initial state
  setup();
}

void wakeUp() {
  // This happens after we wake up.
  feedSleepTimer();
}

void displayOff() {
  // We may need to turn off the display using hardware...
  display.setBrightness(0, false);
  display.setSegments(data);
}

void displayOn() {
  display.setBrightness(7, true);
  display.setSegments(data);
}

void displayEnd() {
//
//      A
//     ---
//  F |   | B
//     -G-
//  E |   | C
//     ---
//      D
// XGFEDCBA
  data[0] = 0;
  data[1] = 0b01111001;
  data[2] = 0b01010100;
  data[3] = 0b01011110;
}

void displayTime(void) {
  int8_t minutes = left / 60;
  int8_t seconds = left % 60;

  uint8_t dot = (!running || milli < 500) ? 0x80 : 0x0;
    
  data[0] = display.encodeDigit(minutes / 10);
  data[1] = display.encodeDigit(minutes % 10) | dot;
  data[2] = display.encodeDigit(seconds / 10);
  data[3] = display.encodeDigit(seconds % 10);
}

void updateTime(void) {
  if(showEnd) {
    displayEnd();
  } else {  
    displayTime();
  }
  
  display.setSegments(data);
}

void setup() {
  encoder = new ClickEncoder(ENCODER_A, ENCODER_B, ENCODER_BUTTON, 4, HIGH);
  encoder->setAccelerationEnabled(true);
    
  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);

  pinMode(LIGHT, OUTPUT);
  running = false;
  showEnd = false;
  lightOn = false;
  
  left = 0;
  last = 0;
  milli = 1000;
  
  feedSleepTimer();
  displayOn();
  updateTime();
}

void checkButton() {
  ClickEncoder::Button b = encoder->getButton();
  if(b == ClickEncoder::Released) {
    running = !running;
  }
}

void checkLight() {
  if(running && !lightOn) {
    digitalWrite(LIGHT, HIGH);
    lightOn = true;
  } else if(!running && lightOn) {
    digitalWrite(LIGHT, LOW);
    lightOn = false;
  }
}

void done() {
  showEnd = true;
  tone(SPEAKER, 1500, 2000);
}

void loop() {
  checkButton();
  
  left += encoder->getValue();
  
  if(left > MAX_SECONDS) {
    left = MAX_SECONDS;
  }
  
  if(milli <= 0) {
    left--;
    milli = 1000;
  }

  if(left < 0) {
    left = 0;
  }

  // If the timer is running, the display needs to be updated every 500ms, otherwise it only needs updating if the encode value changes.
  if ((running && milli / 500 % 2 == 0) || left != last) {
    if(left != last) {
      last = left;
    }
    
    if(running && left == 0) {
      running = false;
      done();
    } else {
      showEnd = false;
    }
    
    updateTime();
    feedSleepTimer();
  }

  checkLight();

  if(sleepTimer == 0) {
    goToSleep();
  }
}

My plan is to use it for activating a timer to control a ssr, nothing fancy...my first issue was the speed at which the display change the time, since it was written of a max of 10 minutes, the display changed in seconds, but i was planning on using it for hours. So turning the know to reach an hour takes forever....i tried changing the steps in the library Clickencoder. h to to 1 but still was to slow.

void setup() {
  //Serial.begin(9600);
  encoder = new ClickEncoder(ENCODER_A, ENCODER_B, ENCODER_BUTTON, [b]1[/b], HIGH);
  encoder->setAccelerationEnabled(true);

Playing with the values gave me nothing useful, so i hunted down the variable that sets the time it turn out to be "left" which was called on the loop there i multiplied the value times 60 and change my steps in the library to get 1 minute per notch, now were talking full sweep gets me like 45 minutes... nice

void loop() {
   
  Serial.println(left);
  checkButton();
  
  left += (encoder->getValue()) [b]* 60[/b];

That out of the way , i realized that the display only tells time in minutes and seconds, i need it to tell minutes and hours so i played with modules and got it going like this :

void displayTime(void) {
  int8_t seconds = left % 60;
  int8_t minutes = (left - seconds) / 60;
  int8_t minutes2 = minutes % 60;
  int8_t hours = minutes / 60;
  uint8_t dot = (!running || milli < 500) ? 0x80 : 0x0;


  data[0] = display.encodeDigit(hours / 10);
  data[1] = display.encodeDigit(hours % 10) | dot;
  data[2] = display.encodeDigit(minutes2 / 10);
  data[3] = display.encodeDigit(minutes2 % 10);

once done, it seem kind of weird so i decide it to ad a simple if else statement to change the display (If someone has a nicer way of doing this please come forward, cause it seems kind of touch and go there) so i have minutes and seconds as long as minutes is less or equal than 59 and hours and minutes if over..

void displayTime(void) {
  int8_t seconds = left % 60;
  int8_t minutes = (left - seconds) / 60;
  int8_t minutes2 = minutes % 60;
  int8_t hours = minutes / 60;
  uint8_t dot = (!running || milli < 500) ? 0x80 : 0x0;

  if (left >= 3599) {
  data[0] = display.encodeDigit(hours / 10);
  data[1] = display.encodeDigit(hours % 10) | dot;
  data[2] = display.encodeDigit(minutes2 / 10);
  data[3] = display.encodeDigit(minutes2 % 10);}
  else if(left < 3599) {
     data[0] = display.encodeDigit(minutes / 10);
  data[1] = display.encodeDigit(minutes % 10) | dot;
  data[2] = display.encodeDigit(seconds / 10);
  data[3] = display.encodeDigit(seconds % 10);}
  
}

Once that was done, i thought i had it figure it out, it turns that the timer won't go pass 10 minutes, simple fix there was a max second variable at the beginning that need it to be change no biggie

#define MAX_SECONDS 10 * 60 // this is the max for "left"

i change it to 180 that would be 3 hours or 8400 (left value)....the problem is thet when ever the value goes over 2 hours and 7 minutes i get glyphs on the display ...

i started the serial monitor on the "left" variable that handles the encoder value and it wrks fine it goes all the way to it set value pf 8400, but the display as soon as it hits 7679 ,7688 it starts displaying alpha numerica values like "0F:bA" "0E:00" i have tried changing the variable types but int16 seems long enough, tried different libraries for the display and nothing, so its something in the code I'm missing, my knowledge can't get me further. If someone sees something I'm missing i appreciate if you can point me in the right direction