'use client';

import React, { useMemo, useCallback } from 'react';
import { VariantOption, VariantType } from '@akinon/next/types';
import { usePathname, useSearchParams } from 'next/navigation';
import clsx from 'clsx';
import { useRouter, useLocalization } from '@akinon/next/hooks';

type VariantProps = {
  className?: string;
  onChange?: (option: VariantOption) => void;
  preventDefaultClick?: boolean;
} & VariantType;

export const Variant = ({
  attribute_key,
  attribute_name,
  options,
  preventDefaultClick,
  onChange,
  className
}: VariantProps) => {
  const { t } = useLocalization();
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  // This is a workaround for the fact that we can't use the useSearchParams set method because of this is not implemented in next.js yet. So we have to use the URLSearchParams's set method.
  const params = useMemo(
    () => new URLSearchParams(searchParams.toString()),
    [searchParams]
  );

  const hasSelected = useMemo(
    () => options.some((option) => option.is_selected),
    [options]
  );

  const selectedVariant = useMemo(
    () => options.find((option) => option.is_selected),
    [options]
  );

  const handleClick = useCallback(
    (option: VariantOption) => {
      if (onChange) {
        onChange(option);
      }

      if (preventDefaultClick) return;

      params.set(attribute_key, option.value);
      router.push(`${pathname}?${params.toString()}`);
    },
    [onChange, preventDefaultClick, params, attribute_key, pathname, router]
  );

  return (
    <div
      className={clsx('flex flex-col gap-2', className)}
      data-testid={`product-variant-${attribute_name}`}
    >
      <p className="flex gap-2 text-xs leading-4">
        <span>
          {hasSelected
            ? `${t('product.selected')} ${attribute_name}:`
            : attribute_name}
        </span>
        {hasSelected && (
          <span
            className="font-bold"
            data-testid={`product-variant-${attribute_name}-value`}
          >
            {selectedVariant?.value}
          </span>
        )}
      </p>
      <div className="flex gap-3 flex-wrap justify-center">
        {options.map((option, i) => (
          <button
            key={`${i}-${option.value}`}
            className={clsx(
              'h-10 px-4 transition-colors duration-200 text-xs',
              {
                'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground pointer-events-none':
                  option.is_selected,
                'bg-gray-200 hover:bg-gray-400':
                  option.is_selectable && !option.is_selected,
                'border border-gray-300 text-gray-600': !option.is_selectable,
                'cursor-not-allowed':
                  !option.is_selectable && !option.is_selectable_without_stock,
                'border border-dashed border-black bg-white text-gray-600 overflow-hidden relative':
                  !option.is_selectable && option.is_selected
              }
            )}
            onClick={() => handleClick(option)}
          >
            {option.value}
          </button>
        ))}
      </div>
    </div>
  );
};

export default Variant;
