import React, { useState, useEffect, useRef } from "react";

import ModalFactory from "./../component/ModalFactory";

import { handleAppParams, postNew } from "./../net/request";
import * as formUtils from "./../utils/formUtils";
import * as commonUtils from "./../utils/commonUtils";
import { CP } from "..";
import { aclCheckPermissions, getHsfHost } from "../net/api";
import CardRender from "../component/CardRender";

const displayName = "CpDetail";
const CpDetail = props => {
  const {
    title,
    schema,
    refreshSchema,
    api = {},
    initData,
    filterParams,
    widgets
  } = props;

  const requestFunc = CP.getCPInfo().requestFunc || postNew;

  const [loading, setLoading] = useState(false);
  const [formData, setForm] = useState({});

  const validate = useRef([]);
  const searchParams = useRef({});

  const hasPageSchema = useRef(false);
  const pageInfo = useRef(formUtils.defaultPageInfo());
  const [cardConfig, setDetailConfig] = useState(null);

  const reqData = useRef(initData);

  useEffect(() => {
    if (schema && !cardConfig) {
      // 改为非受控组件
      try {
        pageInfo.current = schema;
        hasPageSchema.current = true;
        resetDetailConfig();
      } catch (e) {
        commonUtils.log(e);
      }
    }
  }, [schema]);

  useEffect(() => {
    if (refreshSchema) {
      try {
        pageInfo.current = refreshSchema;
        hasPageSchema.current = true;
        resetDetailConfig();
      } catch (e) {
        commonUtils.log(e);
      }
    }
  }, [refreshSchema]);

  useEffect(() => {
    if (hasPageSchema.current && !commonUtils.isEmptyObj(initData)) {
      searchParams.current = { ...searchParams.current, ...initData };
      onSdkSearch();
    } else {
      setModelData(initData);
    }
  }, [initData]);

  const reqHandle = (url, okPath, okFunc, params) =>
    requestFunc(url, handleAppParams(params), okPath)
      .then(res => {
        if (okFunc) okFunc(res, onSdkSearch, params);
        else onSdkSearch();
      })
      .catch(err => commonUtils.log(err));
  /**
   * 按键事件  -  表单弹框
   * @param formSchema  表单内容
   * @param title 表单名称
   * @param okPath 自定义请求成功标示
   * @param url 请求url
   * @param okFunc  自定义成功调用函数
   */
  const formHandle = (formSchema, title, url, okPath, okFunc, params) =>
    ModalFactory.showModalForm({
      formSchema,
      widgets,
      width: 1000,
      title,
      request: {
        okPath,
        url,
        params,
        handleOk: (formData, validate) => {
          if (validate.length) return false;
          return true;
        },
        onSuccess: (res, formData) => {
          if (okFunc) okFunc(res, onSdkSearch, params, formData);
          else onSdkSearch();
        }
      }
    });

  /**
   * 必备函数
   * 表格请求函数
   * 暂支持post请求，因get用长度限制，避免过多参数
   * @param params 搜索项信息
   */
  const onSdkSearch = params => {
    const _params = {
      ...searchParams.current,
      ...params
    };
    const { url, okPath = "data" } = pageInfo.current;
    if (!url) {
      setModelData(_params);
      return;
    }

    setLoading(true);
    requestFunc(
      commonUtils.getUrl(url),
      handleAppParams(_params, filterParams),
      okPath
    )
      .then(({ data, exactData }) => {
        if (!data)
          throw new Error(
            "请求错误，自行处理，该请求可自行设计，只要返回正确数据格式即可！"
          );
        setModelData({ ..._params, ...(exactData || data) });
      })
      .catch(err => {
        console.error("err", err, displayName);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const setModelData = data => {
    reqData.current = data;
    setForm(reqData.current);
  };

  /**
   * 表格列操作区-暂为弹框操作
   * @param record 行数据
   * @param handleInfo 操作信息
   */
  const onSdkTableHandle = (record, handleInfo) => {
    const { content, funcType } = handleInfo;
    const {
      formItems,
      name,
      url,
      okPath,
      okFunc,
      filterSchemaFunc,
      displayType
    } = content || {};
    const apiUrl = commonUtils.getUrl(url);
    const params = { rowInfo: record, ...record };

    switch (funcType) {
      case "34": // 直接请求
      case "35": // 二次确认请求
        reqHandle(apiUrl, okPath, commonUtils.getFunc(okFunc, apis), params);
        break;
      case "36": // 表单弹框请求
        const filterSchema = commonUtils.getFunc(filterSchemaFunc, apis);
        const listTranslSchema = formUtils.listTranslSchema(
          formItems,
          2,
          record
        );
        if (formUtils.getDicTrue(displayType))
          listTranslSchema.displayType = "column";
        formHandle(
          filterSchema ? filterSchema(listTranslSchema) : listTranslSchema,
          name,
          apiUrl,
          okPath,
          commonUtils.getFunc(okFunc, apis),
          params
        );
        break;
      default:
        break;
    }
  };

  const apis = {
    ...api,
    onSdkSearch,
    onSdkTableHandle
  };

  const resetDetailConfig = (search = {}) => {
    const { name, form, handle } = pageInfo.current;

    // 获取默认初始值
    searchParams.current = {
      ...formUtils.getInitData(form?.formItems),
      ...(commonUtils.isObj(initData) ? initData : {}),
      ...search
    };

    const { btn: rowHandle, acl: rowAcl } = formUtils.getTableHandle(
      handle?.handleItems
    );
    const permissionNames = [];
    let aclCheckPermissionResults = [...rowAcl];

    const schema = commonUtils.buildSchema(
      {
        customCardBody: commonUtils.getFunc(form?.customCardBody, apis),
        title: title || name,
        formConfig: {
          ...formUtils.listTranslSchema(form?.formItems, 4), // 第二个参数需配置
          formData: searchParams.current
        },
        actionConfig: {
          showCount: parseInt(handle?.showCount || "2"), // 按键显示数量
          actionList: rowHandle,
          fixed: "right" // 按键显示位置； 常见右、底中
        }
      },
      apis
    );
    setDetailConfig(schema);

    if (permissionNames.length) {
      postNew(
        getHsfHost() + aclCheckPermissions,
        {
          userId: CP.getCPInfo().extParams?.bucId,
          permissionNames
        },
        "checkPermissionResults",
        {},
        "[object Array]"
      ).then(res => {
        aclCheckPermissionResults = res.data;
        setDetailConfig({ ...schema, aclCheckPermissionResults });
      });
    }
    // 刷新详情
    // 延迟刷新
    setTimeout(onSdkSearch, 350);
    // onSdkSearch();
  };

  return cardConfig ? (
    <CardRender
      loading={loading}
      reqData={reqData.current}
      frConfig={{
        formData,
        onChange: data => setForm(data),
        onValidate: value => (validate.current = value)
      }}
      schema={cardConfig}
    />
  ) : null;
};

export default React.memo(CpDetail);
