'use strict';
angular.module('beamng.apps')
.directive('sgrGearindicator', ['$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/SGRGearindicator/SGRGearindicator.svg"></object>
      </div>
    `,
    replace: true,
    restrict: 'EA',
    scope: true,
    link: function (scope, element) {
      element.css({ transition: 'opacity 0.3s ease' });
      let svg;
      let labelText;
      let twoText, stepText;

      function ensureBackgroundColor() {
        const background = svg.getElementById('background');
        if (background) {
          background.setAttribute('fill', '#1c1c1c');
        }
      }

      function initializeLabelText() {
        labelText = svg.getElementById('labelText');
        if (!labelText) {
          labelText = svg.createElementNS('http://www.w3.org/2000/svg', 'text');
          labelText.setAttribute('x', '250');
          labelText.setAttribute('y', '360');
          labelText.setAttribute('fill', 'red');
          labelText.setAttribute('font-size', '32');
          labelText.setAttribute('font-weight', 'bold');
          labelText.setAttribute('text-anchor', 'middle');
          labelText.setAttribute('filter', 'url(#glow)');
          labelText.textContent = '';
          svg.getElementById('background').parentNode.appendChild(labelText);
        }
      }

      function initializeTwoStepText() {
        twoText = svg.querySelector('text[x="370"][y="290"]');
        stepText = svg.querySelector('text[x="370"][y="315"]');
      }

      function updateTwoStepText(isTwoStepActive) {
        if (twoText && stepText) {
          if (isTwoStepActive) {
            twoText.setAttribute('fill', 'red');
            stepText.setAttribute('fill', 'red');
            twoText.setAttribute('filter', 'url(#glow)');
            stepText.setAttribute('filter', 'url(#glow)');
          } else {
            twoText.setAttribute('fill', 'black');
            stepText.setAttribute('fill', 'black');
            twoText.removeAttribute('filter');
            stepText.removeAttribute('filter');
          }
        }
      }

      function getGearDisplay(gear) {
        if (typeof gear === 'number') {
          if (gear === -1) {
            return { number: 'R', label: '' };
          } else if (gear === 0) {
            return { number: 'N', label: '' };
          } else {
            return { number: gear.toString(), label: '' };
          }
        } else if (typeof gear === 'string') {
          const match = gear.match(/^([A-Z]+)(\d*)$/);
          if (match) {
            const prefix = match[1];
            const number = match[2] || '';
            let label = '';

            switch (prefix) {
              case 'M':
                label = 'Manual';
                break;
              case 'S':
                label = 'Sport';
                break;
              case 'P':
                return { number: 'P', label: '' };
              case 'R':
                return { number: 'R', label: '' };
              case 'N':
                return { number: 'N', label: '' };
              case 'D':
                return { number: 'D', label: '' };
              default:
                label = '';
            }
            return { number, label };
          }
        }
        return { number: gear, label: '' };
      }

      function updateLabelText(label) {
        if (labelText) {
          labelText.textContent = label;
        }
      }

      const gearDotMappings = {
        'P': ['a1', 'b1', 'c1', 'd1', 'a2', 'e2', 'a3', 'e3', 'a4', 'b4', 'c4', 'd4', 'a5', 'a6', 'a7'],
        'R': ['a1', 'b1', 'c1', 'd1', 'a2', 'e2', 'a3', 'e3', 'a4', 'b4', 'c4', 'd4', 'a5', 'c5', 'a6', 'd6', 'a7', 'e7'],
        'N': ['a1', 'e1', 'a2', 'e2', 'a3', 'b3', 'e3', 'a4', 'c4', 'e4', 'a5', 'd5', 'e5', 'a6', 'e6', 'a7', 'e7'],
        'D': ['a1', 'b1', 'c1', 'd1', 'a2', 'e2', 'a3', 'e3', 'a4', 'e4', 'a5', 'e5', 'a6', 'e6', 'a7', 'b7', 'c7', 'd7'],
        '1': ['c1', 'b2', 'c2', 'c3', 'c4', 'c5', 'c6', 'a7', 'b7', 'c7', 'd7', 'e7'],
        '2': ['b1', 'c1', 'd1', 'a2', 'e2', 'e3', 'd4', 'c5', 'b6', 'a7', 'b7', 'c7', 'd7', 'e7'],
        '3': ['b1', 'c1', 'd1', 'a2', 'e2', 'e3', 'c4', 'd4', 'e5', 'a6', 'e6', 'b7', 'c7', 'd7'],
        '4': ['e1', 'd2', 'e2', 'c3', 'e3', 'b4', 'e4', 'a5', 'b5', 'c5', 'd5', 'e5', 'e6', 'e7'],
        '5': ['a1', 'b1', 'c1', 'd1', 'e1', 'a2', 'a3', 'a4', 'b4', 'c4', 'd4', 'e5', 'a6', 'e6', 'b7', 'c7', 'd7'],
        '6': ['b1', 'c1', 'd1', 'a2', 'a3', 'a4', 'b4', 'c4', 'd4', 'a5', 'e5', 'a6', 'e6', 'b7', 'c7', 'd7'],
        '7': ['a1', 'b1', 'c1', 'd1', 'e1', 'e2', 'd3', 'c4', 'c5', 'c6', 'c7'],
        '8': ['b1', 'c1', 'd1', 'a2', 'e2', 'a3', 'e3', 'b4', 'c4', 'd4', 'a5', 'e5', 'a6', 'e6', 'b7', 'c7', 'd7'],
        '9': ['b1', 'c1', 'd1', 'a2', 'e2', 'a3', 'e3', 'b4', 'c4', 'd4', 'e4', 'e5', 'e6', 'b7', 'c7', 'e7']
      };

      function lightUpGear(gear) {
        const allDots = svg.querySelectorAll('.gear-dot');
        allDots.forEach(dot => {
          dot.setAttribute('fill', 'black');
        });

        const activeDots = gearDotMappings[gear] || [];
        activeDots.forEach(dotId => {
          const dot = svg.getElementById(dotId);
          if (dot) {
            dot.setAttribute('fill', '#ee5208');
          }
        });
      }

      function updateBlinkers(signal_L, signal_R) {
        const leftBlinker = svg.getElementById('left-blinker');
        const rightBlinker = svg.getElementById('right-blinker');

        const activeColor = '#57fe52';
        const inactiveColor = '#006400';

        if (leftBlinker && rightBlinker) {
          leftBlinker.style.transition = 'fill 0.3s ease, filter 0.3s ease';
          rightBlinker.style.transition = 'fill 0.3s ease, filter 0.3s ease';
        }

        if (leftBlinker) {
          if (signal_L) {
            leftBlinker.setAttribute('fill', activeColor);
            leftBlinker.setAttribute('filter', 'url(#glow)');
          } else {
            leftBlinker.setAttribute('fill', inactiveColor);
            leftBlinker.setAttribute('filter', 'none');
          }
        }

        if (rightBlinker) {
          if (signal_R) {
            rightBlinker.setAttribute('fill', activeColor);
            rightBlinker.setAttribute('filter', 'url(#glow)');
          } else {
            rightBlinker.setAttribute('fill', inactiveColor);
            rightBlinker.setAttribute('filter', 'none');
          }
        }
      }

      function updateHighBeams(lights_state) {
        const semicirclePath = svg.getElementById('high-beams').querySelector('path');
        const horizontalRects = svg.getElementById('high-beams').querySelectorAll('rect');

        if (!semicirclePath || !horizontalRects) return;

        if (lights_state === 2) {
          semicirclePath.setAttribute('stroke', '#034ff3');
          semicirclePath.setAttribute('stroke-width', '3');
          semicirclePath.setAttribute('filter', 'url(#highBeamGlow)');

          horizontalRects.forEach(function (rect) {
            rect.setAttribute('fill', '#034ff3');
            rect.setAttribute('filter', 'url(#highBeamGlow)');
          });
        } else {
          semicirclePath.setAttribute('stroke', 'black');
          semicirclePath.setAttribute('stroke-width', '3');
          semicirclePath.removeAttribute('filter');

          horizontalRects.forEach(function (rect) {
            rect.setAttribute('fill', 'black');
            rect.removeAttribute('filter');
          });
        }
      }

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

          if (!svg) {
            return;
          }

          initializeLabelText();
          initializeTwoStepText();

          scope.$on('streamsUpdate', function (event, data) {
            if (data.electrics && data.electrics.gear !== undefined) {
              const { number, label } = getGearDisplay(data.electrics.gear);
              updateLabelText(label);
              lightUpGear(number);
            }

            if (data.electrics && data.electrics.twoStep !== undefined) {
              const isTwoStepActive = data.electrics.twoStep;
              updateTwoStepText(isTwoStepActive);
            }

            if (data.electrics) {
              const signal_L = data.electrics.signal_L;
              const signal_R = data.electrics.signal_R;
              updateBlinkers(signal_L, signal_R);

              const lights_state = data.electrics.lights_state;
              updateHighBeams(lights_state);
            }
          });
        }, 500);
      });

      scope.$on('$destroy', function () {
        if (svg && svg.getStreams) StreamsManager.remove(svg.getStreams());
      });
    }
  };
}]);
