import React, { useEffect, useContext, useState } from 'react';
import { Select, Button, message, Row, Col, Tabs, Popconfirm, InputNumber, Switch, Typography } from 'antd';
import StringFormField from '../StringFormField';
import RadioGroupFormField from '../RadioGroupFormField';
import JsonEditor from '../JsonEditor';
import RefTableLink from '../RefTableLink';
import PageContext from '../../contexts/page';
import MultiLineInputBox from '../MultiLineInputBox';
import * as constants from '../../constants';
import TextAreaFormField from '../TextAreaFormField';
import { isType, obj2str, str2obj, getFormInitialValues } from './helpers';
import FieldWrapperForCreateUpdatePage from '../FieldWrapperForCreateUpdatePage';
import PresetsButtons from '../PresetsButtons';
import { useAppContext } from '../../contexts/AppContext';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
// Use `Typography` so can apply dark theme to text
const {
  Text
} = Typography;
const renderFormFieldWrapper = ({
  id,
  label,
  formField
}) => /*#__PURE__*/_jsxs("div", {
  className: "dbm-form-field dbm-string-form-field",
  children: [/*#__PURE__*/_jsx("b", {
    children: label
  }), ": ", formField]
}, id);
const filterOutHiddenFields = column => column[constants.TYPE_CREATE_UPDATE_PAGE] !== 'HIDE';
const Form = props => {
  const {
    showDelete = true
  } = props;
  const pageCtx = useContext(PageContext);
  const {
    getTablesByDbName
  } = useAppContext();
  const [formValues, setFormValues] = useState({
    ...props.defaultValues
  });
  const [jsonStr, setJsonStr] = useState(obj2str({
    ...props.defaultValues
  }));
  useEffect(() => {
    const initFormValues = getFormInitialValues(pageCtx.columns, formValues);
    setFormValues(prevFormValues => ({
      ...prevFormValues,
      ...initFormValues
    }));
    setJsonStr(prevJsonStr => {
      const prevJsonObj = str2obj(prevJsonStr);
      return obj2str({
        ...prevJsonObj,
        ...initFormValues
      });
    });
  }, []);
  const changeBothFormAndJsonEditor = newFormValues => {
    setFormValues(newFormValues);
    setJsonStr(obj2str(newFormValues));
  };
  const handleChange = key => value => {
    changeBothFormAndJsonEditor({
      ...formValues,
      [key]: value
    });
  };
  const handleInputChange = key => val => {
    // if key is primary key, check if it contains any whitespace character
    if (key === pageCtx.primaryKey && /\s/.test(val)) {
      message.warning('Primary key cannot contain whitespace character');
    }
    changeBothFormAndJsonEditor({
      ...formValues,
      [key]: val
    });
  };

  /**
   * @param {string} id Column name
   * @param {string[]} value Cell value
   */
  const handleStringArrayChange = id => value => changeBothFormAndJsonEditor({
    ...formValues,
    [id]: value
  });
  const handleKeyDown = event => {
    if (event.code === 'KeyS' && event.metaKey) {
      event.preventDefault();
      handleFormSubmit();
    }
  };
  const handleFormSubmit = () => {
    props.onSubmit(formValues);
  };
  const handleDelete = () => {
    props.onDelete && props.onDelete(formValues);
  };
  const renderStringFormField = column => {
    const {
      loading
    } = props;
    const value = formValues[column.id];
    if (column[constants.TYPE_CREATE_UPDATE_PAGE] === 'TextArea') {
      return /*#__PURE__*/_jsx(TextAreaFormField, {
        label: column.name,
        rows: 2,
        disabled: loading,
        value: value,
        onChange: handleChange(column.id)
      }, column.id);
    }
    if (column[constants.TYPE_CREATE_UPDATE_PAGE] === 'RadioGroup') {
      const radioValue = value || column?.['ui:createUpdatePage:enum']?.[0];
      return renderFormFieldWrapper({
        id: column.id,
        label: column.name,
        formField: /*#__PURE__*/_jsx(RadioGroupFormField, {
          column: column,
          disabled: loading,
          value: radioValue,
          onChange: handleChange(column.id)
        })
      });
    }
    let preview = false;
    if (column[constants.TYPE_CREATE_UPDATE_PAGE] === 'WithPreview') {
      preview = true;
    }
    return /*#__PURE__*/_jsx(StringFormField, {
      inputProps: {
        disabled: loading,
        autoFocus: column.id === pageCtx.primaryKey,
        onKeyDown: handleKeyDown,
        placeholder: column['ui:createUpdatePage:placeholder']
      },
      preview: preview,
      column: column,
      rows: props.rows,
      value: value,
      onChange: handleInputChange(column.id)
    }, column.id);
  };
  const renderStringArrayFormField = column => {
    if (!column[constants.TYPE_CREATE_UPDATE_PAGE] || column[constants.TYPE_CREATE_UPDATE_PAGE] === 'Select') {
      return /*#__PURE__*/_jsxs("div", {
        className: "dbm-form-field dbm-string-array-form-field",
        children: [/*#__PURE__*/_jsx("b", {
          children: column.name
        }), ":", ' ', /*#__PURE__*/_jsx(PresetsButtons, {
          column: column,
          onChange: val => {
            handleStringArrayChange(column.id)([...(formValues[column.id] || []), val]);
          }
        }), ' ', /*#__PURE__*/_jsx(Select, {
          size: "small",
          mode: "tags",
          style: {
            width: '100%'
          },
          disabled: props.loading,
          value: formValues[column.id],
          onChange: handleStringArrayChange(column.id),
          onKeyDown: handleKeyDown
        })]
      }, column.id);
    }
    const {
      is: isMultipleInputs,
      preview: isMultipleInputsWithPreview
    } = isType(column, 'MultiLineInputBox');
    if (isMultipleInputs) {
      if (isMultipleInputsWithPreview) {
        return /*#__PURE__*/_jsx(FieldWrapperForCreateUpdatePage, {
          column: column,
          children: /*#__PURE__*/_jsxs(Row, {
            children: [/*#__PURE__*/_jsx(Col, {
              span: 12,
              children: /*#__PURE__*/_jsx(MultiLineInputBox, {
                rows: 2,
                disabled: props.loading,
                value: formValues[column.id],
                onChange: handleStringArrayChange(column.id)
              })
            }), /*#__PURE__*/_jsx(Col, {
              span: 12,
              children: formValues[column.id] && formValues[column.id].map(img => /*#__PURE__*/_jsx("a", {
                href: img,
                target: "_blank",
                rel: "noreferrer",
                children: /*#__PURE__*/_jsx("img", {
                  width: "200px",
                  src: img,
                  alt: "img"
                })
              }, img))
            })]
          })
        }, column.id);
      }
      return /*#__PURE__*/_jsxs("div", {
        className: "dbm-form-field dbm-string-array-form-field",
        children: [/*#__PURE__*/_jsx("b", {
          children: column.name
        }), ":", ' ', /*#__PURE__*/_jsx(RefTableLink, {
          dbName: pageCtx.dbName,
          tables: getTablesByDbName(pageCtx.dbName),
          value: formValues[column.id],
          column: column
        }), /*#__PURE__*/_jsx(MultiLineInputBox, {
          disabled: props.loading,
          value: formValues[column.id],
          onChange: handleStringArrayChange(column.id)
        })]
      }, column.id);
    }
    return null;
  };
  const renderNumberFormField = column => {
    const {
      loading
    } = props;
    return renderFormFieldWrapper({
      id: column.id,
      label: column.name,
      formField: /*#__PURE__*/_jsx(InputNumber, {
        size: "small",
        disabled: loading,
        autoFocus: column.id === pageCtx.primaryKey,
        value: formValues[column.id],
        onChange: handleChange(column.id),
        onKeyDown: handleKeyDown
      })
    });
  };
  const renderBoolFormField = column => renderFormFieldWrapper({
    id: column.id,
    label: column.name,
    formField: /*#__PURE__*/_jsx(Switch, {
      size: "small",
      disabled: props.loading,
      checked: formValues[column.id],
      onChange: handleChange(column.id)
    })
  });
  const fieldRender = column => {
    switch (column.type) {
      case constants.STRING_ARRAY:
        return renderStringArrayFormField(column);
      case constants.NUMBER:
        return renderNumberFormField(column);
      case constants.BOOL:
        return renderBoolFormField(column);
      case constants.STRING:
      default:
        return renderStringFormField(column);
    }
  };
  const {
    loading
  } = props;
  const tabsItems = [{
    label: 'Form',
    key: 'form',
    children: /*#__PURE__*/_jsx("div", {
      className: "dbm-form",
      children: pageCtx.columns.filter(filterOutHiddenFields).map(fieldRender)
    })
  }, {
    label: 'JSON',
    key: 'json',
    children: /*#__PURE__*/_jsx(JsonEditor, {
      value: jsonStr,
      onChange: setJsonStr,
      onFormValueChange: setFormValues,
      onSave: () => {
        handleFormSubmit();
      }
    })
  }];
  return /*#__PURE__*/_jsxs("div", {
    className: "create-update-component",
    children: [/*#__PURE__*/_jsx(Tabs, {
      defaultActiveKey: "form",
      items: tabsItems
    }), /*#__PURE__*/_jsxs("div", {
      className: "dbm-action-buttons",
      children: [/*#__PURE__*/_jsx(Button, {
        type: "primary",
        disabled: loading,
        loading: loading,
        onClick: handleFormSubmit,
        children: "Save"
      }), ' ', showDelete && /*#__PURE__*/_jsxs(_Fragment, {
        children: [/*#__PURE__*/_jsx(Text, {
          children: "|"
        }), ' ', /*#__PURE__*/_jsx(Popconfirm, {
          title: "Are you sure to delete?",
          onConfirm: handleDelete,
          onCancel: () => {},
          okText: "Yes",
          cancelText: "No",
          children: /*#__PURE__*/_jsx(Button, {
            danger: true,
            disabled: loading,
            loading: loading,
            children: "Delete"
          })
        }), ' ']
      }), /*#__PURE__*/_jsx(Text, {
        children: "|"
      }), ' ', /*#__PURE__*/_jsx(Button, {
        type: "link",
        href: `/${pageCtx.dbName}/${pageCtx.tableName}/create`,
        children: "Reset"
      }), ' ']
    })]
  });
};
export default Form;
//# sourceMappingURL=index.js.map