/*
 * @Author: ZhaoYing 
 * @Date: 2026-02-03 15:40:13 
 * @Last Modified by: ZhaoYing
 * @Last Modified time: 2026-03-25 16:54:44
 */
import { type FC } from 'react'
import clsx from 'clsx';
import { Select, type SelectProps, Flex, Space } from 'antd'

import type { Suggestion } from '../Editor/plugin/AutocompletePlugin'
type LabelRender = SelectProps['labelRender'];

/**
 * Props for VariableSelect component
 */
interface VariableSelectProps extends SelectProps {
  /** Available variable options */
  options: Suggestion[];
  /** Current selected value */
  value?: string;
  /** Whether to show clear button */
  allowClear?: boolean;
  /** Filter out boolean type variables */
  filterBooleanType?: boolean;
  /** Size of the select component */
  size?: 'small' | 'middle' | 'large'
}

/**
 * VariableSelect component
 * Custom select component for workflow variables with grouped options and custom rendering
 * @param props - Component props
 */
const VariableSelect: FC<VariableSelectProps> = ({
  placeholder,
  options,
  value,
  allowClear = true,
  onChange,
  size = 'middle',
  filterBooleanType = false,
  mode,
  ...resetPorps
}) => {

  /**
   * Handle value change and pass selected option to parent
   * @param value - Selected value
   */
  const handleChange: SelectProps['onChange'] = (value: string) => {
    const filterItem = options.find(option => `{{${option.value}}}` === value)
    onChange?.(value, filterItem);
  }
  /**
   * Custom label renderer for selected value
   * Displays node icon, name and variable label
   * @param props - Label render props
   */
  const labelRender: LabelRender = (props) => {
    const { value } = props
    const filterOption = filteredOptions.find(vo => `{{${vo.value}}}` === value)

    if (filterOption) {
      return (
        <span
          className={clsx("rb:max-w-full rb:wrap-break-word rb:line-clamp-1 rb:rounded-md rb:bg-white rb:text-[12px] rb:inline-flex rb:items-center rb:px-1.5 rb:cursor-pointer", {
            'rb:leading-5.5!': size !== 'small',
            'rb:leading-4! rb:text-[10px]!': size === 'small',
            'rb-border': mode !== "multiple"
          })}
          contentEditable={false}
        >
          {filterOption.nodeData?.icon && filterOption.nodeData?.name && (
            <>
              <img
                src={filterOption.nodeData.icon}
                style={{ width: '12px', height: '12px', marginRight: '4px' }}
                alt=""
              />
              {filterOption.nodeData.name}
              <span className="rb:text-[#DFE4ED] rb:mx-0.5">/</span>
            </>
          )}
          <span className="rb:text-[#171719]">{filterOption.label}</span>
        </span>
      )
    }
    return null
  }
  // Filter options based on boolean type if needed
  const filteredOptions = filterBooleanType 
    ? options.filter(option => option.dataType !== 'boolean')
    : options;

  /**
   * Group suggestions by node ID
   */
  const groupedSuggestions = filteredOptions.reduce((groups: Record<string, any[]>, suggestion) => {
    const { nodeData } = suggestion
    const nodeId = nodeData.id as string;
    if (!groups[nodeId]) {
      groups[nodeId] = [];
    }
    groups[nodeId].push(suggestion);
    return groups;
  }, {});

  /**
   * Format grouped options for Select component
   */
  const groupedOptions = Object.entries(groupedSuggestions).map(([_nodeId, suggestions]) => ({
    label: <Flex align="center" gap={4}>
      {suggestions[0].nodeData.icon && <img
        src={suggestions[0].nodeData.icon}
        className="rb:size-3"
        alt=""
      />}
      {suggestions[0].nodeData.name}
    </Flex>,
    options: suggestions.map(s => ({ 
      label: <Flex align="center" justify="space-between" gap={4}>
        <Space size={8}>
          <span className="rb:text-[#155EEF]">{`{x}`}</span>
          {s.label}
        </Space>
        <span className="rb:text-[#5B6167]">{s.dataType}</span>
      </Flex>, 
      value: `{{${s.value}}}` 
    }))
  }));
  
  return (
    <Select
      {...resetPorps}
      mode={mode}
      size={size}
      placeholder={placeholder}
      value={value}
      style={{ width: '100%' }}
      options={groupedOptions}
      labelRender={labelRender}
      onChange={handleChange}
      showSearch
      allowClear={allowClear}
      optionFilterProp="value"
      filterOption={(input, option) => {
        if (input === '/') return true;
        const value = 'value' in option! ? option.value as string : '';
        return value.toLowerCase().includes(input.toLowerCase());
      }}
    />
  )
}

export default VariableSelect
