import React, { forwardRef, useState } from 'react';
import {
  CnList as UICnList,
  CnListItem as UICnListItem,
  CnListProps,
} from '@cainiaofe/cn-ui-m';
import {
  calculateDataSource,
  executeEventWithoutJS,
  getFilterValue,
  isDesignMode,
  setDataToDs,
  executeFunction,
} from '@/common/util/util';
import { ButtonPosition } from '@/type/button-position';
import { dataOriginRequest, dataOriginStatic } from '@/common/util/const';
import useFilterSearchListener from '@/common/hook/useFilterSearchListener';
import {
  transRequestConfigToRemote,
  handleRequestParams,
} from '@/common/manager/request';
import {
  __list_activeKey__,
  __list_currentItem__,
} from '@/common/util/expr-const';

const CnList = forwardRef((props, ref) => {
  if (!UICnList) {
    return null;
  }
  const {
    _context,
    dataFrom,
    events,
    _bindFilter,
    showBorderRadius,
    title,
    _dataSource,
    _dataSourceName,
    itemDescriptionRender,
    pagging,
  } = props || {};
  const state = _context?.state;
  const { dataOrigin } = dataFrom || {};

  const [dataSource, _] = useState(() => {
    if (dataFrom?.dataOrigin === 'static') {
      const result = calculateDataSource({
        dataFrom,
        state,
        _bindFilter,
        _context,
      });
      if (Array.isArray(result)) {
        return result;
      }
    }
    return [];
  });

  const isDesign = isDesignMode(props);

  const extraProps: CnListProps = {
    showBorderRadius,
    pagging,
  };

  if (dataOrigin === dataOriginStatic) {
    extraProps.dataSource = dataSource;
  } else if (dataOrigin === dataOriginRequest) {
    const urlParamsDataSource = _context?.state?.urlParams || {};
    extraProps.requestConfig = transRequestConfigToRemote({
      requestConfig: dataFrom?.requestConfig,
      state,
      recordDataSource: {},
      isDesign,
      formatParam: (() => {
        return function (data) {
          const filterValue =
            getFilterValue({
              filterConfig: {
                _bindFilter,
              },
              _context,
            }) || {};

          const realParams =
            handleRequestParams(dataFrom?.requestConfig.params, {
              urlParamsDataSource,
              recordDataSource: filterValue,
              state,
              flexibleParams: true,
            }) || {};
          let finalparams = { ...filterValue, ...(data || {}) };
          if (typeof realParams === 'function') {
            finalparams = realParams()
          } else if (Object.keys(realParams).length > 0) {
            finalparams = { ...filterValue, ...(data || {}), ...realParams };
          }
          return finalparams;
        };
      })(),
      needFormatResult: true,
    });

    if (extraProps.requestConfig) {
      extraProps.requestConfig.manual = true;
    }
  }

  useFilterSearchListener({
    _bindFilter,
    sendRequest: () => {
      if (dataFrom?.dataOrigin === dataOriginRequest) {
        ref?.current?.refresh?.();
      }
    },
    _context,
  });

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

  const executeEvent = (e, item) => {
    if (!isDesign) {
      setDataSource({
        [__list_currentItem__]: item,
        [__list_activeKey__]: item?.key,
      });
      executeEventWithoutJS({
        eventType: 'onListItemClick',
        events,
        _context,
        position: ButtonPosition.listItemClick,
        recordDataSource: item,
      });
    }
  };

  return (
    <UICnList
      ref={ref}
      {...extraProps}
      renderItem={(item, index) => {
        const key = item.key || index;
        return (
          <UICnListItem
            key={key}
            {...item}
            description={
              typeof itemDescriptionRender === 'function'
                ? executeFunction(itemDescriptionRender, item, index, state)
                : item.description
            }
            onClick={(e) => {
              executeEvent(e, item);
            }}
          />
        );
      }}
    />
  );
});

CnList.displayName = 'CnList';
export default CnList;
