/** 
  author: Zengruihan
  describe: 基础表单组件封装
  创建日期: 2023-09-05
*/
import { useIntl } from '@umijs/max';
import {
  Button,
  Checkbox,
  Col,
  Form,
  FormInstance,
  FormProps,
  Input,
  Radio,
  Row,
  Select,
  Space,
  TreeSelect,
} from 'antd';
const { TextArea } = Input;

type BaseFormProps = {
  itemColumn: ItemType[];
  config: FormProps;
};

type ItemType = {
  [key: string]: any;
};

const BaseForm = ({ itemColumn, config }: BaseFormProps) => {
  const [form] = Form.useForm();
  const intl = useIntl();

  const InputItem = (item: ItemType) => {
    return (
      <Input
        {...item.elementProps}
        placeholder={
          item.elementProps?.placeholder ||
          intl.formatMessage(
            {
              id: 'form.please.enter',
            },
            { label: item.itemProps.label } || '',
          )
        }
      />
    );
  };

  const InputPasswordItem = (item: ItemType) => {
    return (
      <Input.Password
        {...item.elementProps}
        placeholder={
          item.elementProps?.placeholder ||
          intl.formatMessage(
            {
              id: 'form.please.enter',
            },
            { label: item.itemProps.label } || '',
          )
        }
      />
    );
  };

  const CheckboxItem = (item: ItemType) => {
    return (
      <Space>
        {item.options.map((i: any) => (
          <Checkbox key={i.key}>{i.value}</Checkbox>
        ))}
      </Space>
    );
  };

  const TextAreaItem = (item: ItemType) => {
    return (
      <TextArea
        {...item.elementProps}
        placeholder={
          item.elementProps?.placeholder ||
          intl.formatMessage(
            {
              id: 'form.please.enter',
            },
            { label: item.itemProps.label } || '',
          )
        }
      />
    );
  };

  const RadioItem = (item: ItemType) => {
    return (
      <Radio.Group {...item.elementProps}>
        {item.options.map((i: any) => (
          <Radio key={i.key} value={i.value}>
            {i.label}
          </Radio>
        ))}
      </Radio.Group>
    );
  };

  const CustomItem = (item: ItemType) => {
    return item.render();
  };

  const SelectItem = (item: ItemType) => {
    return (
      <Select
        {...item.elementProps}
        placeholder={
          item.elementProps?.placeholder ||
          intl.formatMessage(
            {
              id: 'form.please.select',
            },
            { label: item.itemProps.label } || '',
          )
        }
      >
        {item.options.map((i: any) => (
          <Select.Option key={i.key} value={i.value}>
            {i.label}
          </Select.Option>
        ))}
      </Select>
    );
  };

  const ButtonItem = (item: ItemType, form: FormInstance) => {
    return (
      <Space>
        {item.columns.map((i: any) => (
          <Button
            {...i.elementProps}
            key={i.key}
            onClick={
              i.onclick
                ? () => {
                    i.onclick(form);
                  }
                : undefined
            }
          >
            {i.value}
          </Button>
        ))}
      </Space>
    );
  };
  const TreeSelectItem = (item: ItemType) => {
    return (
      <TreeSelect
        {...item.elementProps}
        placeholder={
          item.elementProps?.placeholder ||
          intl.formatMessage(
            {
              id: 'form.please.select',
            },
            { label: item.itemProps.label } || '',
          )
        }
        showSearch
        allowClear
      />
    );
  };

  const itemRenderMap = new Map([
    ['input', InputItem],
    ['radio', RadioItem],
    ['inputPassword', InputPasswordItem],
    ['checkbox', CheckboxItem],
    ['select', SelectItem],
    ['button', ButtonItem],
    ['textArea', TextAreaItem],
    ['custom', CustomItem],
    ['treeSelect', TreeSelectItem],
  ]);
  itemColumn.forEach((item, index) => {
    itemColumn[index].key = index;
  });
  return (
    <Form {...config} form={config.form || form}>
      {
        // eslint-disable-next-line array-callback-return
        itemColumn.map((item) => {
          const renderFn = itemRenderMap.get(item.type);
          if (renderFn) {
            return item.isGrid ? (
              <Row {...item.row}>
                {item.gridColumn.map((i: any) => {
                  return (
                    <Col {...i.col} key={i.key}>
                      <Form.Item {...i.itemProps} key={i.key}>
                        {renderFn(i, form)}
                      </Form.Item>
                    </Col>
                  );
                })}
              </Row>
            ) : (
              <Form.Item {...item.itemProps} key={item.key}>
                {renderFn(item, form)}
              </Form.Item>
            );
          }
        })
      }
    </Form>
  );
};

export default BaseForm;
