import React, { useEffect, useState, useRef } from 'react';
import { Form, Select, Spin, Tooltip, Checkbox, Typography } from 'antd';

import { dispatch, dispatchLatest } from '../../../../model'; 
import { formatVersionDate } from '../../../../util';
import VersionCompareHeader from './VersionCompareHeader';
import VersionCompareTable from './VersionCompareTable';
import VersionCompareIndex from './VersionCompareIndex';
import FilterColumnAction from './FilterColumnAction';

import './VersionCompare.less';
import VersionCompareProcess from './VersionCompareProcess';

const { Text, Paragraph } = Typography;
const { Option } = Select;
const defaultColumnTitles = ['序号', '中文名称', '英文名称', '类型', '业务含义'];

const VersionCompare = (props) => {

  const { id } = props;

  const [ basicVersion, setBasicVersion ] = useState('');
  const [ basicVersions, setBasicVersions ] = useState([]);
  const [ incVersion, setIncVersion ] = useState('');
  const [ incVersions, setIncVersions ] = useState([]);
  const [ loading, setLoading ] = useState(false);
  const [ compareData, setCompareData ] = useState(null);
  const [ loadingCompare, setLoadingCompare ] = useState(false);
  const [ onlyShowChange, setOnlyShowChange ] = useState(true);
  const [ attrFilterColumns, setAttrFilterColumns ] = useState([]);
  const [ attrSelectedTitles, setAttrSelectedTitles ] = useState(defaultColumnTitles);
 
  const attrColumnsRef = useRef([]);

  useEffect(() => {
    if ((id||'') !== '') {
      getVersions();
    }

    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ id ])

  const getVersions = () => {
    setLoading(true);
    dispatch({
      type: 'datamodel.getVersions',
      payload: {
        params: {
          id
        }
      },
      callback: data => {
        setLoading(false);
        const newData = [];
        (data||[]).forEach((item, index) => {

          let name = item.name||'';
          name = name + '_' + formatVersionDate(item.ts);
          if (index === 0 && item.id !== '-1') {
            name = name+'(当前版本)';
          }
          if (index === 1 && data[0].id === '-1') {
            name = name+'(当前版本)';
          }

          newData.push({ id: item.id, name });
        })

        setBasicVersions(newData);

        if (newData.length >= 2) {
          const defaultBasicVersion = newData[1].id;
          const defaultIncVersion = newData[0].id;
          setBasicVersion(defaultBasicVersion);
          let index = -1;
          (newData||[]).forEach((version, i) => {
            if (version.id === defaultBasicVersion) {
              index = i;
            }
          })

          setIncVersions((newData||[]).slice(0, index));
          setIncVersion(defaultIncVersion);
          getCompare(defaultBasicVersion, defaultIncVersion);
        }
      },
      error: () => {
        setLoading(false);
      }
    })
  }

  const onBasicChange = (value) => {
    setBasicVersion(value);
    setIncVersion('');

    let index = -1;
    (basicVersions||[]).forEach((version, i) => {
      if (version.id === value) {
        index = i;
      }
    })

    setIncVersions((basicVersions||[]).slice(0, index));
  }

  const onIncChange = (value) => {
    setIncVersion(value);
    getCompare(basicVersion, value);
  }

  const getCompare = (value1=basicVersion, value2=incVersion, value3=onlyShowChange) => {
    setLoadingCompare(true);
    dispatchLatest({
      type: 'datamodel.compare',
      payload: {
        params: {
          id,
          versionId1: value1,
          versionId2: value2,
          includeSame: !value3
        }
      },
      callback: data => {
        setLoadingCompare(false);
        setCompareData(data);

        const newAttrOptionColumns = [];
        (data?.heads?.columnHead||[]).forEach((item, index) => {
          newAttrOptionColumns.push({
            title: item||'',
            dataIndex: `column${index}`,
            render: (attrValue, record, index) => {
    
              let stateClassName = '';
              if (attrValue?.state==='ADD' || attrValue?.state==='UPDATE') {
                stateClassName = 'add';
              } else if (attrValue?.state === 'DELETE') {
                stateClassName = 'delete';
              }
    
              return (
                <Paragraph>
                  <Tooltip title={attrValue?.value||''}>
                    <Text className={stateClassName} ellipsis={true}>{attrValue?.value||''}</Text>
                  </Tooltip>
                </Paragraph>
              );
            },
            width: (item==='序号')?60: 150,
            ellipsis: true,
            option: true,
          });
        })

        const newAttrColumns = [...newAttrOptionColumns, { 
          title: <FilterColumnAction columns={newAttrOptionColumns} defaultSelectedKeys={defaultColumnTitles} onChange={onFilterChange} />,
          dataIndex: 'columnFilter',
          render: (_, record, index) => {
            return '';
          },
          width: 40,
          ellipsis: true,
          option: false
        }];

        attrColumnsRef.current = newAttrColumns;

        const newFilterColumns = newAttrColumns.filter(column => column.option===false || attrSelectedTitles.indexOf(column.title) !== -1);

        setAttrFilterColumns(newFilterColumns);
      },
      error: () => {
        setLoadingCompare(false);
      }
    })
  }

  const onFilterChange = (values) => {
    const newFilterColumns = attrColumnsRef.current.filter(column => column.option===false || values.indexOf(column.title) !== -1);

    setAttrSelectedTitles(values);
    setAttrFilterColumns(newFilterColumns);
  }

  const onOnlyShowChange = (e) => {
    setOnlyShowChange(e.target.checked);
    if (basicVersion!=='' && incVersion!=='') {
      getCompare(basicVersion, incVersion, e.target.checked);
    }
  }

  return (
    <div className='model-version-compare'>
      <Form layout='inline'>
        <Form.Item label='基线版本'>
          <Select loading={loading} value={basicVersion} style={{ width: 300 }} onChange={onBasicChange}  >
          {
            (basicVersions||[]).map((version, index) => {

              if (index === 0) {
                return (
                  <Option key={index} value={version.id||''} disabled={true}>
                    <Tooltip title={'最近版本只能在增量版本中被选中'}>
                    {version.name||''}
                    </Tooltip>
                  </Option>
                )
              };

              return (
                <Option key={index} value={version.id||''}>
                {version.name||''}
                </Option>
              );

            })
          }
          </Select>
        </Form.Item>
        <Form.Item label='增量版本'>
          <Select value={incVersion} style={{ width: 300 }} disabled={basicVersion===''} onChange={onIncChange}>
          {
            (incVersions||[]).map((version, index) => {
              return (
                <Option key={index} value={version.id||''}>{version.name||''}</Option>
              );
            })
          }
          </Select>
        </Form.Item>
        <Form.Item>
          <Checkbox onChange={onOnlyShowChange} checked={onlyShowChange}>仅显示差异</Checkbox>
        </Form.Item>
      </Form>

      <div className='py-5'>    
        <Spin spinning={loadingCompare} >
        {
          compareData && <div className='flex'>
            <div style={{ flex: 1, borderRight: '1px solid #EFEFEF', paddingRight: 10, overflow: 'hidden'}}>
              <VersionCompareHeader data={compareData} />
              <VersionCompareTable data={compareData} columns={attrFilterColumns} />
              <VersionCompareIndex data={compareData} />
              <VersionCompareProcess data={compareData} />
            </div>
            <div style={{ flex: 1, paddingLeft: 10, overflow: 'hidden'}}>
              <VersionCompareHeader data={compareData} direction='right' />
              <VersionCompareTable data={compareData} columns={attrFilterColumns} direction='right' />
              <VersionCompareIndex data={compareData} direction='right' />
              <VersionCompareProcess data={compareData} direction='right' />
            </div>
          </div>
        }
        </Spin>
      </div>
    </div>
  );
}

export default VersionCompare;