import { tns, TinySliderInstance } from 'tiny-slider';
import { Controller } from '@hotwired/stimulus';

export default class extends Controller<HTMLElement> {
   static targets = ['slider', 'controls'];
   static values = {
      initBreakpoint: Number,
      showControls: Boolean,
      gapBetween: Number,
      speed: Number
   };

   declare readonly sliderTarget: HTMLElement;
   declare readonly controlsTarget: HTMLElement;
   declare readonly hasSliderTarget: boolean;
   declare readonly hasControlsTarget: boolean;
   declare readonly initBreakpointValue: number;
   declare readonly hasInitBreakpointValue: boolean;
   declare readonly showControlsValue: boolean;
   declare readonly gapBetweenValue: number;
   declare readonly speedValue: number;

   private tnsInstance: TinySliderInstance | null = null;
   private mql: MediaQueryList | null = null;

   connect() {
      if (this.hasSliderTarget && this.hasInitBreakpointValue) {
         this.setupMediaQuery();
      } else {
         this.element.classList.add('without-tns');
         this.element.classList.remove('with-tns');
      }
   }

   disconnect() {
      this.destroySlider();
      if (this.mql) {
         this.mql.removeEventListener('change', this.handleMediaChange);
      }
   }

   private setupMediaQuery() {
      this.mql = window.matchMedia(`(min-width: ${this.initBreakpointValue}px)`);
      this.mql.addEventListener('change', this.handleMediaChange);
      this.handleMediaChange(this.mql);
   }

   private handleMediaChange = (e: MediaQueryListEvent | MediaQueryList) => {
      if (e.matches) {
         this.initSlider();

         this.element.classList.remove('without-tns');
         this.element.classList.add('with-tns');
      } else {
         this.destroySlider();

         this.element.classList.add('without-tns');
         this.element.classList.remove('with-tns');
      }
   };

   private initSlider() {
      if (this.tnsInstance || this.sliderTarget.classList.contains('tns-slider')) return;

      this.tnsInstance = tns({
         container: this.sliderTarget,
         nav: false,
         controls: this.showControlsValue,
         controlsContainer: this.hasControlsTarget ? this.controlsTarget : false,
         autoplay: false,
         speed: this.speedValue,
         autoplayButtonOutput: false,
         items: 1,
         autoWidth: true,
         gutter: this.gapBetweenValue,
         loop: false,
      });
   }

   private destroySlider() {
      if (this.tnsInstance) {
         this.tnsInstance.destroy();
         this.tnsInstance = null;
      }
   }
}
