import React, { useRef, useState, useEffect } from "react";
import { Spin } from "antd";
import { isArray, isString } from "lodash";
import CpBase from "./CpBase";
import { handleAppParams, postNew } from "./../net/request";
import * as commonUtils from "./../utils/commonUtils";
import { CP } from "..";

import "./index.css";

const displayName = "CpComposite";
const CpComposite = props => {
  const {
    schema,
    defaultSchemaMap,
    initData,
    refreshSchema,
    name,
    title,
    api = {},
    filterParams,
    widgets,
    ...otherProps
  } = props;

  const { url, okPath = "data", table } = schema;

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

  const [loading, setLoading] = useState(false);
  // 首次渲染不因 initData 请求
  const hasPageSchema = useRef(false);
  // 用于上下文传递， 作为子页面的initData
  const [pageData, setPageData] = useState(null);
  // 页面级接口请求入参 事件回调需要useRef
  const searchParams = useRef({});

  // 赋值页面上下文数据   initData变更需刷新页面
  useEffect(() => {
    // 此处有待调优
    if (hasPageSchema.current) {
      onSdkSearch(initData);
    } else {
      // 页面首次渲染
      onSdkSearch(initData);
    }
  }, [initData]);

  /**
   * 必备函数
   * 表格请求函数
   * 暂支持post请求，因get用长度限制，避免过多参数
   * @param params 搜索项信息
   */
  const onSdkSearch = params => {
    const _params = {
      ...searchParams.current, // 已有页面信息
      ...params // 新入参信息，常见为：覆盖已有页面信息
    };
    // 是否有 请求配置
    if (url) {
      setLoading(true);
      requestFunc(
        commonUtils.getUrl(url),
        handleAppParams(_params, filterParams),
        okPath
      )
        .then(({ data, exactData, ...other }) => {
          if (!data) {
            throw new Error(
              "请求错误，自行处理，该请求可自行设计，只要返回正确数据格式即可！"
            );
          } else {
            // 将页面数据作为 子页面的initData
            let resData = exactData || data;
            // 当返回数据是数组时， 嵌套一层
            const extInitData =
              isArray(resData) || isString(resData)
                ? { data: resData }
                : resData;
            // 将页面数据作为 子页面的initData
            setSearchParams({ ..._params, ...extInitData });
          }
        })
        .catch(err => {
          console.error("err", err, displayName);
        })
        .finally(() => {
          setLoading(false);
        });
    } else {
      // 无请求配置， 直接设置页面级上下文数据
      setSearchParams(_params);
    }
  };

  /**
   * 设置页面级上下文数据
   * @param {页面级入参} params
   */
  const setSearchParams = params => {
    // 同步事件params
    searchParams.current = params;
    // 刷新所有子页面
    setPageData(params);
  };

  /**
   * 获取自组件的分子、分母
   * @param {分数字符串} fraction
   * @returns 默认 [1,1]即100%宽度
   */
  const getFraction = fraction => {
    try {
      return fraction.split("-").map(s => parseInt(s));
    } catch {
      return [1, 1];
    }
  };
  /**
   * 通过分子分母计算出宽度
   * @param {分子} fenZi
   * @param {分母} fenMu
   * @returns 返回组件宽度
   */
  const getWidth = (fenZi, fenMu) => {
    return `calc(100%*${fenZi / fenMu} - ${fenMu - fenZi}*20px/${fenMu})`;
  };

  const childRender = renderInfo => {
    const {
      pageType,
      name,
      title,
      key,
      sdkRender,
      fraction,
      height
    } = renderInfo;
    // 模块name  支持 不展示模块标题
    const pageTitle = title === "null-Title" ? "" : title || name;
    // 用于计算宽度。 默认100%  1/1
    const [fenZi, fenMu] = getFraction(fraction);
    // 通过分子分母计算出宽度
    const width = getWidth(fenZi, fenMu);
    // 获取自定义渲染函数
    const renderFunc = commonUtils.getFunc(sdkRender, api);
    return (
      <div
        style={{
          width, // 通过fraction占比设置
          height: height || "auto", //  输入框设置，设置出错不兼容
          overflow: "scroll"
        }}
      >
        {pageType === "sunmao_composite" || pageType === "sunmao_tabs" ? (
          <div>暂不支持嵌套复杂详情页，请重新配置该部分实现</div>
        ) : renderFunc ? (
          renderFunc(renderInfo, pageData)
        ) : (
          <CpBase
            flag={key}
            initData={pageData}
            api={api}
            widgets={widgets}
            defaultSchemaMap={defaultSchemaMap}
            title={pageTitle}
            filterParams={filterParams}
            tableProps={{ title: pageTitle }}
            {...otherProps}
          />
        )}
      </div>
    );
  };

  return !!pageData ? (
    <Spin spinning={loading}>
      <div className="sunmao_composite">
        {table.columnItems.map(childRender)}
      </div>
    </Spin>
  ) : (
    <div>页面构建中...</div>
  );
};

export default CpComposite;
