import React, { useCallback, useMemo } from 'react';
import {
  Form,
  Input,
  InputNumber,
  Switch,
  Select,
  DatePicker,
  Button,
  message,
  Divider,
  Typography,
  Tooltip,
} from 'antd';
import { QuestionCircleOutlined, SaveOutlined } from '@ant-design/icons';
import type {
  PluginSettingField,
  PluginSettingType,
} from '../api/plugins';

const { Text } = Typography;

interface PluginSettingsFormProps {
  /** manifest 中声明的 settings 字段 */
  fields: PluginSettingField[];
  /** 当前存储的配置值 */
  values: Record<string, unknown>;
  /** 插件版本（乐观锁） */
  recordVersion: number;
  /** 保存回调 */
  onSave: (config: Record<string, unknown>, version: number) => Promise<unknown>;
  /** 是否只读 */
  readOnly?: boolean;
}

/** 根据 manifest settings 声明自动渲染配置表单 */
const PluginSettingsForm: React.FC<PluginSettingsFormProps> = ({
  fields,
  values,
  recordVersion,
  onSave,
  readOnly = false,
}) => {
  const [form] = Form.useForm();
  const [saving, setSaving] = React.useState(false);

  const initialValues = useMemo(() => {
    const merged: Record<string, unknown> = {};
    for (const f of fields) {
      merged[f.name] = values[f.name] ?? f.default_value ?? getDefaultForType(f.field_type);
    }
    return merged;
  }, [fields, values]);

  const handleSave = useCallback(async () => {
    try {
      const formValues = await form.validateFields();
      setSaving(true);
      await onSave(formValues, recordVersion);
      message.success('配置已保存');
    } catch (err: unknown) {
      if (err && typeof err === 'object' && 'errorFields' in err) {
        // antd 表单校验错误，无需额外提示
        return;
      }
      message.error(err instanceof Error ? err.message : '保存失败');
    } finally {
      setSaving(false);
    }
  }, [form, onSave, recordVersion]);

  const grouped = useMemo(() => {
    const groups = new Map<string, PluginSettingField[]>();
    for (const f of fields) {
      const group = f.group ?? '';
      const list = groups.get(group) ?? [];
      list.push(f);
      groups.set(group, list);
    }
    return groups;
  }, [fields]);

  const renderField = (field: PluginSettingField) => {
    const label = (
      <span>
        {field.display_name}
        {field.description && (
          <Tooltip title={field.description}>
            <QuestionCircleOutlined style={{ marginLeft: 4, color: '#999' }} />
          </Tooltip>
        )}
      </span>
    );

    const rules: Array<{ required: boolean; message?: string; type?: 'string' | 'number' | 'boolean' | 'url' | 'email' }> = [];
    if (field.required) {
      rules.push({ required: true, message: `请输入${field.display_name}` });
    }

    const widget = renderWidget(field, readOnly);

    return (
      <Form.Item
        key={field.name}
        name={field.name}
        label={label}
        rules={rules}
        valuePropName={field.field_type === 'boolean' ? 'checked' : 'value'}
      >
        {widget}
      </Form.Item>
    );
  };

  const groupEntries = Array.from(grouped.entries());

  return (
    <Form
      form={form}
      layout="vertical"
      initialValues={initialValues}
      disabled={readOnly}
    >
      {groupEntries.map(([group, groupFields], gi) => (
        <React.Fragment key={group || `__default_${gi}`}>
          {group ? (
            <Divider type="horizontal" orientationMargin={0} plain>
              <Text strong>{group}</Text>
            </Divider>
          ) : null}
          {groupFields.map(renderField)}
        </React.Fragment>
      ))}

      {!readOnly && (
        <Form.Item>
          <Button
            type="primary"
            icon={<SaveOutlined />}
            loading={saving}
            onClick={handleSave}
          >
            保存配置
          </Button>
        </Form.Item>
      )}
    </Form>
  );
};

function renderWidget(field: PluginSettingField, readOnly: boolean): React.ReactNode {
  switch (field.field_type) {
    case 'text':
      return <Input disabled={readOnly} placeholder={`请输入${field.display_name}`} />;
    case 'number': {
      const props: Record<string, unknown> = {
        disabled: readOnly,
        placeholder: `请输入${field.display_name}`,
        style: { width: '100%' },
      };
      if (field.range) {
        props.min = field.range[0];
        props.max = field.range[1];
      }
      return <InputNumber {...props} />;
    }
    case 'boolean':
      return <Switch disabled={readOnly} />;
    case 'select':
      return (
        <Select
          disabled={readOnly}
          placeholder={`请选择${field.display_name}`}
          options={(field.options ?? []).map((o) => {
            if (typeof o === 'object' && o !== null && 'label' in o && 'value' in o) {
              return o as { label: string; value: string };
            }
            return { label: String(o), value: String(o) };
          })}
        />
      );
    case 'multiselect':
      return (
        <Select
          mode="multiple"
          disabled={readOnly}
          placeholder={`请选择${field.display_name}`}
          options={(field.options ?? []).map((o) => {
            if (typeof o === 'object' && o !== null && 'label' in o && 'value' in o) {
              return o as { label: string; value: string };
            }
            return { label: String(o), value: String(o) };
          })}
        />
      );
    case 'color':
      return <Input type="color" disabled={readOnly} style={{ width: 80 }} />;
    case 'date':
      return <DatePicker disabled={readOnly} style={{ width: '100%' }} />;
    case 'datetime':
      return <DatePicker showTime disabled={readOnly} style={{ width: '100%' }} />;
    case 'json':
      return <Input.TextArea disabled={readOnly} rows={4} placeholder="JSON 格式" />;
    default:
      return <Input disabled={readOnly} />;
  }
}

function getDefaultForType(type: PluginSettingType): unknown {
  switch (type) {
    case 'text':
    case 'color':
      return '';
    case 'number':
      return 0;
    case 'boolean':
      return false;
    case 'select':
      return undefined;
    case 'multiselect':
      return [];
    case 'date':
    case 'datetime':
      return undefined;
    case 'json':
      return '';
    default:
      return '';
  }
}

export default PluginSettingsForm;
