import React, { useState, useEffect } from 'react';
import { NodeGroup } from 'react-move';
import { interpolate, interpolateTransformSvg } from 'd3-interpolate';
import MachineRow from '../MachineRow';
import styles from './index.less';

type MachineTableProps = {
  machineStatusArray: MachineConnectivity.MachineStatus[];
  conditionKey: string;
  rowMovingTime: number;
};

type RowData = {
  key: string;
  machineStatusArray: MachineConnectivity.MachineStatus[];
};

const convertData = (
  machineStatusArray: MachineConnectivity.MachineStatus[],
  cellCount: number,
) => {
  const machineStatusArrayTemp = machineStatusArray
    .slice()
    .sort((a, b) => a.machineName.localeCompare(b.machineName));
  const displayData: RowData[] = [];
  let rowData: RowData = { machineStatusArray: [], key: '' };
  machineStatusArrayTemp.forEach((m) => {
    if (rowData.machineStatusArray.length >= cellCount) {
      displayData.push(rowData);
      rowData = { machineStatusArray: [], key: '' };
    }
    rowData.machineStatusArray.push(m);
    rowData.key = rowData.key + '|' + m.machineName;
  });
  if (rowData.machineStatusArray.length > 0) {
    if (rowData.machineStatusArray.length < cellCount) {
      let left = cellCount - rowData.machineStatusArray.length;
      while (left > 0) {
        rowData.machineStatusArray.push({
          machineName: `@${left}`,
          mode: '',
          program: '',
          runTime: 0,
        });
        left--;
      }
    }
    displayData.push(rowData);
  }
  return displayData;
};

const MachineTable: React.FC<MachineTableProps> = ({
  machineStatusArray,
  conditionKey,
  rowMovingTime,
}) => {
  const cellCount = 4;
  const rowHight = 260;
  const displayCount = 3;

  const [data, setData] = useState<RowData[]>([]);
  const [displayData, setDisplayData] = useState<RowData[]>([]);
  const [displayAt, setDisplayAt] = useState(0);
  const [lastConditionKey, setLastConditionKey] = useState('');

  const updateDisplayData = (da: number, sData: RowData[]) => {
    let endAt1 = da + displayCount;
    let endAt2 = 0;
    if (endAt1 > sData.length) {
      endAt2 = endAt1 - sData.length;
      endAt1 = sData.length;
    }
    const ret = sData.slice(da, endAt1);
    if (sData.length > displayCount) {
      sData.slice(0, endAt2).forEach((i) => ret.push(i));
    }
    setDisplayData(ret);
  };

  useEffect(() => {
    const dataTemp = convertData(machineStatusArray, cellCount);
    setData(dataTemp);
    if (lastConditionKey !== conditionKey) {
      setLastConditionKey(conditionKey);
      setDisplayAt(0);
      updateDisplayData(0, dataTemp);
    }
  }, [conditionKey, lastConditionKey, machineStatusArray]);

  useEffect(() => {
    const t = setInterval(() => {
      let da = 0;
      if (data.length > displayCount) {
        da = displayAt + 1;
        if (da >= data.length) {
          da = 0;
        }
      }
      setDisplayAt(da);
      updateDisplayData(da, data);
    }, rowMovingTime * 1000);
    return () => {
      clearTimeout(t);
    };
  }, [data, displayAt, rowMovingTime]);

  return (
    <div className={styles.content_machs}>
      <NodeGroup
        data={displayData}
        keyAccessor={(d) => d.key}
        start={(d, i) => {
          return { y: i * rowHight, opacity: 0 };
        }}
        enter={() => {
          return { opacity: [1], timing: { duration: 1000 } };
        }}
        update={(d, i) => {
          return { y: [i * rowHight], opacity: [1], timing: { duration: 1000 } };
        }}
        leave={() => {
          return { y: [-rowHight], opacity: [0], timing: { duration: 1000 } };
        }}
        interpolation={(begValue, endValue, attr) => {
          if (attr === 'transform') {
            return interpolateTransformSvg(begValue, endValue);
          }
          return interpolate(begValue, endValue);
        }}
      >
        {(nodes) => (
          <div className={styles.rowcontent}>
            {nodes.map((node) => (
              <MachineRow
                machineStatusArray={node.data.machineStatusArray}
                key={node.key}
                style={{
                  position: 'absolute',
                  left: 0,
                  top: 0,
                  width: '100%',
                  transform: `translate(0px, ${node.state.y}px)`,
                  opacity: node.state.opacity,
                }}
              />
            ))}
          </div>
        )}
      </NodeGroup>
    </div>
  );
};

export default MachineTable;
