import type { Moment } from 'moment';
import moment from 'moment';
import React, { useEffect, useMemo, useState } from 'react';
import { NodeGroup } from 'react-move';
import { interpolate, interpolateTransformSvg } from 'd3-interpolate';
import styles from './index.less';
import { useCallback } from 'react';

type FevorPanelProps = {
  dtoArray: KANBAN.JiejingProductionScheduleKanbanDto[];
  startTime: Moment;
  endTime: Moment;
  conditionKey: string;
  rowMovingTime: number;
};

type RowData = {
  fevor: string;
  zgh: string;
  quantity: number;
  zpPlan?: Moment;
  zpActual?: Moment;
  zzPlan?: Moment;
  zzActual?: Moment;
  wgPlan?: Moment;
  wgActual?: Moment;
  rkPlan?: Moment;
  rkActual?: Moment;
};

const convertData = (dtoArray: KANBAN.JiejingProductionScheduleKanbanDto[]): RowData[] => {
  return dtoArray.map((item) => ({
    fevor: item.fevor,
    zgh: item.zgh,
    quantity: item.quantity,
    zpPlan: item.zpPlan ? moment(item.zpPlan) : undefined,
    zpActual: item.zpActual ? moment(item.zpActual) : undefined,
    zzPlan: item.zzPlan ? moment(item.zzPlan) : undefined,
    zzActual: item.zzActual ? moment(item.zzActual) : undefined,
    wgPlan: item.wgPlan ? moment(item.wgPlan) : undefined,
    wgActual: item.wgActual ? moment(item.wgActual) : undefined,
    rkPlan: item.rkPlan ? moment(item.rkPlan) : undefined,
    rkActual: item.rkActual ? moment(item.rkActual) : undefined,
  }));
};

const FevorPanel: React.FC<FevorPanelProps> = ({
  dtoArray,
  startTime,
  endTime,
  conditionKey,
  rowMovingTime,
}) => {
  const rowHight = 144;
  const displayCount = 8;

  const [data, setData] = useState<RowData[]>([]);
  const [displayData, setDisplayData] = useState<RowData[]>([]);
  const headerData = useMemo(() => {
    const isBetween = (dt?: Moment) => {
      if (!!!dt) {
        return false;
      }
      return dt.isBetween(startTime, endTime, null, '[]');
    };

    let fevor = '';
    if (data.length > 0) {
      fevor = data[0].fevor;
    }

    let zpPlan = 0;
    let zpActual = 0;
    let zzPlan = 0;
    let zzActual = 0;
    let wgPlan = 0;
    let wgActual = 0;
    let rkPlan = 0;
    let rkActual = 0;

    data.forEach((item) => {
      if (isBetween(item.zpPlan)) {
        zpPlan++;
        if (!!item.zpActual) {
          zpActual++;
        }
      }
      if (isBetween(item.zzPlan)) {
        zzPlan++;
        if (!!item.zzActual) {
          zzActual++;
        }
      }
      if (isBetween(item.wgPlan)) {
        wgPlan++;
        if (!!item.wgActual) {
          wgActual++;
        }
      }
      if (isBetween(item.rkPlan)) {
        rkPlan++;
        if (!!item.rkActual) {
          rkActual++;
        }
      }
    });

    return {
      fevor,
      zpRate: zpPlan > 0 ? ((zpActual * 100) / zpPlan).toFixed(0) + '%' : '',
      zzRate: zzPlan > 0 ? ((zzActual * 100) / zzPlan).toFixed(0) + '%' : '',
      wgRate: wgPlan > 0 ? ((wgActual * 100) / wgPlan).toFixed(0) + '%' : '',
      rkRate: rkPlan > 0 ? ((rkActual * 100) / rkPlan).toFixed(0) + '%' : '',
    };
  }, [data, startTime, endTime]);
  const [displayAt, setDisplayAt] = useState(0);
  const [lastConditionKey, setLastConditionKey] = useState('');
  const getWaringStyle = useCallback(
    (plan: Moment | null | undefined, actual: Moment | null | undefined) => {
      if (!!!plan) {
        return '';
      }
      if (!!actual) {
        if (actual.startOf('day').isAfter(plan.startOf('day'))) {
          return styles.waring;
        } else {
          return '';
        }
      } else {
        if (moment().startOf('day').isAfter(plan.startOf('day'))) {
          return styles.waring;
        } else {
          return '';
        }
      }
    },
    [],
  );

  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(() => {
    if (lastConditionKey !== conditionKey) {
      const dataTemp = convertData(dtoArray);
      setData(dataTemp);
      setLastConditionKey(conditionKey);
      setDisplayAt(0);
      updateDisplayData(0, dataTemp);
    }
  }, [conditionKey, lastConditionKey, dtoArray]);

  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.main}>
      <div className={styles.row_container}>
        <div className={styles.top_header_1}>生产管理员：</div>
        <div className={styles.top_header_2}>各工序月完成率：</div>
      </div>
      <div className={styles.row_container}>
        <div className={styles.top_content_l}>{headerData.fevor}</div>
        <div className={styles.top_content_c}>{headerData.zpRate}</div>
        <div className={styles.top_content_c}>{headerData.zzRate}</div>
        <div className={styles.top_content_c}>{headerData.wgRate}</div>
        <div className={styles.top_content_r}>{headerData.rkRate}</div>
      </div>
      <div className={styles.row_container}>
        <div className={styles.table_header_1}>
          <div className={styles.table_cell_c}>施工号</div>
        </div>
        <div className={styles.table_header_1}>
          <div className={styles.table_cell_c}>瓶数</div>
        </div>
        <div className={styles.table_header_s}>
          <div className={styles.row_container}>
            <div className={styles.table_header_2}>装瓶</div>
            <div className={styles.table_header_2}>组装</div>
            <div className={styles.table_header_2}>完工</div>
            <div className={styles.table_header_2}>入库</div>
          </div>
          <div className={styles.row_container}>
            <div className={styles.table_header_3}>计划</div>
            <div className={styles.table_header_3}>实际</div>
            <div className={styles.table_header_3}>计划</div>
            <div className={styles.table_header_3}>实际</div>
            <div className={styles.table_header_3}>计划</div>
            <div className={styles.table_header_3}>实际</div>
            <div className={styles.table_header_3}>计划</div>
            <div className={styles.table_header_3}>实际</div>
          </div>
        </div>
      </div>
      <NodeGroup
        data={displayData}
        keyAccessor={(d) => d.zgh}
        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) => (
              <div
                className={styles.row_container}
                key={node.key}
                style={{
                  position: 'absolute',
                  left: 0,
                  top: 0,
                  width: '100%',
                  transform: `translate(0px, ${node.state.y}px)`,
                  opacity: node.state.opacity,
                }}
              >
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data?.zgh}</div>
                </div>
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data?.quantity}</div>
                </div>
                <div
                  className={`${styles.table_content} ${getWaringStyle(
                    node.data.zpPlan,
                    node.data.zpActual,
                  )}`}
                >
                  <div className={styles.table_cell_c}>{node.data.zpPlan?.format('M.D')}</div>
                </div>
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data.zpActual?.format('M.D')}</div>
                </div>
                <div
                  className={`${styles.table_content} ${getWaringStyle(
                    node.data.zzPlan,
                    node.data.zzActual,
                  )}`}
                >
                  <div className={styles.table_cell_c}>{node.data.zzPlan?.format('M.D')}</div>
                </div>
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data.zzActual?.format('M.D')}</div>
                </div>
                <div
                  className={`${styles.table_content} ${getWaringStyle(
                    node.data.wgPlan,
                    node.data.wgActual,
                  )}`}
                >
                  <div className={styles.table_cell_c}>{node.data.wgPlan?.format('M.D')}</div>
                </div>
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data.wgActual?.format('M.D')}</div>
                </div>
                <div
                  className={`${styles.table_content} ${getWaringStyle(
                    node.data.rkPlan,
                    node.data.rkActual,
                  )}`}
                >
                  <div className={styles.table_cell_c}>{node.data.rkPlan?.format('M.D')}</div>
                </div>
                <div className={styles.table_content}>
                  <div className={styles.table_cell_c}>{node.data.rkActual?.format('M.D')}</div>
                </div>
              </div>
            ))}
          </div>
        )}
      </NodeGroup>
    </div>
  );
};

export default FevorPanel;
