angular.module('gaugesScreen', [])
.controller('GaugesScreenController', function($scope, $window) {
  $scope.data = {
    mphVal: "RyL>PDM",
    gear: "Bork",
    rpm: "Bork",
    coolantTempVal: "Bork",
    boostVal: "Bork", // Add this line to define a placeholder for boost value
  };

  // Define constants for idle and max voltage
  const idleVoltage = 15.9;
  const maxVoltage = 15.3;

  // Define constants for AFR target ranges
  const afrDecelValue = 5.2;
  const afrAccelValue = 6.5;
  const afrIdleValue = 6.9;

  // Define constants for fuel pressure
  const idleFuelPressure = 60;
  const maxRPMIncrease = 10; // Fuel pressure increase based on RPM
  const fuelRandomVariance = 5; // Random fluctuation for fuel pressure

  // Define constants for oil pressure based on temperature
  const coldOilTempF = 70;
  const warmOilTempF = 190;
  const hotOilTempF = 250;
  const coldOilPressure = 104;
  const warmOilPressure = 73;
  const hotOilPressure = 25;
  const coldRPMPressureIncrease = 20; // Additional psi due to RPM when oil is cold
  const warmRPMPressureIncrease = 10; // Additional psi due to RPM when oil is warm
  const lowRPMThreshold = 500; // RPM threshold for pressure to start dropping
  const nearZeroRPMThreshold = 25; // RPM threshold for pressure to hit zero

  // Helper function for random AFR value fluctuation
  function getRandomAFR(baseValue, variance) {
    return (baseValue + (Math.random() * (variance * 2) - variance)).toFixed(1);
  }

  $window.updateData = (data) => {
    // Log all received data to the console
    console.log(JSON.stringify(data, null, 2)); // Updated console log for better readability

    $scope.$evalAsync(function () {
      // Initialize placeholders for display data
      $scope.data.mphVal = "RyL>PDM";
      $scope.data.gear = "Bork";
      $scope.data.rpm = "Bork";
      $scope.data.coolantTempVal = "Bork";
      $scope.data.boostVal = "Bork"; // Initialize boost value with placeholder

      // Gear display logic
      if (data.gear === -1) {
        $scope.data.gear = "R";
      } else if (data.gear === 0) {
        $scope.data.gear = "N";
      } else {
        $scope.data.gear = data.gear;
      }

      // Boost and fuel percentage calculations
      $scope.data.boostVal = data.turboBoost !== undefined ? data.turboBoost.toFixed(1) + " PSI" : "0.0 PSI"; // Set boost value with formatting

      $scope.data.fuelPercentage = Math.floor((data.fuel / 45) * 100) + '%';
      $scope.data.fuelUnit = "%";

      // Set RPM display value
      $scope.data.rpm = data.ripems;

      // Speed and GPS speed conversion to mph
      $scope.data.mphVal = (data.speed * 2.23694).toFixed(0);
      $scope.data.speedUnit = "mph";
      $scope.data.gpsSpeedVal = (data.airspeed * 2.23694).toFixed(0);

      // Oil temperature conversion to Fahrenheit
      let oilTempF = (data.oiltemp * 1.8) + 32;
      $scope.data.oilTempVal = oilTempF.toFixed(0);
      $scope.data.tempUnit = "F";

      // Coolant temperature conversion to Fahrenheit
      let coolantTempF = (data.watertemp * 1.8) + 32;
      $scope.data.coolantTempVal = coolantTempF.toFixed(0);

      // Transmission oil temp calculation based on engine oil temp in Fahrenheit
      const minOilTempF = 180;
      const maxOilTempF = 250;
      const minTransTempF = 135;
      const maxTransTempF = 230;

      let transOilTempF;
      if (oilTempF < minOilTempF) {
        transOilTempF = minTransTempF;
      } else if (oilTempF > maxOilTempF) {
        transOilTempF = maxOilTempF;
      } else {
        transOilTempF = minTransTempF + ((oilTempF - minOilTempF) / (maxOilTempF - minOilTempF)) * (maxTransTempF - minTransTempF);
      }

      $scope.data.transOilTempVal = transOilTempF.toFixed(0);

      // Voltage simulation based on RPM
      let voltage;
      if (data.ripems === 0) {
        voltage = idleVoltage;
      } else if (data.ripems > 0 && data.ripems <= 500) {
        voltage = idleVoltage + (0.4 * (data.ripems / 1000));
      } else if (data.ripems > 500 && data.ripems <= 5000) {
        voltage = 14.3 + ((data.ripems - 500) / 4500 * (maxVoltage - 14.3));
        voltage += (Math.random() * 0.2 - 0.1);
      } else {
        voltage = maxVoltage;
      }

      $scope.data.voltsVal = voltage.toFixed(1); // Display in volts

      // AFR Calculation based on RPM ranges
      if (data.ripems < 500) {
        $scope.data.afrLeftVal = 0;
        $scope.data.afrRightVal = 0;
      } else if (data.ripems >= 4500) {
        $scope.data.afrLeftVal = getRandomAFR(afrAccelValue, 0.1);
        $scope.data.afrRightVal = getRandomAFR(afrAccelValue, 0.1);
      } else if (data.ripems < 1300) {
        $scope.data.afrLeftVal = getRandomAFR(afrIdleValue, 0.1);
        $scope.data.afrRightVal = getRandomAFR(afrIdleValue, 0.1);
      } else {
        $scope.data.afrLeftVal = getRandomAFR(afrDecelValue, 0.1);
        $scope.data.afrRightVal = getRandomAFR(afrDecelValue, 0.1);
      }

      // Fuel Pressure Calculation based on RPM and random variance
      let baseFuelPressure = idleFuelPressure + (Math.random() * fuelRandomVariance * 2 - fuelRandomVariance);
      let rpmFuelPressure = (data.ripems / 10000) * maxRPMIncrease;

      if (data.ripems < lowRPMThreshold) {
        let pressureDropFactor = data.ripems < nearZeroRPMThreshold ? 0 : data.ripems / lowRPMThreshold;
        baseFuelPressure *= pressureDropFactor;
        rpmFuelPressure *= pressureDropFactor;
      }

      let fuelPressure = baseFuelPressure + rpmFuelPressure;
      $scope.data.fuelPressVal = fuelPressure.toFixed(1); // Display in psi

      // Oil Pressure Calculation based on oil temperature, RPM, and random variance
      let oilPressure;
      if (oilTempF <= coldOilTempF) {
        oilPressure = coldOilPressure + (data.ripems / 10000) * coldRPMPressureIncrease;
      } else if (oilTempF >= hotOilTempF) {
        oilPressure = hotOilPressure;
      } else {
        oilPressure = warmOilPressure + ((oilTempF - warmOilTempF) / (hotOilTempF - warmOilTempF)) * (hotOilPressure - warmOilPressure);
        oilPressure += (data.ripems / 10000) * warmRPMPressureIncrease;
      }

      if (data.ripems < lowRPMThreshold) {
        let pressureDropFactor = data.ripems < nearZeroRPMThreshold ? 0 : data.ripems / lowRPMThreshold;
        oilPressure *= pressureDropFactor;
      }

      oilPressure += (Math.random() * 2 - 1); // Random variance ±1
      $scope.data.oilPressVal = oilPressure.toFixed(1); // Display in psi
    });
  };
});
