import { Controller } from '@hotwired/stimulus';
import { useDebounce } from 'stimulus-use';

// language=css
const PIECES_INPUT_SELECTOR = 'input[data-id-product]';

export default class extends Controller {
   static debounces = ['calculateTotal'];
   static targets = ['total', 'rowTotal'];
   static values = {
      productIds: Array,
      useCart: Boolean,
   };

   declare totalTarget: HTMLSpanElement;
   declare rowTotalTargets: HTMLSpanElement[];

   declare productIdsValue: number[];
   declare useCartValue: boolean;

   connect() {
      useDebounce(this);

      this.productIdsValue = this.productIdsValue.map(Number);
      this.calculateTotal();
      this.initialize();
   }

   calculateTotal() {
      // productId => sum of variation pieces in cart
      const piecesMap: Record<number, number> = {};

      const piecesInputElements = Array.from(
         this.element.querySelectorAll(PIECES_INPUT_SELECTOR) as NodeListOf<HTMLInputElement>
      ).filter(input => input.value);

      for (const piecesInput of piecesInputElements) {
         piecesMap[+piecesInput.dataset.idProduct] =
            (piecesMap[+piecesInput.dataset.idProduct] || 0) + piecesInput.valueAsNumber;
      }

      let total = 0;
      for (const rowTotalTarget of this.rowTotalTargets) {
         const productId = +rowTotalTarget.dataset.productId;
         if (!(productId in piecesMap)) {
            rowTotalTarget.innerText = '0';

            continue;
         }

         const rowTotal = piecesMap[productId];

         rowTotalTarget.innerText = rowTotal.toString();
         total += rowTotal;
      }

      this.totalTarget.innerText = total.toString();
   }

   removeFromCart() {
      if (this.useCartValue) {
         const toBeRemoved = wpj.jsShop.cart.get()
            .filter(cartItem => this.productIdsValue.includes(+cartItem.productId))
            .map(({ productId, variationId, note }) => ({
               productId,
               variationId,
               note: typeof note === 'string' ? JSON.parse(note) : note,
            }));

         wpj.jsShop.cart.removeItems(toBeRemoved);

         return;
      }

      const pieceInputs = this.element.querySelectorAll(PIECES_INPUT_SELECTOR);

      for (const input of Array.from(pieceInputs as NodeListOf<HTMLInputElement>)) {
         input.value = '0';
         input.dispatchEvent(new Event('change', { bubbles: true }));
      }
   }

   initialize() {
      const scrollElement = document.querySelectorAll(".variations-wrapper-content");

      scrollElement.forEach((element) => {
            const resizeObserver = new ResizeObserver(() => {
               const isScrollbarActive = element.scrollWidth > element.clientWidth;

               if (isScrollbarActive) {
                  element.classList.add("has-scroll")
               }

               element.addEventListener("scroll", () => {
               const isAtEnd = Math.abs(element.scrollLeft + element.clientWidth - element.scrollWidth) < 1;

               if (isAtEnd) {
                  element.classList.remove("has-scroll")
                  element.classList.add("at-end")
               } else {
                  element.classList.add("has-scroll")
                  element.classList.remove("at-end")
               }
               });
            });
            resizeObserver.observe(element);
         });
   }w
}
