import type { UnwrapRef, Ref } from 'vue';
import { unref, nextTick, toRaw } from 'vue';
import { get, isArray, isNil, isUndefined, isPlainObject, forEach, isFunction } from 'lodash-es';
import { isDateType, transformDate } from '/nerv-lib/component/form/form-util';

interface useFormModelType {
  schemas: Ref<UnwrapRef<FormSchema[]>>;
  formModel: Ref<Recordable>;
  formElRef: any;
  emit: Function;
}

export function useFormModel({ schemas, formModel, formElRef, emit }: useFormModelType) {
  /**
   * 序列化传参  去除viewOnly，单个值转多个（时间范围、经纬度)
   * @param formSchema
   */
  function handleFormModel(formSchema = schemas) {
    // console.log('formSchema', formSchema.value, formModel.value);
    return unref(formSchema).reduce((prev: Recordable, cur: FormSchema) => {
      const { field, fieldMap, keepField, format, addModel = [] } = cur;
      if (cur.viewOnly !== true) {
        let value = getFormModel(field);
        if (isFunction(format)) {
          value = format(value);
        }
        if (cur?.componentProps?.schemas) {
          Object.assign(prev, handleFormModel(cur.componentProps.schemas));
        } else if (fieldMap && !isNil(value)) {
          if (fieldMap === true) {
            Object.keys(value).forEach((key: string) => {
              Object.assign(prev, { [key]: value[key] });
            });
          } else if (isArray(fieldMap)) {
            if (!isArray(value) && ![null, undefined, ''].includes(value)) {
              console.error(`Field value isn't Array`);
            } else {
              fieldMap.forEach((item: string, index) => {
                Object.assign(prev, { [item]: value[index] });
              });
            }
          } else if (isPlainObject(fieldMap)) {
            if (!isPlainObject(value) && ![null, undefined, ''].includes(value)) {
              console.error(`Field value isn't Object`);
            } else {
              Object.keys(fieldMap).forEach((key: string) => {
                Object.assign(prev, { [key]: get(value, (<Props>fieldMap)[key]) });
              });
            }
          }
          //保留原值
          if (keepField === true) {
            Object.assign(prev, { [field]: value });
          }
        } else {
          Object.assign(prev, { [field]: value });
          if (isArray(addModel)) {
            addModel.forEach((item: string) => {
              Object.assign(prev, { [item]: unref(formModel)[item] });
            });
          } else {
            // @ts-ignore
            forEach(addModel as any, (value, key) => {
              Object.assign(prev, { [key]: unref(formModel)[key] });
            });
          }
        }
      }
      return prev;
    }, {});
  }

  /**
   * 设置默认值， formModel > defaultValue
   */
  function initFormModel() {
    unref(schemas).forEach((schema: FormSchema) => {
      const { field, component, defaultValue, componentProps } = schema;

      if (schema.component) {
        if (!isUndefined(defaultValue) && isUndefined(getFormModel(field))) {
          if (defaultValue && isDateType(component)) {
            setFormModel(
              field,
              transformDate(component as string, defaultValue, componentProps.valueFormat),
            );
          } else {
            setFormModel(field, defaultValue);
          }
        } else if (isDateType(component) && !isUndefined(getFormModel(field))) {
          setFormModel(
            field,
            transformDate(component as string, getFormModel(field), componentProps.valueFormat),
          );
        }
      } else {
        setFormModel(field, defaultValue);
      }
    });
  }

  /**
   * 恢复默认值 defaultValue
   */
  function resetFormModel() {
    Object.keys(formModel.value).forEach((key) => {
      unsetFormModel(key);
    });
    console.log(formModel.value);
    unref(schemas).forEach((schema: FormSchema) => {
      const { field, component, defaultValue, componentProps } = schema;
      setFormModel(field, defaultValue);

      if (schema.component) {
        if (defaultValue && isDateType(component)) {
          setFormModel(
            field,
            transformDate(component as string, defaultValue, componentProps.valueFormat),
          );
        } else {
          setFormModel(field, defaultValue);
        }
      } else {
        setFormModel(field, defaultValue);
      }
    });

    emit('reset', toRaw(formModel.value));
  }

  async function validateFields(nameList?: string[] | undefined) {
    await nextTick();
    return unref(formElRef)?.validateFields(nameList);
  }

  // function fieldRules(field: string) {
  //   if (field === 'fieldLink') return undefined;
  //   console.log('field', field, getNamePath.value);
  //   return getNamePath.value[field]?.rules || undefined;
  // }

  // function setNamePath(schemas: FormSchema[], namePathList: Recordable = {}) {
  //   unref(schemas).forEach((schema: FormSchema) => {
  //     if (schema.rules) {
  //       namePathList[schema.field] = {
  //         state: false,
  //         rules: schema.rules,
  //       };
  //     }
  //     if (schema?.componentProps?.schemas) {
  //       setNamePath(schema?.componentProps?.schemas, namePathList);
  //     }
  //   });
  //   console.log('namePathList', namePathList);
  //   return namePathList;
  // }

  // const getNamePath = computed(() => {
  //   return setNamePath(unref(schemas));
  // });

  /**
   * 设置表单值
   * @param key
   * @param value
   */
  function setFormModel(key: string, value?: any) {
    if (value === null) {
      delete unref(formModel)[key];
    } else {
      //select allowClear时值被设为undefined
      unref(formModel)[key] = value;
    }
    validateFields([key]).catch((err) => {
      console.error(`${key}:`, err);
    });
    // console.log('formModel', key, value, formModel.value);
    // if (fieldRules(key)) {
    //   console.log('getNamePath', getNamePath.value);
    //   validateFields([key])
    //     .then((data) => {
    //       console.log('validateFields then', key, data);
    //     })
    //     .catch((e) => {
    //       console.log('validateFields catch', key, e);
    //     });
    // }
  }

  /**
   * 清除表单值
   * @param key
   */
  function unsetFormModel(key: string) {
    console.log('unsetFormModel', key);
    delete unref(formModel)[key];
  }

  /**
   * 获得表单值
   * @param key
   */
  function getFormModel(key: string) {
    return unref(formModel)[key];
  }

  return {
    handleFormModel,
    initFormModel,
    resetFormModel,
    setFormModel,
    unsetFormModel,
    getFormModel,
  };
}
