'use client';

/**
 * ============================================
 * PRODUCT VARIANT SELECTOR
 * ============================================
 * Equivalent to: buy-widget-form.html.twig in Shopware
 *
 * Shopware's /product/{id}/configurator returns PropertyGroup[]
 * where each group has a nested options[] array.
 *
 * Renders:
 *  - Color swatches when displayType === 'color' and colorHexCode exists
 *  - Text buttons for size, material, etc.
 *
 * On selection, calls Shopware's find-variant endpoint
 * and navigates to the matching child product.
 */

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { findProductVariant, PropertyGroup } from '@/lib/shopware-api';

interface ProductVariantSelectorProps {
  /** The parent product ID (used for find-variant API call) */
  parentId: string;
  /** Currently selected option IDs (from product.optionIds) */
  selectedOptionIds: string[];
  /** Configurator groups returned by Shopware — each group contains its options[] */
  elements: PropertyGroup[];
}

export default function ProductVariantSelector({
  parentId,
  selectedOptionIds,
  elements,
}: ProductVariantSelectorProps) {
  const router = useRouter();
  const [isNavigating, setIsNavigating] = useState(false);
  const [error, setError] = useState('');

  // Build the current selection map: { groupId -> optionId }
  const buildSelectionMap = (): Record<string, string> => {
    const map: Record<string, string> = {};
    for (const group of elements) {
      const selected = (group.options || []).find((opt) =>
        selectedOptionIds.includes(opt.id)
      );
      if (selected) {
        map[group.id] = selected.id;
      }
    }
    return map;
  };

  const handleOptionSelect = async (groupId: string, optionId: string) => {
    setError('');
    setIsNavigating(true);

    const currentSelection = buildSelectionMap();
    const newSelection = { ...currentSelection, [groupId]: optionId };

    try {
      const result = await findProductVariant(parentId, newSelection, groupId);
      if (result?.variantId) {
        router.push(`/products/${result.variantId}`);
      }
    } catch (e) {
      console.error('Failed to find variant:', e);
      setError('This combination is not available.');
      setIsNavigating(false);
    }
  };

  // Filter out groups with no options
  const groups = elements.filter((g) => g.options && g.options.length > 0);

  if (groups.length === 0) return null;

  const currentSelection = buildSelectionMap();

  return (
    <div className="space-y-5">
      {isNavigating && (
        <div className="flex items-center gap-2 text-sm text-surface-500">
          <svg className="w-4 h-4 animate-spin" viewBox="0 0 24 24" fill="none">
            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
          </svg>
          Loading variant...
        </div>
      )}

      {error && <p className="text-sm text-red-600">{error}</p>}

      {groups.map((group) => {
        const groupName = group.translated?.name || group.name;
        const selectedId = currentSelection[group.id];
        const sortedOptions = [...(group.options || [])].sort(
          (a, b) => a.position - b.position
        );

        return (
          <div key={group.id}>
            <p className="text-sm font-medium text-surface-700 mb-2">
              {groupName}
              {selectedId && (
                <span className="ml-2 font-normal text-surface-500">
                  —{' '}
                  {sortedOptions.find((o) => o.id === selectedId)?.translated?.name ||
                    sortedOptions.find((o) => o.id === selectedId)?.name}
                </span>
              )}
            </p>

            <div className="flex flex-wrap gap-2">
              {sortedOptions.map((option) => {
                const isSelected = selectedId === option.id;
                const optionName = option.translated?.name || option.name;
                const isColor = group.displayType === 'color' && option.colorHexCode;
                const isImage = group.displayType === 'image' && option.media?.url;

                if (isImage) {
                  const thumb =
                    option.media!.thumbnails?.find((t) => t.width >= 60) ||
                    option.media!.thumbnails?.[0];
                  const imgUrl = thumb?.url || option.media!.url;
                  return (
                    <button
                      key={option.id}
                      onClick={() => handleOptionSelect(group.id, option.id)}
                      disabled={isNavigating}
                      title={optionName}
                      className={`w-14 h-14 rounded-lg border-2 overflow-hidden transition-all disabled:opacity-50 ${
                        isSelected
                          ? 'border-brand-500 ring-2 ring-brand-500/30'
                          : 'border-surface-300 hover:border-surface-500'
                      }`}
                      aria-label={optionName}
                      aria-pressed={isSelected}
                    >
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img
                        src={imgUrl}
                        alt={option.media!.alt || optionName}
                        className="w-full h-full object-cover"
                      />
                    </button>
                  );
                }

                if (isColor) {
                  return (
                    <button
                      key={option.id}
                      onClick={() => handleOptionSelect(group.id, option.id)}
                      disabled={isNavigating}
                      title={optionName}
                      className={`w-9 h-9 rounded-full border-2 transition-all disabled:opacity-50 ${
                        isSelected
                          ? 'border-brand-500 ring-2 ring-brand-500/30 scale-110'
                          : 'border-surface-300 hover:border-surface-500'
                      }`}
                      style={{ backgroundColor: option.colorHexCode! }}
                      aria-label={optionName}
                      aria-pressed={isSelected}
                    />
                  );
                }

                return (
                  <button
                    key={option.id}
                    onClick={() => handleOptionSelect(group.id, option.id)}
                    disabled={isNavigating}
                    className={`px-4 py-2 text-sm font-medium rounded-lg border-2 transition-all disabled:opacity-50 ${
                      isSelected
                        ? 'border-brand-500 bg-brand-50 text-brand-700'
                        : 'border-surface-200 text-surface-700 hover:border-surface-400'
                    }`}
                    aria-pressed={isSelected}
                  >
                    {optionName}
                  </button>
                );
              })}
            </div>
          </div>
        );
      })}
    </div>
  );
}
