import React from "react";
import classNames from "classnames";
import { StyledProps } from "../_type";
import { FormItem } from "./FormItem";
import { FormControl } from "./FormControl";
import { createRocket } from "../_util/create-rocket";
import { FormContext } from "./FormContext";
import { useConfig } from "../_util/config-context";
import { forwardRefWithStatics } from "../_util/forward-ref-with-statics";

export interface FormProps extends StyledProps {
  /**
   * 表单布局方式
   *
   * - `default` 默认布局
   * - `fixed` 固定标签栏宽度，可用于对齐多个表单
   * - `vertical` 标签和控件垂直排列
   * - `inline` 表单内容行内流水排列
   * - `inline-vertical` 表单内容行内流水排列，且标签和控件垂直排列
   * @default "default"
   */
  layout?: "default" | "fixed" | "vertical" | "inline" | "inline-vertical";

  /**
   * 是否为纯展示表单（样式更加紧凑）
   *
   * @default false
   */
  readonly?: boolean;

  /**
   * 不展示表单 Label 部分
   *
   * @default false
   */
  hideLabel?: boolean;

  /**
   * 表单布局为 `fixed` 时 Label 部分的宽度
   * @default "6em"
   * @since 2.4.0
   */
  fixedLabelWidth?: React.CSSProperties["width"];

  /**
   * 表单内容
   */
  children?: React.ReactNode;
}

export const FormText = createRocket("Form.Text", "div.@{prefix}-form__text");
export const FormTitle = createRocket("Form.Title", "h3.@{prefix}-form-title");
export const FormAction = createRocket(
  "Form.Action",
  "div.@{prefix}-form-operate"
);

export const Form = forwardRefWithStatics(
  function Form(
    {
      layout,
      readonly,
      hideLabel,
      fixedLabelWidth,
      children,
      className,
      ...props
    }: FormProps,
    ref: React.Ref<HTMLDivElement>
  ) {
    const { classPrefix } = useConfig();
    // readonly 只和 fixed 共存
    const formClassName = classNames(
      `${classPrefix}-form`,
      {
        [`${classPrefix}-form--fixed-layout`]: layout === "fixed",
        [`${classPrefix}-form--vertical`]:
          !readonly && (layout === "vertical" || layout === "inline-vertical"),
        [`${classPrefix}-form--inline`]:
          !readonly && (layout === "inline" || layout === "inline-vertical"),
        [`${classPrefix}-form--readonly`]: readonly,
      },
      className
    );
    return (
      <div ref={ref} className={formClassName} {...props}>
        <FormContext.Provider
          value={{
            hideLabel,
            fixedLabelWidth: layout === "fixed" ? fixedLabelWidth : undefined,
          }}
        >
          {children}
        </FormContext.Provider>
      </div>
    );
  },
  {
    Item: FormItem,
    Title: FormTitle,
    Action: FormAction,
    Control: FormControl,
    Text: FormText,
  }
);

Form.displayName = "Form";
