import { useEffect, useRef } from 'react';
/**
 * Form — B端表单组合组件 (Tailwind 内联)
 *
 * Form 只负责字段标题、说明、错误反馈、top/left 布局与字段编排。
 * 平台已有的表单控件必须复用：Input / TextArea / InputNumber / Select / Checkbox / Radio / Switch / DatePicker / Slider / Upload。
 *
 * @prop {Array} [items=null] — 字段配置列表；为空时使用内置示例字段
 * @prop {'vertical'|'grid'} [layout='vertical'] — 字段排列方式
 * @prop {'top'|'left'} [labelPosition='top'] — 默认标签位置；单项可覆盖
 * @prop {'sm'|'md'} [size='md'] — 传给可复用控件的尺寸
 * @prop {number} [columns=1] — grid 布局列数
 * @prop {number|string} [labelWidth=96] — left 布局下左侧标题列宽度
 * @prop {boolean} [disabled=false] — 是否禁用整个表单
 * @prop {boolean} [requiredMark=true] — required 字段是否显示红色星号
 * @prop {boolean} [labelOptional=false] — 默认标题是否显示“（可选）”
 * @prop {boolean} [labelRequired=false] — 默认标题是否显示红色星号
 * @prop {boolean} [labelAi=false] — 默认标题是否显示 AI 标签
 * @prop {boolean} [labelHelp=false] — 默认标题是否显示 Help 图标
 * @prop {boolean} [debugLayout=false] — 是否打印 left 布局对齐调试日志
 * @prop {string} [debugName='Form'] — 调试日志名称
 * @prop {string} [className=''] — 额外类名
 */

import { AlertCircle, HelpCircle } from 'lucide-react';
import Input from './Input';
import TextArea from './TextArea';
import InputNumber from './InputNumber';
import Select from './Select';
import CheckboxGroup, { Checkbox } from './Checkbox';
import RadioGroup, { Radio } from './Radio';
import Switch from './Switch';
import Slider from './Slider';
import Upload from './Upload';
import DatePicker from './DatePicker';
import TimePicker from './TimePicker';
import TagInput from './TagInput';
import Tag from './Tag';

export const FORM_FIELD_TYPES = [
  'input',
  'input-number',
  'textarea',
  'select',
  'checkbox',
  'radio',
  'switch',
  'date-picker',
  'time-picker',
  'slider',
  'upload',
  'input-group',
  'tag-input',
];

const FORM_SAMPLE_IMAGE = `data:image/svg+xml;utf8,${encodeURIComponent(
  "<svg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 96 96'><defs><linearGradient id='g' x1='0' y1='0' x2='1' y2='1'><stop offset='0%' stop-color='#2B90D9'/><stop offset='100%' stop-color='#0A355A'/></linearGradient></defs><rect width='96' height='96' fill='url(#g)'/><circle cx='72' cy='24' r='10' fill='rgba(255,255,255,0.28)'/><path d='M0 66C13 52 25 49 38 56C50 62 59 60 69 51C76 45 85 43 96 45V96H0Z' fill='rgba(255,255,255,0.24)'/></svg>"
)}`;

export const FORM_SAMPLE_ITEMS = [
  { id: 'name', label: '字段标题', type: 'input', placeholder: '请输入' },
  { id: 'amount', label: '字段标题', type: 'input-number', placeholder: '请输入' },
  { id: 'desc', label: '字段标题', type: 'textarea', placeholder: '请输入', showCount: true, maxLength: 140 },
  { id: 'region', label: '字段标题', type: 'select', placeholder: '请选择' },
  { id: 'checks', label: '字段标题', type: 'checkbox', defaultValue: ['a'] },
  { id: 'radios', label: '字段标题', type: 'radio', defaultValue: 'a' },
  { id: 'enabled', label: '字段标题', type: 'switch' },
  { id: 'date', label: '字段标题', type: 'date-picker' },
  { id: 'time', label: '字段标题', type: 'time-picker' },
  { id: 'range', label: '字段标题', type: 'slider', defaultValue: 24 },
  {
    id: 'cover',
    label: '字段标题',
    type: 'upload',
    defaultValue: [{ uid: 'cover', name: 'cover.png', url: FORM_SAMPLE_IMAGE, status: 'done' }],
  },
  { id: 'combined', label: '字段标题', type: 'input-group' },
  { id: 'tag', label: '字段标题', type: 'tag-input', defaultValue: ['标签', '标签', '标签', '标签', '标签'] },
];

const DEFAULT_SELECT_OPTIONS = [
  { value: 'a', label: '选项 A' },
  { value: 'b', label: '选项 B' },
  { value: 'c', label: '选项 C' },
];

const DEFAULT_INLINE_OPTIONS = [
  { value: 'a', label: '选项标题' },
  { value: 'b', label: '选项标题' },
];

/* ── 表单布局 → 字段排列 ── */
const FORM_LAYOUT_CLASS = {
  vertical: 'flex w-full min-w-0 flex-col items-stretch gap-6',
  grid: 'grid w-full min-w-0 items-start gap-x-[152px] gap-y-[126px]',
};

/* ── 标签位置 → 单字段结构 ── */
const FIELD_POSITION_CLASS = {
  top: 'flex w-full min-w-0 max-w-full flex-col items-start gap-1 self-stretch',
  left: 'flex w-full min-w-0 max-w-full items-start gap-6 self-stretch',
};

/* ── 左侧标签列 / 右侧内容区 ── */
const LABEL_COLUMN = 'flex h-[36px] shrink-0 items-center';
const FIELD_BODY_CLASS = {
  top: 'flex w-full min-w-0 flex-col items-stretch gap-1',
  left: 'flex w-full min-w-0 flex-1 flex-col items-stretch gap-1',
};
const LEFT_CONTROL_ROW = 'flex min-h-[36px] w-full items-center';

/* ── 文本元素 ── */
const LABEL_TEXT = 'text-sm [font-weight:var(--font-semibold)] leading-5 text-foreground-secondary';
const REQUIRED_MARK = 'text-sm [font-weight:var(--font-semibold)] leading-5 text-red-500';
const HELP_TEXT = 'text-sm leading-5 text-foreground-muted';
const ERROR_TEXT = 'text-sm leading-5 text-red-500';
const LABEL_OPTIONAL_TEXT = 'text-sm [font-weight:var(--font-semibold)] leading-5 text-foreground-muted';
const LABEL_HELP_ICON = 'shrink-0 text-foreground-muted';

/* ── 表单控件宽度适配 ── */
const CONTROL_FULL = '!w-full';
const COMPACT_INLINE = 'inline-flex items-center gap-4 py-[6px]';

function normalizeItems(items) {
  return Array.isArray(items) && items.length > 0 ? items : FORM_SAMPLE_ITEMS;
}

function getStatus(item) {
  if (item.status === 'error' || item.error) return 'error';
  return 'default';
}

function renderRequired(required) {
  if (!required) return null;
  return <span className={REQUIRED_MARK}>*</span>;
}

function renderLabelDecorations(item, defaults = {}) {
  const labelRequired = item.labelRequired ?? defaults.labelRequired ?? false;
  const labelAi = item.labelAi ?? defaults.labelAi ?? false;
  const labelHelp = item.labelHelp ?? defaults.labelHelp ?? false;
  const decorations = [];

  if (labelRequired) decorations.push(renderRequired(true));

  if (labelAi) {
    decorations.push(
      <Tag
        key="ai"
        variant="ai"
        size="m"
        radius="full"
        fontWeight="bold"
        className="shrink-0"
      >
        AI
      </Tag>
    );
  }

  if (labelHelp) {
    decorations.push(
      <HelpCircle
        key="help"
        size={16}
        strokeWidth={1.8}
        aria-hidden="true"
        className={LABEL_HELP_ICON}
      />
    );
  }

  return decorations;
}

function renderFeedback(item, { helpId, errorId } = {}) {
  if (item.error) {
    return (
      <div className="flex w-full items-start gap-1 text-red-500">
        <span className="flex h-5 shrink-0 items-center">
          <AlertCircle size={16} strokeWidth={1.8} />
        </span>
        <p id={errorId} className={ERROR_TEXT}>{item.errorText || '该项目为必填项'}</p>
      </div>
    );
  }

  if (!item.helpText) return null;
  return <p id={helpId} className={HELP_TEXT}>{item.helpText}</p>;
}

function InputGroupField({ item, disabled, status, size }) {
  return (
    <div className="flex w-full items-center">
      <Select
        id={`${item.id || 'input-group'}-select`}
        size={size}
        status={status}
        disabled={disabled}
        placeholder="请选择"
        options={item.selectOptions || DEFAULT_SELECT_OPTIONS}
        defaultValue={item.selectDefaultValue}
        className="!w-[116px] rounded-r-none"
      />
      <Input
        id={item.id}
        size={size}
        status={status}
        disabled={disabled}
        placeholder={item.placeholder || '请输入'}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        className="-ml-px w-full [&>div]:rounded-l-none"
      />
    </div>
  );
}

function renderControl(item, {
  disabled,
  size,
  labelledBy,
  describedBy,
}) {
  const type = item.type || 'input';
  const status = getStatus(item);
  const commonDisabled = disabled || item.disabled;

  if (item.control) return item.control;

  if (type === 'input-number') {
    return (
      <InputNumber
        id={item.id}
        size={size}
        status={status}
        disabled={commonDisabled}
        innerButtons={item.innerButtons}
        controls={item.controls !== false}
        min={item.min}
        max={item.max}
        step={item.step}
        precision={item.precision}
        placeholder={item.placeholder || '请输入'}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        onStep={item.onStep}
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'textarea') {
    const hasMaxLimit = typeof item.maxLength === 'number';
    const showCountResolved = item.showCount === false
      ? false
      : item.showCount === true
        ? true
        : hasMaxLimit;
    return (
      <TextArea
        id={item.id}
        variant={item.variant === 'code' ? 'code' : 'default'}
        minRows={item.minRows ?? 3}
        status={status}
        disabled={commonDisabled}
        placeholder={item.placeholder || '请输入'}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        aiSuggestion={item.aiSuggestion}
        aiSuggestions={item.aiSuggestions}
        onAdoptSuggestion={item.onAdoptSuggestion}
        onRefreshAiSuggestions={item.onRefreshAiSuggestions}
        {...(hasMaxLimit ? { maxLength: item.maxLength } : {})}
        showCount={showCountResolved}
        enforceMaxLength={item.enforceMaxLength !== false}
        resize={item.resize === 'none' ? 'none' : 'vertical'}
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'tag-input') {
    return (
      <TagInput
        id={item.id}
        size={size}
        status={status}
        disabled={commonDisabled}
        placeholder={item.placeholder || '请输入'}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        onRemove={item.onRemove}
        aiSuggestion={item.aiSuggestion}
        aiSuggestions={item.aiSuggestions}
        onAdoptSuggestion={item.onAdoptSuggestion}
        onRefreshAiSuggestions={item.onRefreshAiSuggestions}
        closable={item.closable !== false}
        tagVariant="grey"
        tagSize="m"
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'select') {
    return (
      <Select
        id={item.id}
        size={size}
        status={status}
        disabled={commonDisabled}
        placeholder={item.placeholder || '请选择'}
        options={item.options || DEFAULT_SELECT_OPTIONS}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        allowClear={item.allowClear}
        aiSuggestion={item.aiSuggestion}
        aiSuggestions={item.aiSuggestions}
        onAdoptSuggestion={item.onAdoptSuggestion}
        onRefreshAiSuggestions={item.onRefreshAiSuggestions}
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'checkbox') {
    return (
      <div className={COMPACT_INLINE}>
        <CheckboxGroup
          variant={item.variant || 'brand'}
          size={size}
          layout={item.layout || 'horizontal'}
          disabled={commonDisabled}
          value={item.value}
          defaultValue={item.defaultValue}
          onChange={item.onChange}
        >
          {(item.options || DEFAULT_INLINE_OPTIONS).map((option) => (
            <Checkbox key={option.value} value={option.value} disabled={option.disabled}>
              {option.label}
            </Checkbox>
          ))}
        </CheckboxGroup>
      </div>
    );
  }

  if (type === 'radio') {
    return (
      <div className={COMPACT_INLINE}>
        <RadioGroup
          variant={item.variant || 'brand'}
          size={size}
          layout={item.layout || 'horizontal'}
          disabled={commonDisabled}
          value={item.value}
          defaultValue={item.defaultValue}
          onChange={item.onChange}
        >
          {(item.options || DEFAULT_INLINE_OPTIONS).map((option) => (
            <Radio key={option.value} value={option.value} disabled={option.disabled}>
              {option.label}
            </Radio>
          ))}
        </RadioGroup>
      </div>
    );
  }

  if (type === 'switch') {
    return (
      <div className="flex h-[36px] items-center">
        <Switch
          variant={item.variant || 'black'}
          disabled={commonDisabled}
          checked={item.value}
          defaultChecked={item.defaultChecked}
          onChange={item.onChange}
        />
      </div>
    );
  }

  if (type === 'date-picker') {
    return (
      <DatePicker
        id={item.id}
        type={item.pickerType || 'date'}
        disabled={commonDisabled}
        placeholder={item.placeholder}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'time-picker') {
    return (
      <TimePicker
        id={item.id}
        type={item.pickerType || 'time'}
        disabled={commonDisabled}
        placeholder={item.placeholder}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
        className={CONTROL_FULL}
      />
    );
  }

  if (type === 'slider') {
    return (
      <div className="flex h-[36px] w-full items-center">
        <Slider
          id={item.id}
          min={item.min}
          max={item.max}
          step={item.step}
          marks={item.marks}
          disabled={commonDisabled}
          value={item.value}
          defaultValue={item.defaultValue}
          onChange={item.onChange}
          onAfterChange={item.onAfterChange}
          showTooltip={item.showTooltip}
          ariaLabel={item.ariaLabel}
          ariaLabelStart={item.ariaLabelStart}
          ariaLabelEnd={item.ariaLabelEnd}
          ariaLabelledBy={labelledBy}
          ariaDescribedBy={describedBy}
          className={CONTROL_FULL}
        />
      </div>
    );
  }

  if (type === 'upload') {
    return (
      <Upload
        disabled={commonDisabled}
        limit={item.limit || 3}
        value={item.value}
        defaultValue={item.defaultValue}
        onChange={item.onChange}
      />
    );
  }

  if (type === 'input-group') {
    return <InputGroupField item={item} disabled={commonDisabled} status={status} size={size} />;
  }

  return (
    <Input
      id={item.id}
      size={size}
      status={status}
      disabled={commonDisabled}
      placeholder={item.placeholder || '请输入'}
      value={item.value}
      defaultValue={item.defaultValue}
      onChange={item.onChange}
      prefix={item.prefix}
      suffix={item.suffix}
      allowClear={item.allowClear}
      aiSuggestion={item.aiSuggestion}
      aiSuggestions={item.aiSuggestions}
      onAdoptSuggestion={item.onAdoptSuggestion}
      onRefreshAiSuggestions={item.onRefreshAiSuggestions}
      className={CONTROL_FULL}
    />
  );
}

export function FormField({
  item,
  labelPosition = 'top',
  size = 'md',
  labelWidth = 96,
  disabled = false,
  requiredMark = true,
  labelOptional = false,
  labelRequired = false,
  labelAi = false,
  labelHelp = false,
  debugLayout = false,
  debugName = 'Form',
}) {
  const position = item.labelPosition || labelPosition;
  const resolvedLabelWidth = item.labelWidth ?? labelWidth;
  const fieldContainerClassName = item.fullWidth
    ? 'flex w-full min-w-0 max-w-full flex-col items-start gap-1 self-stretch'
    : (FIELD_POSITION_CLASS[position] || FIELD_POSITION_CLASS.top);
  const fieldBodyClassName = item.fullWidth
    ? 'flex w-full min-w-0 flex-col items-stretch gap-1'
    : (FIELD_BODY_CLASS[position] || FIELD_BODY_CLASS.top);
  const fieldId = item.id || item.name || item.label || 'form-field';
  const labelId = `${fieldId}-label`;
  const middleHelpId = item.middleHelpText ? `${fieldId}-middle-help` : undefined;
  const helpId = item.helpText && !item.error ? `${fieldId}-help` : undefined;
  const errorId = item.error ? `${fieldId}-error` : undefined;
  const describedBy = [middleHelpId, helpId, errorId].filter(Boolean).join(' ') || undefined;
  const isSliderField = item.type === 'slider';
  const showLabelOptional = item.labelOptional ?? labelOptional ?? false;
  const effectiveLabelRequired = requiredMark && (item.labelRequired ?? labelRequired ?? false);
  const shouldDebugLayout = (item.debugLayout ?? debugLayout) && position === 'left';
  const labelMeasureRef = useRef(null);
  const controlMeasureRef = useRef(null);
  const labelNode = item.label !== false ? (
    <label
      id={labelId}
      htmlFor={isSliderField ? undefined : fieldId}
      className="flex min-w-0 flex-wrap items-center gap-[2px]"
    >
      <span className="inline-flex min-w-0 shrink-0 items-center gap-[2px] whitespace-nowrap">
        <span className={LABEL_TEXT}>{item.label || '字段标题'}</span>
        {showLabelOptional ? (
          <span className={LABEL_OPTIONAL_TEXT}>（可选）</span>
        ) : null}
      </span>
      {renderLabelDecorations(item, {
        labelOptional,
        labelRequired: effectiveLabelRequired,
        labelAi,
        labelHelp,
      })}
    </label>
  ) : null;

  useEffect(() => {
    if (!shouldDebugLayout || !labelMeasureRef.current || !controlMeasureRef.current) return undefined;

    const debugFieldName = item.debugName || item.label || item.id || 'FormField';
    const frameId = window.requestAnimationFrame(() => {
      const labelRect = labelMeasureRef.current?.getBoundingClientRect();
      const controlRect = controlMeasureRef.current?.getBoundingClientRect();
      if (!labelRect || !controlRect) return;

      const labelCenter = labelRect.top + labelRect.height / 2;
      const controlCenter = controlRect.top + controlRect.height / 2;
      const centerOffset = Number((labelCenter - controlCenter).toFixed(2));
      const payload = {
        form: debugName,
        field: debugFieldName,
        labelWidth: resolvedLabelWidth,
        labelHeight: Number(labelRect.height.toFixed(2)),
        controlHeight: Number(controlRect.height.toFixed(2)),
        centerOffset,
      };

      console.info('[FormLayout] measured', payload);

      if (Math.abs(centerOffset) <= 1) {
        console.info('[FormLayout] aligned', payload);
      } else {
        console.warn('[FormLayout] misaligned', payload);
      }
    });

    return () => window.cancelAnimationFrame(frameId);
  }, [
    debugName,
    item.debugLayout,
    item.debugName,
    item.error,
    item.helpText,
    item.id,
    item.label,
    item.middleHelpText,
    item.type,
    item.value,
    position,
    resolvedLabelWidth,
    shouldDebugLayout,
  ]);

  const fieldBody = (
    <div className={fieldBodyClassName}>
      {item.middleHelpText ? <p id={middleHelpId} className={HELP_TEXT}>{item.middleHelpText}</p> : null}
      <div ref={position === 'left' ? controlMeasureRef : undefined} className={position === 'left' ? LEFT_CONTROL_ROW : undefined}>
        {renderControl(item, {
          disabled,
          size,
          labelledBy: labelNode ? labelId : undefined,
          describedBy,
        })}
      </div>
      {renderFeedback(item, { helpId, errorId })}
    </div>
  );

  if (position === 'left') {
    return (
      <div className={fieldContainerClassName}>
        <div
          ref={labelMeasureRef}
          className={LABEL_COLUMN}
          style={{ width: typeof resolvedLabelWidth === 'number' ? `${resolvedLabelWidth}px` : resolvedLabelWidth }}
        >
          {labelNode}
        </div>
        {fieldBody}
      </div>
    );
  }

  return (
    <div className={fieldContainerClassName}>
      {labelNode}
      {fieldBody}
    </div>
  );
}

export default function Form({
  items = null,
  layout = 'vertical',
  labelPosition = 'top',
  size = 'md',
  columns = 1,
  labelWidth = 96,
  disabled = false,
  requiredMark = true,
  labelOptional = false,
  labelRequired = false,
  labelAi = false,
  labelHelp = false,
  debugLayout = false,
  debugName = 'Form',
  className = '',
  children,
  style,
  ...rest
}) {
  const normalized = normalizeItems(items);
  const useGrid = layout === 'grid';
  const formCls = [
    FORM_LAYOUT_CLASS[layout] || FORM_LAYOUT_CLASS.vertical,
    className,
  ].filter(Boolean).join(' ');

  const gridStyle = useGrid
    ? { gridTemplateColumns: `repeat(${Math.max(1, Number(columns) || 1)}, minmax(0, 1fr))` }
    : undefined;
  const mergedFormStyle = { ...gridStyle, ...style };

  if (children) {
    return (
      <form className={[`tfds-form`, formCls].filter(Boolean).join(' ')} style={mergedFormStyle} {...rest} data-tfds-component="Form">
        {children}
      </form>
    );
  }

  return (
    <form className={[`tfds-form`, formCls].filter(Boolean).join(' ')} style={mergedFormStyle} {...rest} data-tfds-component="Form">
      {normalized.map((item) => (
        <FormField
          key={item.id || item.name || `${item.label}-${item.type}`}
          item={item}
          labelPosition={labelPosition}
          size={size}
          labelWidth={labelWidth}
          disabled={disabled}
          requiredMark={requiredMark}
          labelOptional={labelOptional}
          labelRequired={labelRequired}
          labelAi={labelAi}
          labelHelp={labelHelp}
          debugLayout={debugLayout}
          debugName={debugName}
        />
      ))}
    </form>
  );
}
