'use strict';
angular.module('beamng.apps')
.directive('shiftLightControl', ['$log', '$timeout', function ($log, $timeout) {
  return {
    template:
      '<object style="width:100%; height:100%;" type="image/svg+xml" data="/ui/modules/apps/SGRTach/SGRTach.svg"></object>',
    replace: true,
    restrict: 'EA',
    scope: true,
    link: function (scope, element, attrs) {
      element.css({transition: 'opacity 0.3s ease'});
      let visible = false;
      let svg;
      let normalOperation = true;
      let needleTimeout;
      let rpmDisplayTimeout;

      scope.targetRPM = parseInt(localStorage.getItem('targetRPM')) || 5000;

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

      function saveTargetRPM() {
        localStorage.setItem('targetRPM', scope.targetRPM);
      }

      element.on('load', function () {
        svg = element[0].contentDocument;

        let needle = svg.getElementById('needle');
        let shiftLightOff = svg.getElementById('shift_light');
        let shiftLightOn = svg.getElementById('shift_light_on');
        let upBtn = svg.getElementById('up_btn');
        let downBtn = svg.getElementById('down_btn');
        let rpmDisplay = svg.getElementById('target_rpm_display');

        if (!needle || !shiftLightOff || !shiftLightOn || !upBtn || !downBtn || !rpmDisplay) return;

        function updateNeedleRotation(currentRPM) {
          if (currentRPM < 50) return;
          const maxRPM = 10000;
          const rotationDegree = (currentRPM / maxRPM) * 270 - 3;
          needle.setAttribute('transform', `rotate(${rotationDegree}, 58, 39)`);
        }

        function updateShiftLight(currentRPM) {
          if (currentRPM >= scope.targetRPM) {
            shiftLightOff.setAttribute('opacity', '0');
            shiftLightOn.setAttribute('opacity', '1');
          } else {
            shiftLightOff.setAttribute('opacity', '1');
            shiftLightOn.setAttribute('opacity', '0');
          }
        }

        function pointNeedleToTargetRPM() {
          const maxRPM = 10000;
          const rotationDegree = (scope.targetRPM / maxRPM) * 270 - 3;
          needle.setAttribute('transform', `rotate(${rotationDegree}, 58, 39)`);

          if (needleTimeout) {
            $timeout.cancel(needleTimeout);
          }

          needleTimeout = $timeout(function () {
            normalOperation = true;
          }, 2000);
        }

        function updateRPMDisplay() {
          rpmDisplay.textContent = scope.targetRPM + ' RPM';
          rpmDisplay.setAttribute('opacity', '1');

          if (rpmDisplayTimeout) {
            $timeout.cancel(rpmDisplayTimeout);
          }

          rpmDisplayTimeout = $timeout(function () {
            rpmDisplay.setAttribute('opacity', '0');
          }, 2000);
        }

        upBtn.addEventListener('mousedown', function (event) {
          scope.$apply(function () {
            const increment = event.button === 2 ? 10 : 100;
            scope.targetRPM = Math.min(9000, scope.targetRPM + increment);
            saveTargetRPM();
            normalOperation = false;
            pointNeedleToTargetRPM();
            updateRPMDisplay();
          });
        });

        downBtn.addEventListener('mousedown', function (event) {
          scope.$apply(function () {
            const decrement = event.button === 2 ? 10 : 100;
            scope.targetRPM = Math.max(0, scope.targetRPM - decrement);
            saveTargetRPM();
            normalOperation = false;
            pointNeedleToTargetRPM();
            updateRPMDisplay();
          });
        });

        scope.$on('streamsUpdate', function (event, streams) {
          if (svg && needle && shiftLightOff && shiftLightOn) {
            let currentRPM = streams.engineInfo[4];
            if (normalOperation) {
              updateNeedleRotation(currentRPM);
            }
            updateShiftLight(currentRPM);
            if (!visible) {
              element[0].style.opacity = 1;
              visible = true;
            }
          }
        });

        rpmDisplay.setAttribute('opacity', '0');
      });

      scope.$on('VehicleChange', function() {
        if (svg && svg.vehicleChanged) svg.vehicleChanged();
      });

      scope.$on('VehicleFocusChanged', function (event, data) {
        if (data.mode === true && svg && svg.vehicleChanged) {
          svg.vehicleChanged();
        }
      });

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