"use strict";
"use client";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var Form_exports = {};
__export(Form_exports, {
  default: () => Form_default
});
module.exports = __toCommonJS(Form_exports);
var import_jsx_runtime = require("react/jsx-runtime");
var import_react = require("react");
var import_formik = require("formik");
var import_Check12 = require("../../icons/Check12");
var import_Input = require("./components/Field/components/Input");
var import_FormContext = require("./context/FormContext");
var import_Placeholder = __toESM(require("./components/Placeholder"));
var import_Field = __toESM(require("./components/Field"));
var import_Spinner = __toESM(require("./components/Spinner"));
var import_Button = __toESM(require("../Button"));
var import_Link = require("../../shared/Link");
var import_box_models = require("../../../state/modules/box-models");
var import_useTableFormFieldRefs = require("../../hooks/useTableFormFieldRefs");
var import_css = require("@emotion/css");
var import_responsive_style = require("../../utils/responsive-style");
var import_host_api_client = require("../../../runtimes/react/host-api-client");
var import_use_style = require("../../../runtimes/react/use-style");
var import_makeswift_api = require("../../../runtimes/react/hooks/makeswift-api");
const LOCAL_STORAGE_NAMESPACE = "@@makeswift/components/form";
function getSizeFontSize(size) {
  switch (size) {
    case import_FormContext.Sizes.SMALL:
      return 12;
    case import_FormContext.Sizes.MEDIUM:
      return 14;
    case import_FormContext.Sizes.LARGE:
      return 18;
    default:
      throw new Error(`Invalid form size "${size}"`);
  }
}
const GridForm = (0, import_react.forwardRef)(function GridFrom({ className, size, ...restOfProps }, ref) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "form",
    {
      ...restOfProps,
      ref,
      className: (0, import_css.cx)(
        (0, import_use_style.useStyle)({ display: "flex", flexWrap: "wrap", width: "100%" }),
        (0, import_use_style.useStyle)(
          (0, import_responsive_style.useResponsiveStyle)([size], ([size2 = import_FormContext.Sizes.MEDIUM]) => ({
            fontSize: getSizeFontSize(size2)
          }))
        ),
        className
      )
    }
  );
});
const GridItem = (0, import_react.forwardRef)(function GridItem2({ className, grid, index, rowGap, columnGap, ...restOfProps }, ref) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      ...restOfProps,
      ref,
      className: (0, import_css.cx)(
        (0, import_use_style.useStyle)({ alignSelf: "flex-end", flexDirection: "column" }),
        (0, import_use_style.useStyle)((0, import_responsive_style.useResponsiveGridItem)({ grid, index, rowGap, columnGap })),
        className
      )
    }
  );
});
function getAlignmentMargin(alignment) {
  switch (alignment) {
    case import_FormContext.Alignments.LEFT:
      return "0 auto 0 0";
    case import_FormContext.Alignments.RIGHT:
      return "0 0 0 auto";
    default:
      return "0 auto";
  }
}
function StyledButton({ className, size, alignment, ...restOfProps }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    import_Button.default,
    {
      ...restOfProps,
      as: "button",
      className: (0, import_css.cx)(
        (0, import_use_style.useStyle)({ display: "flex", alignItems: "center", justifyContent: "center" }),
        (0, import_use_style.useStyle)(
          (0, import_responsive_style.useResponsiveStyle)(
            [size, alignment],
            ([size2 = import_FormContext.Sizes.MEDIUM, alignment2 = import_FormContext.Alignments.CENTER]) => ({
              minHeight: (0, import_Input.getSizeHeight)(size2),
              maxHeight: (0, import_Input.getSizeHeight)(size2),
              margin: getAlignmentMargin(alignment2),
              paddingTop: 0,
              paddingBottom: 0
            })
          )
        ),
        className
      )
    }
  );
}
function ErrorContainer({ className, ...restOfProps }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      ...restOfProps,
      className: (0, import_css.cx)(
        (0, import_use_style.useStyle)({
          padding: "8px 16px",
          backgroundColor: "#f19eb9",
          borderRadius: 4,
          marginTop: 16
        }),
        className
      )
    }
  );
}
function IconContainer({ className, ...restOfProps }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...restOfProps, className: (0, import_css.cx)((0, import_use_style.useStyle)({ fill: "currentColor" }), className) });
}
function ErrorMessage({ className, ...restOfProps }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "p",
    {
      ...restOfProps,
      className: (0, import_css.cx)(
        (0, import_use_style.useStyle)({ fontSize: 12, margin: "8px 0", color: "rgba(127, 0, 0, 0.95)" }),
        className
      )
    }
  );
}
function getTableColumnDefaultValue(tableColumn) {
  switch (tableColumn.__typename) {
    case "CheckboxTableColumn":
      return false;
    case "MultipleSelectTableColumn":
      return [];
    case "SingleLineTextTableColumn":
    case "LongTextTableColumn":
    case "SingleSelectTableColumn":
    case "PhoneNumberTableColumn":
    case "EmailTableColumn":
    case "URLTableColumn":
    case "NumberTableColumn":
    default:
      return "";
  }
}
const Form = (0, import_react.forwardRef)(function Form2({
  id,
  tableId,
  fields: fieldsProp,
  submitLabel = "Submit",
  submitLink,
  shape,
  size,
  contrast,
  brandColor,
  gap,
  width,
  margin,
  submitTextStyle,
  submitVariant,
  submitTextColor,
  submitWidth,
  submitAlignment,
  labelTextStyle,
  labelTextColor
}, ref) {
  const fields = (0, import_react.useMemo)(() => fieldsProp?.fields ?? [], [fieldsProp]);
  const grid = (0, import_react.useMemo)(() => fieldsProp?.grid ?? [], [fieldsProp]);
  const table = (0, import_makeswift_api.useTable)(tableId ?? null);
  const client = (0, import_host_api_client.useMakeswiftHostApiClient)();
  const [refEl, setRefEl] = (0, import_react.useState)(null);
  const [propControllers, setPropControllers] = (0, import_react.useState)(null);
  const [initialValues, setInitialValues] = (0, import_react.useState)(
    () => fields.reduce((acc, formField) => {
      const tableColumn = table && table.columns.find((field) => field.id === formField.tableColumnId);
      const defaultValue = formField ? formField.defaultValue : null;
      if (tableColumn) {
        acc[tableColumn.name] = defaultValue == null ? getTableColumnDefaultValue(tableColumn) : defaultValue;
      }
      return acc;
    }, {})
  );
  const controller = propControllers?.fields;
  const { container, items } = (0, import_useTableFormFieldRefs.useTableFormFieldRefs)(controller, { fieldsCount: fields.length });
  const [isDone, setIsDone] = (0, import_react.useState)(false);
  const linkRef = (0, import_react.useRef)(null);
  (0, import_react.useImperativeHandle)(
    ref,
    () => ({
      getDomNode() {
        return refEl instanceof Element ? refEl : null;
      },
      getBoxModel() {
        return refEl instanceof Element ? (0, import_box_models.getBox)(refEl) : null;
      },
      setPropControllers
    }),
    [refEl, setPropControllers]
  );
  (0, import_react.useEffect)(() => {
    container(refEl);
  }, [container, refEl]);
  (0, import_react.useEffect)(() => {
    if (!isDone)
      return;
    let timeoutId = setTimeout(() => setIsDone(false), 2500);
    return () => clearTimeout(timeoutId);
  }, [isDone]);
  function getTableColumn({ tableColumnId }) {
    return table && table.columns.find((field) => tableColumnId === field.id);
  }
  async function handleSubmit(values, { setSubmitting, resetForm, setStatus }) {
    if (table) {
      const columns = [];
      fields.forEach((field) => {
        const tableColumn = getTableColumn(field);
        if (tableColumn) {
          const data = values[tableColumn.name];
          if (data) {
            columns.push({ columnId: field.tableColumnId, data });
            if (field.autofill) {
              localStorage.setItem(
                `${LOCAL_STORAGE_NAMESPACE}/${tableColumn.name}`,
                JSON.stringify(data)
              );
            }
          }
        }
      });
      try {
        await client.createTableRecord(table.id, columns);
        setIsDone(true);
        setInitialValues(
          (prev) => fields.reduce(
            (acc, field) => {
              const tableColumn = getTableColumn(field);
              if (tableColumn) {
                const data = values[tableColumn.name];
                if (data && field.autofill)
                  return { ...acc, [tableColumn.name]: data };
              }
              return acc;
            },
            { ...prev }
          )
        );
        resetForm();
        if (linkRef.current != null)
          linkRef.current.click();
      } catch (error) {
        setStatus({ error: "An unexpected error has occurred, please try again later" });
      } finally {
        setSubmitting(false);
      }
    }
  }
  (0, import_react.useEffect)(() => {
    setInitialValues(
      (prev) => fields.reduce(
        (acc, formField) => {
          const tableColumn = table && table.columns.find((field) => field.id === formField.tableColumnId);
          if (tableColumn && formField.autofill) {
            const storedValue = localStorage.getItem(
              `${LOCAL_STORAGE_NAMESPACE}/${tableColumn.name}`
            );
            if (storedValue) {
              try {
                acc[tableColumn.name] = JSON.parse(storedValue);
              } catch (e) {
              }
            }
          }
          return acc;
        },
        { ...prev }
      )
    );
  }, [fields, table]);
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    import_FormContext.Provider,
    {
      value: { shape, size, contrast, brandColor, labelTextStyle, labelTextColor },
      children: tableId == null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Placeholder.default, { ref: setRefEl, width, margin }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        import_formik.Formik,
        {
          onSubmit: handleSubmit,
          initialValues,
          initialStatus: { error: null },
          enableReinitialize: true,
          children: (formik) => {
            const error = formik.status && formik.status.error;
            const errors = fields.map((field) => {
              const tableColumn = getTableColumn(field);
              return tableColumn && (0, import_formik.getIn)(formik.touched, tableColumn.name) && (0, import_formik.getIn)(formik.errors, tableColumn.name);
            }).filter((message) => typeof message === "string");
            return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
              /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
                GridForm,
                {
                  ref: setRefEl,
                  id,
                  className: (0, import_css.cx)(width, margin),
                  size,
                  onSubmit: formik.handleSubmit,
                  onReset: formik.handleReset,
                  noValidate: true,
                  children: [
                    fields.map((field, index) => {
                      const tableColumn = getTableColumn(field);
                      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
                        GridItem,
                        {
                          ref: items[index],
                          grid,
                          index,
                          rowGap: gap,
                          columnGap: gap,
                          children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Field.default, { tableColumn, tableFormField: field })
                        },
                        field.id
                      );
                    }),
                    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
                      GridItem,
                      {
                        ref: items[fields.length],
                        grid,
                        index: fields.length,
                        rowGap: gap,
                        columnGap: gap,
                        children: [
                          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
                            StyledButton,
                            {
                              type: "submit",
                              disabled: formik.isSubmitting || isDone,
                              shape,
                              size,
                              color: brandColor,
                              variant: submitVariant,
                              textColor: submitTextColor,
                              width: submitWidth,
                              alignment: submitAlignment,
                              textStyle: submitTextStyle,
                              children: formik.isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Spinner.default, {}) : isDone ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Check12.Check12, {}) }) : submitLabel
                            }
                          ),
                          (errors.length > 0 || error) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ErrorContainer, { children: [
                            errors.map((message) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorMessage, { children: message }, message)),
                            error != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorMessage, { children: error })
                          ] })
                        ]
                      }
                    )
                  ]
                }
              ),
              submitLink != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Link.Link, { ref: linkRef, hidden: true, link: submitLink })
            ] });
          }
        }
      ) })
    }
  );
});
var Form_default = Form;
//# sourceMappingURL=Form.js.map