import {Ref, useEffect, useImperativeHandle, useRef, useState} from 'react';
import {ProForm, ProFormInstance} from "@ant-design/pro-components";
import {GetProps, Skeleton} from "antd";
import type {IBaseFormFieldItem, IBaseFormProps} from "@jeoshi-design/rex-design.data-entry.core";
import {BaseForm, getFieldsDefaultValues} from "@jeoshi-design/rex-design.data-entry.core";
import {useRequestFields, useRequestFieldsConfig, useRexProConfigProvider} from '@jeoshi-design/rex-design.other.core';
import {useStateData} from "@jeoshi-design/rex-design.hooks.core";
import classNames from "classnames";
import {RexProFormStyle} from "./style";


export const Form = <T extends Record<string, unknown>> ({
  formDataUrl,
  formSaveUrl,
  fieldPropsFn,
  form: outForm,
  initialValues,
  requestOptions,
  onFormInstanceReady,
  fieldsConfig,
  actionRef,
  onEvent,
  initSendOn,
  ...otherProps
}: TFormProps<T>) => {
  const responseConfig = useRequestFieldsConfig();
  const [inlineForm] = ProForm.useForm<T>();
  const inlineFormRef = useRef<ProFormInstance>();
  const form = outForm || inlineForm;
  const formRef = (inlineFormRef) as typeof inlineFormRef;
  const hasFormInstanceReadyBeenCalled = useRef(false);
  const {apiClient} = useRexProConfigProvider();
  const {state} = useStateData(() => ({
    fieldProps: fieldPropsFn?.(form),
    initialDefaultValues: {} as T,
  }));

  const urlParams = new URLSearchParams(window.location.search);
  const urlParamsObj = Object.fromEntries(urlParams.entries());

  const {loading, fields} = useRequestFields({
    requestFieldsUrl: responseConfig.formFieldUrl,
    requestFieldsParams: responseConfig.formFieldParams,
    fieldsConfig: (fieldsConfig || responseConfig.formFieldConfig) as typeof fieldsConfig,
  }, (data) => {
    state.initialDefaultValues = getFieldsDefaultValues(data);
  });

  useEffect(() => {
    if (onFormInstanceReady && !hasFormInstanceReadyBeenCalled.current) {
      onFormInstanceReady(form);
      hasFormInstanceReadyBeenCalled.current = true;
    }
  }, [form, onFormInstanceReady]);


  useImperativeHandle<{}, RexProFormActionRef>(actionRef, () => {
    return {
      setValues: (data) => {
        formRef.current?.setFieldsValue?.(data);
      },
      resetValues: () => {
        formRef.current?.resetFields?.();
      },
    };
  });

  if (loading) {
    return (
      <>
        <Skeleton active={true} />
      </>
    )
  }

  return (
    <>
      <RexProFormStyle />
      <ProForm<T>
        params={urlParamsObj}
        request={async (params) => {

          if (!formDataUrl || initSendOn === false) return {} as T;

          const res = await apiClient(formDataUrl, params);

          return res as T;
        }}
        {...otherProps}
        rootClassName={classNames(otherProps.rootClassName, 'rex-pro-form-box')}
        initialValues={typeof initialValues === 'function'
          ? initialValues(state.initialDefaultValues)
          : (initialValues ?? state.initialDefaultValues)}
        form={form}
        formRef={formRef}
        onFinish={async (values) => {

          try {
            // 提交表单数据
            if (formSaveUrl) {
              await apiClient(formSaveUrl, {
                ...values,
                ...urlParamsObj,
              });
            }

            // 执行事件处理
            if (onEvent?.actionType) {
              switch (onEvent.actionType) {
                case 'url':
                  if (onEvent.linkUrl) {
                    window.location.href = onEvent.linkUrl;
                  }
                  break;
                case 'refresh':
                  window.location.reload();
                  break;
                case 'goBack':
                  window.history.go(-1);
                  break;
                default:
                  console.error(`不支持的操作类型: ${onEvent.actionType}`);
                  break;
              }
            }
          } catch (e) {
            console.error(e);
          }

        }}
      >
        <BaseForm
          requestOptions={requestOptions}
          fields={fields}
          fieldProps={state.fieldProps}
        />
      </ProForm>
    </>
  );
};


export interface TFormProps<T extends Record<string, unknown>> extends Omit<TRawProFormProps<T>, 'form' | 'initialValues'>, Omit<IBaseFormProps, 'fields' | 'fieldProps'> {
  formDataUrl?: string;
  formSaveUrl?: string;
  fieldsConfig?: TFields;
  /** 动态字段属性配置函数 */
  fieldPropsFn?: (form: TForm<T>) => Exclude<IBaseFormProps['fieldProps'], undefined>;
  /** ProForm实例 */
  form?: TForm<T>;
  /** 初始化值 */
  initialValues?: T | ((defaultValues: T) => T);
  /** 表单实例准备就绪回调 */
  onFormInstanceReady?: (form: TForm<T>) => void;
  /** 操作对象 */
  actionRef?: Ref<RexProFormActionRef>;
  /** 提交事件 */
  onEvent?: {
    actionType?: 'url' | 'refresh' | 'goBack'
    linkUrl?: string
  },
  /** 初始化请求接口 */
  initSendOn?: boolean
}

// type FormFieldItem = IBaseFormFieldItem & {defaultValue?: string | string[] | boolean | number}
type TFields = Exclude<IBaseFormProps['fields'], undefined>;
// type TFieldProps = Exclude<IBaseFormProps['fieldProps'], undefined>;
type TRawProFormProps<T> = GetProps<typeof ProForm<T>>;
type TForm<T> = ReturnType<typeof ProForm.useForm<T>>[0];

export interface RexProFormActionRef {
  /** 设置表单数据 */
  setValues: (data: Record<string, unknown>) => void;
  /** 重置值 */
  resetValues: () => void;
}
