import React from 'react';
import { CnTab as UICnTab, CnTabItem as UICnTabItem } from '@cainiaofe/cn-ui-m';
import './view.scss';
import isFunction from 'lodash/isFunction';
import {
  calculateTextExprValue,
  executeFunction,
  executeObjectExpr,
  getRealResponse,
  isDesignMode,
  isEmptyButNotZero,
  isRequestConfig,
  setDataToDs,
} from '@/common/util/util';
import isPlainObject from 'lodash/isPlainObject';
import { __tab_activeKey__ } from '@/common/util/expr-const';
import { getButtonAction } from '@/common/manager/button';
import { CnFilterOnChange, onEvent } from '@/common/util/event-name';
import { makeRequest } from '@/common/manager/request';
import { ButtonPosition } from '@/type/button-position';

class CnTab extends React.Component {
  constructor(props) {
    super(props);
    const defaultActiveKey = this.getDefaultActiveKey();
    this.state = {
      activeKey: defaultActiveKey,
      itemList: [],
    };
    this.setDataSource({
      [__tab_activeKey__]: defaultActiveKey,
    });
  }

  setDataSource = (data) => {
    if (data) {
      const { _context, _dataSource, _dataSourceName } = this.props;
      setDataToDs({
        _context,
        _dataSource,
        _dataSourceName,
        data,
      });
    }
  };

  getDefaultActiveKey = () => {
    const { dataOrigin, items, _context, activeKey } = this.props;
    if (dataOrigin !== 'request') {
      let first;
      if (activeKey) {
        first = calculateTextExprValue(activeKey, {
          state: _context?.state,
          recordDataSource: {},
        });
      } else {
        if (Array.isArray(items)) {
          for (const item of items) {
            const { primaryKey, hidden } = item;
            if (primaryKey) {
              const isHidden = executeObjectExpr(
                hidden,
                {},
                {},
                _context?.state,
              );
              if (isHidden !== true) {
                first = primaryKey;
                break;
              }
            }
          }
        }
        if (first === undefined) {
          first = items[0]?.primaryKey;
        }
      }
      return first;
    }
  };

  getItems = () => {
    const { items = [] } = this.props;
    const { itemList = [] } = this.state;
    const { dataOrigin } = this.props;
    if (dataOrigin === 'request') {
      return itemList;
    }
    return items;
  };

  getUrlParams = () => {
    const { _context } = this.props;
    return _context?.state?.urlParams || {};
  };

  getData = () => {
    const isDesign = isDesignMode(this.props);
    const { dataOrigin, requestConfig, _context } = this.props;
    if (dataOrigin === 'request' && isRequestConfig(requestConfig)) {
      makeRequest({
        buttonConfig: {
          options: {
            requestConfig,
          },
        },
        urlParamsDataSource: this.getUrlParams(),
        recordDataSource: {},
        state: _context?.state || {},
        needSuccessToast: false,
        isDesign,
      }).then((res) => {
        const res2 = getRealResponse(res);
        const { success, data } = res2;
        if (success) {
          if (isPlainObject(data)) {
            const { list, activeKey: originalActiveKey } = data;
            const state = {
              itemList: [],
            };
            if (Array.isArray(list) && list.length > 0) {
              const newList = list.map((item) => {
                if (isPlainObject(item)) {
                  const { label, value, title, primaryKey } = item;
                  if (isEmptyButNotZero(title) && label) {
                    item.title = label;
                  }
                  if (isEmptyButNotZero(primaryKey) && value) {
                    item.primaryKey = value;
                  }
                }
                return { ...item };
              });
              let activeKey = originalActiveKey;
              if (isEmptyButNotZero(activeKey)) {
                activeKey = newList[0]?.primaryKey;
              }
              state.itemList = newList;
              if (activeKey !== undefined) {
                state.activeKey = activeKey;
                this.setDataSource({
                  [__tab_activeKey__]: activeKey,
                });
              }
            }
            this.setState(state);
            this.executeEvent({
              eventType: 'onTabRequestFinish',
              activeKey: state.activeKey,
            });
          }
        }
      });
    }
  };

  componentDidMount() {
    this.getData();
    onEvent(CnFilterOnChange, (tableInfo) => {
      this.forceUpdate();
    });
  }

  renderTitle(title, props) {
    const { renderBadge = () => null } = this.props;
    const badge = renderBadge(props);
    if (!badge) {
      return title;
    }
  }

  clickTab = (tabKey) => {
    const items = this.getItems();
    const current = items.find((item) => {
      if (item) {
        return item.primaryKey === tabKey;
      }
    });
    if (current) {
      const { optType, url, redirectType } = current;
      if (optType === 'link' && url && redirectType) {
        if (redirectType === 'current') {
          location.href = url;
        } else if (redirectType === 'open') {
          window.open(url);
        }
      }
    }
  };

  renderTabItems() {
    const items = this.getItems();
    const { children, _context, dataOrigin, _customRenderTabItem } = this.props;
    let tabItems = [];
    if (dataOrigin === 'request') {
      if (items.length > 0) {
        tabItems = items.map((item) => {
          const { title, primaryKey, disabled } = item;
          let realTitle = title;
          if (typeof _customRenderTabItem === 'function') {
            const tempTitle = executeFunction(
              _customRenderTabItem,
              item,
              _context?.state,
            );
            if (tempTitle) {
              realTitle = tempTitle;
            }
          }
          return (
            <UICnTabItem
              title={realTitle}
              key={primaryKey}
              disabled={disabled}
            />
          );
        });
      }
    } else {
      const isDesign = isDesignMode(this.props);
      const safeChildren = Array.isArray(children) ? children : [children];
      safeChildren.forEach((child, index) => {
        if (!child) {
          return null;
        }
        let childProps;
        if (Array.isArray(items) && items[index]) {
          childProps = items[index];
        } else if (child.props.componentSchema) {
          childProps = child.props.componentSchema.props;
        } else {
          childProps = child.props;
        }
        const hidden = executeObjectExpr(
          childProps?.hidden,
          {},
          {},
          _context?.state,
        );
        if (hidden === true) {
          return null;
        }
        const title = this.renderTitle(childProps.title, childProps);
        tabItems.push(
          <UICnTabItem
            title={title}
            key={childProps.primaryKey}
            disabled={childProps.disabled}
            closeable={childProps.closeable}
          >
            {child}
          </UICnTabItem>,
        );
      });
    }

    return tabItems;
  }

  findItem(activeKey) {
    const items = this.getItems();
    let ret;
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (
        activeKey === item.primaryKey ||
        (item.customKey && item.customKey === activeKey)
      ) {
        ret = item;
        break;
      }
    }
    return ret ? { ...ret, customKey: ret.customKey || ret.primaryKey } : null;
  }

  setTabActiveKey = (activeKey) => {
    this.setDataSource({
      [__tab_activeKey__]: activeKey,
    });
    this.setState({
      activeKey,
    });
    this.executeEvent({
      eventType: 'onChange',
      activeKey,
    });
    // const { onTabChange, onChange, fieldId, traceable } = this.props;
    // const activeItem = this.findItem(activeKey);
    // const key = activeItem?.customKey;
    // const changeHandle = onTabChange || onChange;
    // this.setState(
    //   {
    //     activeKey: activeItem.primaryKey,
    //   },
    //   () => {
    //     if (isFunction(changeHandle)) {
    //       const activeIndex = this.indexesCache.indexOf(key) + 1;
    //       changeHandle(activeIndex, key, activeItem);
    //     }
    //   },
    // );
  };

  executeEvent = (config) => {
    const { eventType, activeKey } = config;
    const { events, _context } = this.props;
    if (Array.isArray(events) && events.length > 0) {
      for (const item of events) {
        const { name: eventName, optType, flowList } = item;
        if (eventName === eventType) {
          const action = getButtonAction({
            ...item,
            position: ButtonPosition.tabEvent,
          });
          if (typeof action === 'function') {
            action({
              buttonConfig: {
                ...item,
                position: ButtonPosition.tabEvent,
                options: {
                  ...item,
                },
              },
              position: ButtonPosition.tabEvent,
              state: _context?.state,
              urlParamsDataSource: this.getUrlParams(),
              _context,
              recordDataSource: activeKey,
            });
          }
        }
      }
    }
  };

  render() {
    const {
      shape,
      size,
      excessMode,
      tabPosition,
      contentPadding,
      unmountInactiveTabs,
      extraRender,
      tabRender,
      onClose,
      // items,
      children,
      // lazyLoad = true,
      dataOrigin,
      className,
      tabAlign,
      type,
    } = this.props;

    const { activeKey } = this.state;
    const isDesign = isDesignMode(this.props);
    const tabProps = {
      type,
      animation: false,
      shape,
      size,
      activeKey,
      excessMode,
      tabPosition,
      unmountInactiveTabs,
      onClose,
      className,
      tabAlign,
    };

    // if (contentPadding) {
    //   tabProps.contentStyle = {
    //     padding: contentPadding,
    //   };
    // }

    if (isFunction(extraRender)) {
      tabProps.extra = extraRender();
    }

    if (isFunction(tabRender)) {
      tabProps.tabRender = tabRender;
    }
    if (isDesign && dataOrigin === 'request') {
      return (
        <>
          <UICnTab {...tabProps}>
            <UICnTabItem
              title={'动态Tab，请到预览页面查看'}
              key={'dynamic_tab'}
            />
          </UICnTab>
        </>
      );
    }
    return (
      <UICnTab
        onChange={this.setTabActiveKey}
        {...tabProps}
        onClick={this.clickTab}
      >
        {this.renderTabItems()}
      </UICnTab>
    );
  }
}
CnTab.displayName = 'CnTab';

class CnTabItem extends React.Component {
  static displayName = 'CnTabItem';

  render() {
    return <>{this.props.children}</>;
  }
}
export default [CnTab, CnTabItem];

export { CnTab, CnTabItem };
