'use strict';
angular.module('beamng.apps')
.directive('sgrFuelpress', ['$log', '$timeout', function ($log, $timeout) {
  return {
    template: `
      <div style="width: 100%; height: 100%; position: relative;">
        <object style="width:100%; height:100%;" type="image/svg+xml" data="/ui/modules/apps/SGRFuelpress/SGRFuelpress.svg"></object>
      </div>
    `,
    replace: true,
    restrict: 'EA',
    scope: true,
    link: function (scope, element) {
      element.css({ transition: 'opacity 0.3s ease' });
      let svg;
      let visible = false;
      let currentPressure = 63;
      let lastThrottleTime = 0;
      const dropTime = 0.5;
      const pressureDropDuration = 180;
      let isDropping = false;
      let throttleHeld = false;
      let targetDropPressure = currentPressure;
      let pressureDropStartTime = null;

      var streamsList = ['engineInfo', 'electrics'];
      StreamsManager.add(streamsList);

      element[0].querySelector('object').addEventListener('load', function () {
        $timeout(function () {
          svg = element[0].querySelector('object').contentDocument;

          if (!svg) return;

          let needle = svg.getElementById('needle');
          if (!needle) return;

          function updateFuelGauge(rpm, throttle, fuelLevel) {
            let currentTime = Date.now() / 1000;

            if (rpm > 0 && pressureDropStartTime !== null) {
              pressureDropStartTime = null;
            }

            if (rpm === 0 && pressureDropStartTime === null) {
              pressureDropStartTime = currentTime;
            }

            let targetPressure = calculateFuelPressure(rpm, fuelLevel);

            if (pressureDropStartTime !== null) {
              let elapsed = currentTime - pressureDropStartTime;
              if (elapsed < pressureDropDuration) {
                let dropFactor = 1 - (elapsed / pressureDropDuration);
                targetPressure = currentPressure * dropFactor;
              } else {
                targetPressure = 0;
                currentPressure = 0;
              }
            }

            if (throttle > 0 && !throttleHeld) {
              throttleHeld = true;
              lastThrottleTime = currentTime;
              isDropping = true;
              let pressureDrop = throttle * 8;
              targetDropPressure = Math.max(currentPressure - pressureDrop, 0);
              pressureDropStartTime = null;
            }

            if (isDropping) {
              let elapsed = currentTime - lastThrottleTime;
              if (elapsed < dropTime) {
                currentPressure = smoothTransition(currentPressure, targetDropPressure, 0.1);
              } else {
                isDropping = false;
              }
            }

            if (!isDropping && throttleHeld) {
              currentPressure = smoothTransition(currentPressure, targetPressure, 0.1);
            }

            if (throttle === 0) {
              throttleHeld = false;
              currentPressure = smoothTransition(currentPressure, targetPressure, 0.02);
            }

            let rotationDegree = mapFuelPressureToRotation(currentPressure);
            needle.setAttribute('transform', `rotate(${rotationDegree}, 1, -20)`);
          }

          function calculateFuelPressure(rpm, fuelLevel) {
            const idleRPM = 700;
            const maxRPM = 6000;
            const maxFuelPressure = 75;
            const idleFuelPressure = 63;
            const lowFuelPressure = 10;

            if (fuelLevel === 0) {
              return 0;
            } else if (fuelLevel < 0.05) {
              return Math.max(lowFuelPressure, lowFuelPressure * (fuelLevel / 0.05));
            }

            let pressure = 0;
            if (rpm > 0 && rpm <= idleRPM) {
              pressure = (rpm / idleRPM) * idleFuelPressure;
            } else if (rpm > idleRPM) {
              pressure = idleFuelPressure + ((rpm - idleRPM) / (maxRPM - idleRPM)) * (maxFuelPressure - idleFuelPressure);
            }

            return Math.max(0, Math.min(pressure, maxFuelPressure));
          }

          function smoothTransition(currentValue, targetValue, smoothFactor) {
            return currentValue + (targetValue - currentValue) * smoothFactor;
          }

          function mapFuelPressureToRotation(pressure) {
            const minRotation = -287;
            const maxRotation = -15;
            return minRotation + (pressure / 100) * (maxRotation - minRotation);
          }

          scope.$on('streamsUpdate', function (event, streams) {
            if (svg && needle) {
              let rpm = streams.electrics.rpm || 0;
              let throttle = streams.electrics.throttle || 0;
              let fuelLevel = (streams.engineInfo[11] / streams.engineInfo[12]) || 1;

              updateFuelGauge(rpm, throttle, fuelLevel);

              if (!visible) {
                element[0].querySelector('object').style.opacity = 1;
                visible = true;
              }
            }
          });

          scope.$on('$destroy', function () {
            StreamsManager.remove(streamsList);
          });
        }, 500);
      });
    }
  };
}]);
