import React, { useState } from 'react';
import { InputNumber, Select, Space, SpaceProps } from 'antd';
import type { InputNumberProps } from 'antd/es/input-number';
import type { SelectProps } from 'antd/es/select';

const { Option } = Select;

export interface NumberUnitOption {
  label: React.ReactNode;
  value: string;
}

export interface NumberUnitValue {
  number?: number;
  unit?: string;
}
export type NumberWithUnitProps = SpaceProps & {
  value?: NumberUnitValue;
  onChange?: (next: NumberUnitValue) => void;
  numberClassName?: string;
  unitClassName?: string;
  className?: string;
  options: NumberUnitOption[];
  defaultUnit?: string;
  defaultNumber?: number;
  numberProps?: Partial<InputNumberProps>;
  selectProps?: Partial<SelectProps>;
};

const NumberWithUnit: React.FC<NumberWithUnitProps> = ({
  value = {},
  onChange,
  numberClassName,
  unitClassName,
  className,
  options,
  defaultUnit,
  defaultNumber,
  numberProps,
  selectProps,
  onBlur,
  ...rest // ← 这里会收到、style 等
}) => {
  const unit = value?.unit ?? defaultUnit ?? undefined;
  const [isComposing, setIsComposing] = useState(false);

  const triggerChange = (changed: Partial<NumberUnitValue>) => {
    onChange?.({ ...value, ...changed });
  };

  // 处理键盘输入 - 阻止非数字字符的输入
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    // 如果正在使用输入法，不拦截
    if (isComposing) return;

    // 允许的功能键
    const allowedKeys = [
      'Backspace',
      'Delete',
      'ArrowLeft',
      'ArrowRight',
      'ArrowUp',
      'ArrowDown',
      'Tab',
      'Enter',
      'Escape',
      'Home',
      'End',
    ];

    // 如果是功能键，允许
    if (allowedKeys.includes(e.key)) return;

    // 如果是 Ctrl/Cmd 组合键（如 Ctrl+A, Ctrl+C, Ctrl+V），允许
    if (e.ctrlKey || e.metaKey) return;

    // 如果不是数字，阻止输入
    if (!/^\d$/.test(e.key)) {
      e.preventDefault();
    }
  };

  // 处理粘贴 - 过滤粘贴内容中的非数字字符
  const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
    e.preventDefault();

    // 获取剪贴板内容
    const pastedText = e.clipboardData.getData('text');

    // 只保留数字
    const cleanedText = pastedText.replace(/\D/g, '');

    if (cleanedText) {
      const numValue = parseInt(cleanedText, 10);
      triggerChange({ number: numValue });
    }
  };

  // 处理输入法开始
  const handleCompositionStart = () => {
    setIsComposing(true);
  };

  // 处理输入法结束 - 过滤输入法输入的非数字字符
  const handleCompositionEnd = (
    e: React.CompositionEvent<HTMLInputElement>
  ) => {
    setIsComposing(false);

    // 获取输入的内容并过滤
    const inputValue = e.currentTarget.value;
    const cleanedValue = inputValue.replace(/\D/g, '');

    if (cleanedValue) {
      const numValue = parseInt(cleanedValue, 10);
      triggerChange({ number: numValue });
    } else {
      // 如果过滤后没有有效数字，清空
      triggerChange({ number: undefined });
    }
  };

  return (
    <>
      <style>{`
            .my-space .ant-space-item:nth-child(1) {
              width: 70%;
            }
            .my-space .ant-space-item:nth-child(2) {
              width: 30%;
            }
        `}</style>
      <Space {...rest} className={`${className}  my-space`}>
        <InputNumber
          className={numberClassName}
          value={value?.number}
          onChange={(n) =>
            triggerChange({ number: typeof n === 'number' ? n : undefined })
          }
          min={0}
          precision={0}
          parser={(value) => value?.replace(/\D/g, '') || ''}
          keyboard={true}
          onKeyDown={handleKeyDown}
          onPaste={handlePaste}
          onCompositionStart={handleCompositionStart}
          onCompositionEnd={handleCompositionEnd}
          {...numberProps}
          defaultValue={defaultNumber}
          onBlur={onBlur}
        />
        <Select
          className={unitClassName}
          value={unit}
          onChange={(u) => triggerChange({ unit: u })}
          {...selectProps}
        >
          {options.map((opt) => (
            <Option key={opt.value} value={opt.value}>
              {opt.label}
            </Option>
          ))}
        </Select>
      </Space>
    </>
  );
};
export default NumberWithUnit;
