import React, { useCallback, useMemo, useContext, useEffect } from 'react';
import { connect } from 'react-redux';
import { Row, Col, Tag, Tooltip } from '@easyv/antd';
import message from 'components/message';
import AceEditorBox from '../../ScreenConfig/AceEditorBox';
import SQL from './SQL';
import API from './API';
import isEqual from 'lodash/isEqual';
import { getTopScreenId } from 'utils/screen';
import EasyvEmpty from 'components/EasyvEmpty';
import { sourceOptions, dtableOptions } from 'constants/config';
import SourceEdit from 'containers/data-source-list/components/SourceEdit';
import styles from './ComponentDataSource.less';
import { Checkbox, EasySelect, Select, EasyNumber } from '@easyv/react-gui';
import QuestionCircleOutlined from '@ant-design/icons/QuestionCircleOutlined';
import classnames from 'classnames';
import EasyvButton from 'components/EasyvButton';
import { isAppPage, scrollChangeSelectBlur } from 'utils/utils';
import { getFilterScreenId } from 'models/create-app';
import { DataContext } from './Context/index';
import { RightOutlined } from '@easyv/react-icons';
import {
  changeDataSourceType,
  updateComponentDataConfig,
  updateContainerFilter,
} from 'models/data-container';
import DTable from './DTable';
import { CourseState } from '@/models/course.types';

const { Option } = Select;
let dataSourceOptions = [{ name: '静态数据', value: 'static' }].concat(sourceOptions);

const productVersionUpdateNum = {
  saas_personal: {
    min: 30,
    name: '个人版',
  },
  saas_basic: {
    min: 30,
    name: '基础版',
  },
  saas_advanced: {
    min: 10,
    name: '高级版',
  },
  saas_vip: {
    min: 3,
    name: '尊享版',
  },
  local: {
    min: 1,
    name: '运行平台',
  },
};

function ComponentDataSource({
  sources = [],
  filterResult = {},
  filters = [],
  productVersion,
  isPerson = false,
  dtableApiTutorial,
  updateComponentDataConfig,
  changeDataSourceType,
  updateContainerFilter,
}: {
  dtableApiTutorial: CourseState['dtableApiTutorial'];
  filterResult: {
    [x: string]: (string | number)[];
  };
  filters: any[];
  productVersion: 'saas_basic' | 'saas_advanced' | 'saas_vip';
  sources: any;
  isPerson: boolean;
  updateComponentDataConfig: (param) => any;
  changeDataSourceType: (param) => any;
  updateContainerFilter: (param) => any;
}) {
  const isAppEdit = isAppPage();
  const { onOpenFilter, onSetEdit, editItem } = useContext(DataContext);
  const {
    id,
    filters: usedFilters,
    useFilter,
    dataConfigs,
    autoUpdate,
    dataType,
  } = editItem.data || {};
  const dataConfig = dataConfigs?.[dataType];

  useEffect(() => {
    //监听某一个元素的滚动条 隐藏select
    document
      .querySelector('#data-container-config')
      ?.addEventListener('scroll', scrollChangeSelectBlur);
    return () => {
      document
        .querySelector('#data-container-config')
        ?.removeEventListener('scroll', scrollChangeSelectBlur);
    };
  }, [scrollChangeSelectBlur]);

  const handleUpdate = useCallback(
    (value) => {
      updateComponentDataConfig({ ...value, dataContainerId: id });
    },
    [id],
  );

  if (isPerson) {
    dataSourceOptions = dtableOptions;
  }
  const autoUpdateNum = productVersionUpdateNum[productVersion];

  const typeName = dataSourceOptions.find((d) => d.value === dataType)?.name;
  const selectOptions = useMemo(() => {
    return sources.filter((d) => d.type === typeName).map((d) => ({ name: d.name, value: d.id }));
  }, [sources, typeName]);

  if (!id) {
    return null;
  }
  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('数据格式有误，请检查');
      }
    }
  };

  // 数据源配置面板
  const getTypeConfig = () => {
    switch (dataType) {
      case 'static':
        return (
          <AceEditorBox
            height={'200px'}
            onBlur={handlBlur}
            value={JSON.stringify(dataConfig.data, null, '\t')}
          />
        );
      case 'csv':
        return null;
      case 'oracle':
      case 'mssql':
      case 'mysql':
      case 'postgresql':
      case 'clickhouse':
      case 'damengdb':
      case 'db2':
        return <SQL onChange={handleUpdate} dataConfig={dataConfig.config} />;
      case 'api':
      case 'apiGateway':
      case 'dtInsight':
        return (
          <API
            type={dataType}
            onChange={handleUpdate}
            dataList={sources}
            dataConfig={dataConfig.config}
          />
        );
      case 'dtableapi':
        return <DTable onChange={handleUpdate} dataConfig={dataConfig.config} />;
    }
  };
  const { data = [], config = {} } = dataConfig;

  const topScreenId = getTopScreenId();
  const filterScreenId = getFilterScreenId();

  // 当前组件/控件 过滤器
  const currentFilters = usedFilters
    // .filter((d) => d.enable)
    .map((d) => filters.find((o) => o.id === d.id))
    .filter((d) => d);

  // 属于当前空间 && 当前控件没选择过
  const leaveFilterOptions = filters
    .filter((d) => !usedFilters.find((o) => o.id === d.id))
    ?.filter((d) => d && d.screenId === (isAppEdit ? filterScreenId : topScreenId));

  // 过滤器处理后的数据
  const resultData = useFilter ? filterResult[id] || {} : data;

  return (
    <div className={styles.content}>
      <div className={styles.dataSourceContainer}>
        <div className={styles.typeWrap}>
          <label className={styles.label}>数据源类型</label>
          <div style={{ flex: 1 }}>
            <EasySelect
              value={dataType}
              options={dataSourceOptions}
              onChange={(type) => {
                changeDataSourceType({
                  containerId: id,
                  type,
                });
              }}
              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={selectOptions}
                onChange={(dataId) => handleUpdate({ data: { ...config, data_id: dataId } })}
              />
            </div>
            <SourceEdit defaultType={dataType}>
              <EasyvButton theme="primary" style={{ width: 64, height: 26, marginLeft: 8 }}>
                新建
              </EasyvButton>
            </SourceEdit>
          </div>
        )}

        {getTypeConfig()}

        <div className={styles.filter}>
          <Checkbox
            checked={useFilter}
            onChange={(e) => handleUpdate({ useFilter: e.target.checked })}>
            数据过滤器:
          </Checkbox>
          {usedFilters.length > 0 ? (
            <span className={styles.tip}>
              已添加
              <i
                style={{
                  fontStyle: 'normal',
                  color: '#2491F7',
                }}>
                {usedFilters.length}
              </i>
              个过滤器
            </span>
          ) : (
            <span>当前未添加过滤器</span>
          )}
        </div>
        <div className={styles.filterSelect}>
          <Select
            showSearch
            notFoundContent={
              <div style={{ margin: '40px 0' }}>
                <EasyvEmpty />
              </div>
            }
            value="请选择过滤器"
            optionFilterProp="title"
            onChange={async (value) => {
              const result = await updateContainerFilter({
                containerId: editItem.data?.id,
                id,
                type: 'bind',
                filterId: value,
              });
              result &&
                onSetEdit({
                  type: editItem.type,
                  data: result,
                });
            }}
            placeholder="请选择过滤器">
            {leaveFilterOptions.map((e: any) => {
              return (
                <Option key={e.id} title={e.name} value={e.id}>
                  {e.name}
                </Option>
              );
            })}
          </Select>
          <div
            className={styles.addIcon}
            onClick={() => {
              // add
              onOpenFilter({
                type: 'create',
                data: {
                  id: id,
                  createCode: true,
                  useFilter,
                  usedFilters: usedFilters,
                  originData: data,
                },
              });
            }}>
            <i className="icon iconfont icon-icon_add"></i>
          </div>
        </div>
        <div className={styles.filterRow}>
          <Row gutter={5}>
            {currentFilters.splice(0, 4).map((e: any, i: number) => {
              let Dom = <></>;
              switch (i) {
                case 0:
                case 1:
                case 2:
                  Dom = (
                    <Col key={e.id} className={styles.colItem} span={12}>
                      <Tag
                        title={e.name}
                        className={styles.tag}
                        onClick={() => {
                          onOpenFilter({
                            type: 'edit',
                            data: {
                              id: id,
                              createCode: e.id,
                              useFilter,
                              usedFilters: usedFilters,
                              originData: data,
                            },
                          });
                        }}>
                        {e.name}
                      </Tag>
                    </Col>
                  );
                  break;
                case 3:
                  Dom = (
                    <Col span={12} key={e.id} className={styles.colItem}>
                      <Tag
                        className={classnames(styles.tag, styles.more)}
                        onClick={() => {
                          onOpenFilter({
                            type: 'view',
                            data: {
                              id: id,
                              useFilter,
                              usedFilters: usedFilters,
                              originData: data,
                            },
                          });
                        }}>
                        查看更多
                      </Tag>
                    </Col>
                  );
              }
              return Dom;
            })}
          </Row>
        </div>
      </div>
      <div className={styles.autoUpdate}>
        <Checkbox
          checked={autoUpdate.isAuto}
          onChange={(e) =>
            handleUpdate({
              autoUpdate: {
                ...autoUpdate,
                isAuto: e.target.checked,
              },
            })
          }>
          自动更新
        </Checkbox>
        {autoUpdate.isAuto && (
          <Tooltip
            title={
              window.appConfig.LOCAL
                ? '为保障产品使用流畅性，数据更新频率不得低于1s。'
                : '为保障产品使用流畅性，基础版、高级版、尊享版数据更新频率最小值分别为30s、10s、3s。'
            }>
            <QuestionCircleOutlined className="whiteHover" />
          </Tooltip>
        )}

        {autoUpdate.isAuto && (
          <div style={{ marginLeft: 20 }}>
            每
            <div style={{ display: 'inline-block', width: 88, marginLeft: 6, marginRight: 6 }}>
              <EasyNumber
                min={autoUpdateNum.min || 10}
                value={autoUpdate.interval}
                onChange={(value) => {
                  handleUpdate({
                    autoUpdate: {
                      isAuto: autoUpdate.isAuto,
                      interval: value,
                    },
                  });
                }}
              />
            </div>
            秒请求一次
          </div>
        )}
      </div>

      <div className={styles.resData}>
        <div style={{ marginTop: 32, marginBottom: 16 }}>
          数据响应结果
          <span style={{ color: '#999999', fontSize: '12px' }}>（只读）</span>
        </div>
        <AceEditorBox
          className="dark"
          mode="json"
          theme="twilight"
          width="100%"
          height="400px"
          readOnly={true}
          name="responseData"
          tabSize={2}
          value={JSON.stringify(resultData, null, 2)}
          showGutter={true}
          editorProps={{ $blockScrolling: true }}
          setOptions={{ wrap: true }}
        />
      </div>
    </div>
  );
}

const mapStateToProps = ({ sources, filters, user, dataContainers, course }) => {
  const { userInfo } = user;

  return {
    productVersion: !window.appConfig.LOCAL ? userInfo.edition.id : 'local',
    sources: sources.list,
    filters: filters.list,
    filterResult: dataContainers.filterResult,
    isPerson: user.isPerson,
    dtableApiTutorial: course?.dtableApiTutorial as CourseState['dtableApiTutorial'],
  };
};

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

export default connect(mapStateToProps, mapDispatchToProps)(ComponentDataSource);
