import React, { memo, useCallback } from 'react';
import EasyvCardSelect from '@/components/EasyvCardSelect';
import {
  changeDataSourceType,
  updateComponentDataConfig,
  updateUseDataContainer,
} from '@/models/component';
import { RightOutlined } from '@easyv/react-icons';
import { sourceOptions } from 'constants/config';
import { EasySelect } from '@easyv/react-gui';
import DataBox from '../DataBox';
import TableViewEdit from './TableViewEdit';
import DataSourceTypeConfig from './DataSourceTypeConfig';
import EasyvEmpty from '@/components/EasyvEmpty';
import SourceEdit from '@/containers/data-source-list/components/SourceEdit';
import EasyvButton from '@/components/EasyvButton';
import { ComponentItem, DataFrom } from '@/models/component.types';
import { CourseState } from '@/models/course.types';
import isEqual from 'lodash/isEqual';
import { connect } from 'react-redux';
import message from '@/components/message';
import styles from './data-source.less';
import { isEditPage } from '@/utils/utils';

const DataInterface = ({
  sources,
  isPerson,
  useFilter,
  dataType,
  dtableApiTutorial,
  dataConfig,
  changeDataSourceType,
  handleUpdate,
}) => {
  const { config } = dataConfig || {};
  const dataSourceOptions = [{ name: '静态数据', value: 'static' }].concat(
    sourceOptions.filter((i) => (isPerson ? i.value === 'dtableapi' : true)),
  );

  const typeName = dataSourceOptions.find((d) => d.value === dataType)?.name;
  const handlBlur = (_event, editor) => {
    if (editor) {
      try {
        const data = JSON.parse(editor.getValue());
        if (Array.isArray(data)) {
          if (!isEqual(data, dataConfig.data)) {
            handleUpdate({
              data,
            });
          }
        } else {
          message.error('数据必须为数组');
        }
      } catch (error) {
        message.error('数据格式有误，请检查');
      }
    }
  };
  return (
    <div style={{ padding: '0 12px' }}>
      <div className={styles.typeWrap}>
        <label className={styles.label}>数据源类型</label>
        <div style={{ flex: 1 }}>
          <EasySelect
            value={dataType}
            options={dataSourceOptions}
            onChange={async (type) => {
              const res = await changeDataSourceType(type);
              if (isPerson && useFilter && res && type === 'static') {
                handleUpdate({ useFilter: false });
              }
            }}
            placeholder="请选择"
          />
        </div>
      </div>

      {dataType === 'dtableapi' && dtableApiTutorial?.courseUrl && (
        <div style={{ fontSize: '12px', margin: '-18px 0 12px 80px' }}>
          <a href={dtableApiTutorial?.courseUrl} target="_blank" className={styles.course}>
            DTable API使用教程
            <RightOutlined className={styles.right} />
          </a>
        </div>
      )}

      {dataType !== 'static' && (
        <div className={styles.typeWrap} style={{ marginBottom: 16, marginTop: 0, padding: 0 }}>
          <label className={styles.label}>数据源</label>
          <div className={styles.content}>
            <EasySelect
              value={config?.data_id}
              notFoundContent={
                <div style={{ margin: '15px 0' }}>
                  <EasyvEmpty />
                </div>
              }
              placeholder="请选择数据源"
              options={sources
                .filter((d) => d.type === typeName)
                .map((d) => ({ name: d.name, value: d.id }))}
              onChange={(dataId) => handleUpdate({ data: { ...(config || {}), data_id: dataId } })}
            />
          </div>
          <SourceEdit defaultType={dataType}>
            <EasyvButton theme="primary" style={{ width: 64, height: 28, marginLeft: 8 }}>
              新建
            </EasyvButton>
          </SourceEdit>
        </div>
      )}
      {/* 数据源类型为csv且选择了数据源,表格视图编辑 */}
      {dataType === 'csv' && config?.data_id && <TableViewEdit />}
      <DataSourceTypeConfig
        isPerson={isPerson}
        dataType={dataType}
        dataConfig={dataConfig}
        sources={sources}
        handlBlur={handlBlur}
        handleUpdate={handleUpdate}
      />
    </div>
  );
};

const DataSourceSwitch = ({
  dataFrom,
  componentId,
  isPerson,
  useFilter,
  dataType,
  updateComponentDataConfig,
  updateUseDataContainer,
  dataContainers,
  sources,
  dtableApiTutorial,
  dataConfig,
  changeDataSourceType,
}) => {
  const handleUpdate = useCallback(
    (value) => {
      updateComponentDataConfig({ ...value, id: componentId });
    },
    [componentId],
  );

  return isEditPage() ? (
    <EasyvCardSelect
      current={dataFrom}
      onChange={async (current) => {
        const result = await updateUseDataContainer(componentId, current);
        if (
          isPerson &&
          useFilter &&
          result &&
          current === DataFrom.DEFAULT &&
          dataType === 'static'
        ) {
          handleUpdate({ useFilter: false }); // 个人版从数据容器 切换 状态需要手动关闭过滤器
        }
      }}
      style={{
        borderBottom: '1px solid #434956',
      }}>
      <EasyvCardSelect.CardSelectTab name="容器关联">
        <DataInterface
          sources={sources}
          isPerson={isPerson}
          useFilter={useFilter}
          dataType={dataType}
          dtableApiTutorial={dtableApiTutorial}
          dataConfig={dataConfig}
          changeDataSourceType={changeDataSourceType}
          handleUpdate={handleUpdate}
        />
      </EasyvCardSelect.CardSelectTab>
      <EasyvCardSelect.CardSelectTab name="数据接口">
        <div style={{ padding: '0 12px' }}>
          <DataBox dataContainers={dataContainers} />
        </div>
      </EasyvCardSelect.CardSelectTab>
    </EasyvCardSelect>
  ) : (
    <DataInterface
      sources={sources}
      isPerson={isPerson}
      useFilter={useFilter}
      dataType={dataType}
      dtableApiTutorial={dtableApiTutorial}
      dataConfig={dataConfig}
      changeDataSourceType={changeDataSourceType}
      handleUpdate={handleUpdate}
    />
  );
};

const mapStateToProps = ({ sources, componentsById, createApp, user, course }) => {
  const { componentsChildSelected, layersSelected } = createApp;
  const componentId = componentsChildSelected || layersSelected[0];
  const current = componentsById[componentId] as ComponentItem;

  return {
    dataFrom: current.dataFrom || DataFrom.DEFAULT,
    sources: sources.list || [],
    componentId: componentId,
    isPerson: user.isPerson,
    useFilter: current.useFilter, // TODO过滤器开关
    dataType: current.dataType,
    dtableApiTutorial: course?.dtableApiTutorial as CourseState['dtableApiTutorial'],
    dataConfig: current.dataConfigs[current.dataType],
    dataContainers: current.dataContainers || [],
  };
};

const mapDispatchToProps = {
  changeDataSourceType,
  updateComponentDataConfig,
  updateUseDataContainer,
};

function areEqual(props, nextProps) {
  return (
    isEqual(props.dataContainers, nextProps.dataContainers) &&
    isEqual(props.componentId, nextProps.componentId) &&
    isEqual(props.useFilter, nextProps.useFilter) &&
    isEqual(props.dataConfig, nextProps.dataConfig) &&
    isEqual(props.dataFrom, nextProps.dataFrom) &&
    isEqual(props.dataType, nextProps.dataType) &&
    isEqual(props.isPerson, nextProps.isPerson) &&
    isEqual(props.sources, nextProps.sources) &&
    isEqual(props.dtableApiTutorial, nextProps.dtableApiTutorial)
  );
}
export default connect(mapStateToProps, mapDispatchToProps)(memo(DataSourceSwitch, areEqual));
