import type { FunctionalComponent } from 'preact';

import type { AsukaElement } from '../../../types/elements';
import { Accordion } from '../../ui/Accordion';
import { EmptyState } from '../../core';
import { AsukaIcon } from '../../core/AsukaIcon';
import { ElementCard, getElementDisplayName } from './ElementCard';

type ElementCategoryGroup = {
  category: string;
  items: AsukaElement[];
};

const getElementCardKey = (element: any, name: string, index: number, scope: string): string => {
  const candidates = [
    element?.id,
    element?.instanceId,
    element?.productId,
    element?.product?.id,
    element?.product?.instanceId,
    element?.metadata?.instanceId,
    element?.metadata?.productId,
    element?.metadata?.asukaProductId,
  ];
  const stableId = candidates.map((candidate) => String(candidate ?? '').trim()).find(Boolean);
  return `${scope}:${stableId || name || 'element'}:${index}`;
};

type ElementListPanelProps = {
  t: (key: string, fallback?: any) => string;
  uncategorized: AsukaElement[];
  categorized: ElementCategoryGroup[];
  getCount: (element: AsukaElement) => number;
  getStatusLabel?: (element: AsukaElement) => string | undefined;
  getStatusBadge?: (element: AsukaElement) => string | undefined;
  isActiveProduct?: (element: AsukaElement) => boolean;
  canSelectProduct?: (element: AsukaElement) => boolean;
  onSelectProduct?: (element: AsukaElement) => void;
  canEditElementVariations?: boolean;
  canDeleteElements?: boolean;
  onOpen: (element: AsukaElement) => void;
  onEdit: (element: AsukaElement) => void;
  onDelete: (element: AsukaElement) => void;
};

export const ElementListPanel: FunctionalComponent<ElementListPanelProps> = ({
  t,
  uncategorized,
  categorized,
  getCount,
  getStatusLabel,
  getStatusBadge,
  isActiveProduct,
  canSelectProduct,
  onSelectProduct,
  canEditElementVariations,
  canDeleteElements,
  onOpen,
  onEdit,
  onDelete,
}) => {
  const hasItems = uncategorized.length > 0 || categorized.some((group) => group.items.length > 0);

  if (!hasItems) {
    return (
      <EmptyState
        icon={<AsukaIcon name="elements" size={16} />}
        title={t('elements.emptyTitle', 'No elements in this view')}
        description={t('elements.emptyDescription', 'Add an element or copy one from another view to start editing variations.')}
        className="ask-rounded-[18px] ask-bg-surfaceAlt/70 ask-shadow-none"
      />
    );
  }

  const renderElementCard = (element: any, elementIndex: number, scope: string) => {
    const name = getElementDisplayName(element, t('elements.unnamed', 'Element'));
    return (
      <ElementCard
        key={getElementCardKey(element, name, elementIndex, scope)}
        t={t}
        element={element}
        count={getCount(element)}
        statusLabel={getStatusLabel?.(element)}
        statusBadge={getStatusBadge?.(element)}
        isActiveProduct={isActiveProduct?.(element)}
        canSelectProduct={canSelectProduct?.(element)}
        onSelectProduct={onSelectProduct}
        canEdit={canEditElementVariations}
        canDelete={canDeleteElements}
        compact={scope !== 'uncategorized'}
        onOpen={onOpen}
        onEdit={onEdit}
        onDelete={onDelete}
      />
    );
  };

  return (
    <div className="ask-flex ask-flex-col ask-gap-3">
      {uncategorized.length > 0 ? (
        <div className="ask-flex ask-flex-col ask-gap-2">
          {uncategorized.map((element: any, elementIndex: number) => renderElementCard(element, elementIndex, 'uncategorized'))}
        </div>
      ) : null}

      <Accordion
        items={categorized.map((group, groupIndex) => ({
          id: group.category,
          title: group.category,
          right: (
            <span className="ask-inline-flex ask-h-6 ask-min-w-6 ask-items-center ask-justify-center ask-rounded-full ask-bg-primary/8 ask-px-2 ask-text-[10px] ask-font-semibold ask-text-primary">
              {group.items.length}
            </span>
          ),
          defaultOpen: group.items.length > 0 && groupIndex === 0,
          content: (
            <div className="ask-flex ask-flex-col ask-gap-2">
              {group.items.map((element: any, elementIndex: number) => renderElementCard(element, elementIndex, `category:${group.category}`))}
            </div>
          ),
        }))}
      />
    </div>
  );
};
