/**
 * Repeatable Field Group Component
 *
 * Renders a group of fields that can be dynamically added/removed.
 * Each item in the group follows a schema template.
 */

import { memo } from 'react';
import { Plus, Trash2 } from 'lucide-react';
import { Button } from '../ui/button';
import { Card } from '../ui/card';
import { Label } from '../ui/label';
import { ActionField, Action } from '../../types/action';
import { AvailableContext } from '../../hooks/useAvailableContext';
import { QueueFetchHandler } from '../../types/schema';
import { SchemaFieldRenderer } from './SchemaFieldRenderer';

interface RepeatableFieldGroupProps {
  fieldName: string;
  field: ActionField;
  value: Record<string, unknown>[];
  onChange: (value: Record<string, unknown>[]) => void;
  availableContext: AvailableContext;
  error?: string;
  // Pass through dynamic options state for nested fields
  dynamicOptions: Record<string, unknown[]>;
  loadingDynamicFields: Record<string, boolean>;
  dynamicFieldErrors: Record<string, string>;
  onQueueFetch: QueueFetchHandler;
  actionConfig: Record<string, unknown>;
  currentAction?: Action;
}

export const RepeatableFieldGroup = memo(function RepeatableFieldGroup({
  fieldName,
  field,
  value,
  onChange,
  availableContext,
  error,
  dynamicOptions,
  loadingDynamicFields,
  dynamicFieldErrors,
  onQueueFetch,
  actionConfig,
  currentAction,
}: RepeatableFieldGroupProps) {
  const itemSchema = field.item_schema || {};
  const repeatableConfig = field.repeatable || {};
  const minItems = repeatableConfig.min ?? 0;
  const maxItems = repeatableConfig.max ?? 0; // 0 = unlimited
  const addLabel = repeatableConfig.add_label ?? 'Add Item';
  const removeLabel = repeatableConfig.remove_label ?? 'Remove';

  const items = value || [];
  const canAdd = maxItems === 0 || items.length < maxItems;
  const canRemove = items.length > minItems;

  // Create a new empty item based on the schema
  const createEmptyItem = (): Record<string, unknown> => {
    const emptyItem: Record<string, unknown> = {};
    for (const [key, fieldDef] of Object.entries(itemSchema)) {
      if (fieldDef.default !== undefined) {
        emptyItem[key] = fieldDef.default;
      } else {
        emptyItem[key] = '';
      }
    }
    return emptyItem;
  };

  const handleAddItem = () => {
    if (!canAdd) return;
    const newItems = [...items, createEmptyItem()];
    onChange(newItems);
  };

  const handleRemoveItem = (index: number) => {
    if (!canRemove) return;
    const newItems = items.filter((_, i) => i !== index);
    onChange(newItems);
  };

  const handleItemChange = (index: number, itemFieldName: string, itemValue: unknown) => {
    const newItems = items.map((item, i) => {
      if (i === index) {
        return { ...item, [itemFieldName]: itemValue };
      }
      return item;
    });
    onChange(newItems);
  };

  // Sort fields by order
  const sortedFields = Object.entries(itemSchema).sort(([, a], [, b]) => {
    const orderA = a.order ?? 999;
    const orderB = b.order ?? 999;
    return orderA - orderB;
  });

  return (
    <div className="space-y-3">
      <Label>{field.label}</Label>
      {field.description && <p className="text-sm text-muted-foreground">{field.description}</p>}

      {items.length === 0 && (
        <p className="text-sm text-muted-foreground italic">
          No items yet. Click "{addLabel}" to add one.
        </p>
      )}

      <div className="space-y-3">
        {items.map((item, index) => (
          <Card key={index} className="p-4">
            <div className="flex items-start justify-between gap-4">
              <div className="flex-1 space-y-4">
                {sortedFields.map(([itemFieldName, itemField]) => {
                  // Skip hidden fields
                  if (itemField.hidden) return null;

                  // Create a unique field name for nested fields
                  const nestedFieldName = `${fieldName}[${index}].${itemFieldName}`;

                  return (
                    <SchemaFieldRenderer
                      key={nestedFieldName}
                      fieldName={nestedFieldName}
                      field={itemField}
                      value={item[itemFieldName]}
                      onChange={(_, val) => handleItemChange(index, itemFieldName, val)}
                      availableContext={availableContext}
                      dynamicOptions={dynamicOptions}
                      loadingDynamicFields={loadingDynamicFields}
                      dynamicFieldErrors={dynamicFieldErrors}
                      onQueueFetch={onQueueFetch}
                      actionConfig={{ ...actionConfig, ...item }}
                      currentAction={currentAction}
                    />
                  );
                })}
              </div>
              {canRemove && (
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  onClick={() => handleRemoveItem(index)}
                  className="shrink-0 text-destructive hover:text-destructive hover:bg-destructive/10"
                  title={removeLabel}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              )}
            </div>
          </Card>
        ))}
      </div>

      {canAdd && (
        <Button type="button" variant="outline" size="sm" onClick={handleAddItem} className="mt-2">
          <Plus className="h-4 w-4 mr-2" />
          {addLabel}
        </Button>
      )}

      {error && <p className="text-sm text-destructive">{error}</p>}
    </div>
  );
});
