import React, { useState, useEffect, useMemo, useCallback, useRef, useContext } from 'react';
import { Result, Tabs } from 'antd';
import {
  PieChartOutlined,
  PlayCircleOutlined,
  HighlightOutlined,
  DoubleRightOutlined,
  DoubleLeftOutlined,
} from '@ant-design/icons';
import { connect } from 'dva';
import HeaderComponent from './components/Header';
import CanvasControl from './components/CanvasControl';
import SourceBox from './SourceBox';
import TargetBox from './TargetBox';
import Calibration from '../../components/Calibration';
import DynamicEngine, { componentsType } from 'editorCore/DynamicEngine';
import FormRender from 'editorCore/FormRender';

import template from '../../components/BasicShop/BasicComponents/template';
import basictemplate from '../../components/BasicPcShop/BasicComponents/template';
import mediaTpl from '../../components/BasicShop/MediaComponents/template';
import basicmediaTpl from '../../components/BasicPcShop/MediaComponents/template';
import graphTpl from '../../components/BasicShop/VisualComponents/template';

import schemaH5 from '../../components/BasicShop/schema';
import schema from '../../components/BasicPcShop/schema';
import { ActionCreators, StateWithHistory } from 'redux-undo';
import { throttle } from 'editorUtils/tool';

import styles from './index.less';
import { createHtml, nodeToString } from '../../utils/tool';


import { dooringContext } from '../../layouts';
import SourcePcBox from './SourcePcBox';

const { TabPane } = Tabs;

const Container = (props: {
  history?: any;
  location?: any;
  pstate?: any;
  cstate?: any;
  dispatch?: any;
}) => {
  const [scaleNum, setScale] = useState(1);
  const [collapsed, setCollapsed] = useState(false);
  const [rightColla, setRightColla] = useState(true);
  const { pstate, cstate, dispatch } = props;
  const pointData = pstate?.pointData ? pstate?.pointData : [];
  const cpointData = cstate?.pointData ? cstate?.pointData : [];

  const changeCollapse = useMemo(() => {
    return (c: boolean) => {
      setCollapsed(c);
    };
  }, []);
  const changeRightColla = useMemo(() => {
    return (c: boolean) => {
      setRightColla(c);
    };
  }, []);
  const curPoint = pstate?.curPoint ? pstate?.curPoint : {};

  // 指定画布的id
  let canvasId = 'js_canvas';

  const backSize = () => {
    setScale(1);
    setDragState({ x: 0, y: 0 });
  };

  const CpIcon = {
    base: <HighlightOutlined />,
    media: <PlayCircleOutlined />,
    visible: <PieChartOutlined />,
  };

  const generateHeader = useMemo(() => {
    return (type: componentsType, text: string) => {
      return (
        <div>
          {CpIcon[type]} {text}
        </div>
      );
    };
  }, [CpIcon]);

  const handleSlider = useMemo(() => {
    return (type: any) => {
      if (type) {
        setScale((prev: number) => +(prev + 0.1).toFixed(1));
      } else {
        setScale((prev: number) => +(prev - 0.1).toFixed(1));
      }
    };
  }, []);

  const handleFormSave = useMemo(() => {
    return (data: any) => {
      console.log(data, '!!!!')
      dispatch({
        type: 'editorTempModal/modPointData',
        payload: { ...curPoint, item: { ...curPoint.item, config: data } },
      });
    };
  }, [curPoint, dispatch]);

  const clearData = useCallback(() => {
    dispatch({ type: 'editorTempModal/clearAll' });
  }, [dispatch]);

  const handleDel = useMemo(() => {
    return (id: any) => {
      dispatch({
        type: 'editorTempModal/delPointData',
        payload: { id },
      });
    };
  }, [dispatch]);

  const redohandler = useMemo(() => {
    return () => {
      dispatch(ActionCreators.redo());
    };
  }, [dispatch]);

  const undohandler = useMemo(() => {
    return () => {
      if (curPoint) {
        dispatch(ActionCreators.undo());
      }
    };
  }, [dispatch, curPoint]);

  const importTpl = (data: any) => {
    dispatch({
      type: 'editorTempModal/importTplData',
      payload: data,
    });
  };


  useEffect(() => {
    if (pstate?.curPoint && pstate?.curPoint.status === 'inToCanvas') {
      setRightColla(false);
    }
  }, [pstate?.curPoint]);

  const allType = useMemo(() => {
    let arr: string[] = [];
    template.forEach(v => {
      arr.push(v.type);
    });
    basictemplate.forEach(v => {
      arr.push(v.type);
    });
    mediaTpl.forEach(v => {
      arr.push(v.type);
    });
    basicmediaTpl.forEach(v => {
      arr.push(v.type);
    });
    graphTpl.forEach(v => {
      arr.push(v.type);
    });
    return arr;
  }, [graphTpl, mediaTpl, template, basictemplate, basicmediaTpl]);

  const [dragstate, setDragState] = useState({ x: 0, y: 0 });

  const ref = useRef<HTMLDivElement>(null);
  const renderRight = useMemo(() => {
    return (
      <div
        ref={ref}
        className={styles.attrSetting}
        style={{
          transition: 'all ease-in-out 0.5s',
          transform: rightColla ? 'translate(100%,0)' : 'translate(0,0)',
        }}
      >
        {pointData.length && curPoint?.id ? (
          <>
            <div className={styles.tit}>属性设置</div>
            <FormRender
              config={curPoint.item.editableEl}
              uid={curPoint.id}
              defaultValue={curPoint.item.config}
              onSave={handleFormSave}
              onDel={handleDel}
              rightPannelRef={ref}
            />
          </>
        ) : (
          <div style={{ paddingTop: '100px' }}>
            <Result status="404" title="还没有数据哦" subTitle="欢迎使用丽维家editor" />
          </div>
        )}
      </div>
    );
  }, [cpointData.length, curPoint, handleDel, handleFormSave, pointData.length, rightColla]);


  const containerRef = useRef<HTMLDivElement>(null);
  const [diffmove, setDiffMove] = useState({
    start: { x: 0, y: 0 },
    move: false,
  });

  const mousedownfn = useMemo(() => {
    return (e: React.MouseEvent<HTMLDivElement>) => {
      if (e.target === containerRef.current) {
        setDiffMove({
          start: {
            x: e.clientX,
            y: e.clientY,
          },
          move: true,
        });
      }
    };
  }, []);

  const mousemovefn = useMemo(() => {
    return (e: React.MouseEvent<HTMLDivElement>) => {
      if (diffmove.move) {
        let diffx: number;
        let diffy: number;
        const newX = e.clientX;
        const newY = e.clientY;
        diffx = newX - diffmove.start.x;
        diffy = newY - diffmove.start.y;
        setDiffMove({
          start: {
            x: newX,
            y: newY,
          },
          move: true,
        });
        setDragState(prev => {
          return {
            x: prev.x + diffx,
            y: prev.y + diffy,
          };
        });
      }
    };
  }, [diffmove.move, diffmove.start.x, diffmove.start.y]);

  const mouseupfn = useMemo(() => {
    return () => {
      setDiffMove({
        start: { x: 0, y: 0 },
        move: false,
      });
    };
  }, []);

  const onwheelFn = useMemo(() => {
    return (e: React.WheelEvent<HTMLDivElement>) => {
      if (e.deltaY < 0) {
        setDragState(prev => ({
          x: prev.x,
          y: prev.y + 40,
        }));
      } else {
        setDragState(prev => ({
          x: prev.x,
          y: prev.y - 40,
        }));
      }
    };
  }, []);

  useEffect(() => {
    if (diffmove.move && containerRef.current) {
      containerRef.current.style.cursor = 'move';
    } else {
      containerRef.current!.style.cursor = 'default';
    }
  }, [diffmove.move]);


  const { setTheme, theme } = useContext(dooringContext);
  const savePage = () => {
    if (pstate?.isNewPage) {
      const node = document.getElementById(canvasId);
      const bodyHtml = nodeToString(node, theme === 'h5' ? 'wapContainer' : 'pcContainer');
      const pageConfigInfo = pstate?.pageConfig;
      const html = createHtml(bodyHtml, pageConfigInfo, theme === 'h5' ? 'wap' : 'pc');

      console.log(pointData, '保存的数据')
      const _pointData = _.cloneDeep(pointData);
      _pointData.forEach(element => {
        const translates = document.defaultView.getComputedStyle(document.getElementById(element?.id), null).transform;
        const translateData: any[] = translates.substring(7, translates.length - 1).split(',');
        element.translateSortX = translateData[4] / 1;
        element.translateSortY = translateData[5] / 1;
      });
      _pointData.sort((a, b) => a.translateSortY - b.translateSortY || a.translateSortX - b.translateSortX)
      _pointData.forEach(element => {
        element.point = {
          ...element.point,
          y: element.translateSortY / 2
        };
        console.log(element.point.y, element, '当前数据')
      });
      console.log(_pointData)

      dispatch({
        type: 'editorTempModal/savePage',
        payload: {
          client: theme === 'h5' ? 'wap' : 'pc',
          content: html,
          html_param: JSON.stringify({
            pointData: _pointData,
            pageConfig: pstate?.pageConfig
          }),
          id: pstate?.pageId,
          param: {
            online_consult: 0,
            sub_status: 0
          },
          sub_status: 0,
          type: 2
        }
      });
    } else {
      const pageConfigInfo = pstate?.pageConfig;
      dispatch({
        type: 'editorTempModal/savePage',
        payload: {
          client: theme === 'h5' ? 'wap' : 'pc',
          id: pstate?.pageId,
          param: {
            online_consult: 0,
            sub_status: 0
          },
          sub_status: 0,
          type: 2
        }
      });
    }
  }

  const { mode = 'wap' } = props.history.location.query || {};
  return (
    <div className={styles.editorWrap}>
      
      <HeaderComponent
        redohandler={redohandler}
        undohandler={undohandler}
        pointData={pointData}
        clearData={clearData}
        location={props.location}
        importTpl={importTpl}
        dispatch={dispatch}
        __pageConfig={pstate?.pageConfig}
        isNewPage={pstate?.isNewPage}
        savePage={savePage}
      />
      <div className={styles.container}>
        <div
          className={styles.list}
          style={{
            transition: 'all ease-in-out 0.5s',
            position: 'fixed',
            width: collapsed ? '50px' : '350px',
            zIndex: 200,
            boxShadow: 'none',
          }}
        >
          <div className={styles.componentList}>
            <Tabs
              className="editorTabclass"
              onTabClick={() => changeCollapse(false)}
              defaultActiveKey="1"
              tabPosition={'left'}
            >
              {pstate?.isNewPage && <TabPane tab={generateHeader('base', '')} key="1">
                <div className={styles.ctitle}>基础组件</div>
                <div style={{ height: window.innerHeight - 130, overflow: 'auto', display: 'flex', flexDirection: 'row', flexWrap: 'wrap' }}>
                  {
                    theme === 'h5' ?
                      template
                      .filter((item) => item.mode === mode)
                      .map((value, i) => {
                        return (
                          <TargetBox item={value} key={i} canvasId={canvasId}>
                            <DynamicEngine
                              {...value}
                              config={schemaH5[value.type as keyof typeof schemaH5].config}
                              componentsType="base"
                              isTpl={true}
                            />
                          </TargetBox>
                        );
                      }) :
                      basictemplate.map((value, i) => {
                        return (
                          <TargetBox item={value} key={i} canvasId={canvasId}>
                            <DynamicEngine
                              {...value}
                              config={schema[value.type as keyof typeof schema].config}
                              componentsType="base"
                              isTpl={true}
                            />
                          </TargetBox>
                        );
                      })
                  }
                </div>
              </TabPane>}
              {/* <TabPane tab={generateHeader('media', '')} key="2">
                <div className={styles.ctitle}>媒体组件</div>
                {
                  theme === 'h5' ? mediaTpl.map((value, i) => (
                    <TargetBox item={value} key={i} canvasId={canvasId}>
                      <DynamicEngine
                        {...value}
                        config={schemaH5[value.type as keyof typeof schemaH5].config}
                        componentsType="media"
                        isTpl={true}
                      />
                    </TargetBox>
                  )) : basicmediaTpl.map((value, i) => (
                    <TargetBox item={value} key={i} canvasId={canvasId}>
                      <DynamicEngine
                        {...value}
                        config={schema[value.type as keyof typeof schema].config}
                        componentsType="media"
                        isTpl={true}
                      />
                    </TargetBox>
                  ))
                }
              </TabPane> */}
              {/* <TabPane tab={generateHeader('visible', '')} key="3">
                <div className={styles.ctitle}>可视化组件</div>
                {graphTpl.map((value, i) => (
                  <TargetBox item={value} key={i} canvasId={canvasId}>
                    <DynamicEngine
                      {...value}
                      config={schemaH5[value.type as keyof typeof schemaH5].config}
                      componentsType={'visible' as componentsType}
                      isTpl={true}
                    />
                  </TargetBox>
                ))}
              </TabPane> */}
            </Tabs>
          </div>
          <div
            className={styles.collapsed}
            style={{ position: 'absolute', bottom: '80px', left: '20px' }}
            onClick={() => changeCollapse(!collapsed)}
          >
            {collapsed ? <DoubleRightOutlined /> : <DoubleLeftOutlined />}
          </div>
        </div>
        <div
          style={{
            width: collapsed ? '50px' : '350px',
            transition: 'all ease-in-out 0.5s',
          }}
        ></div>

        <div
          className={styles.tickMark}
          id="calibration"
          ref={containerRef}
          onMouseDown={mousedownfn}
          onMouseMove={throttle(mousemovefn, 500)}
          onMouseUp={mouseupfn}
          onMouseLeave={mouseupfn}
          onWheel={onwheelFn}
        >
          <div className={styles.tickMarkTop}>
            <Calibration direction="up" id="calibrationUp" multiple={scaleNum} />
          </div>
          <div className={styles.tickMarkLeft}>
            <Calibration direction="right" id="calibrationRight" multiple={scaleNum} />
          </div>
          {
            theme === 'h5' ? <SourceBox
              dragState={dragstate}
              setDragState={setDragState}
              scaleNum={scaleNum}
              canvasId={canvasId}
              allType={allType}
              __pageConfig={pstate?.pageConfig}
            /> : <SourcePcBox
              dragState={dragstate}
              setDragState={setDragState}
              scaleNum={scaleNum}
              canvasId={canvasId}
              allType={allType}
              __pageConfig={pstate?.pageConfig}
            />
          }
          <CanvasControl scaleNum={scaleNum} handleSlider={handleSlider} backSize={backSize} />
        </div>
        {renderRight}
        <div
          className={styles.rightcolla}
          style={{
            position: 'absolute',
            right: rightColla ? 0 : '304px',
            transform: 'translate(0,-50%)',
            transition: 'all ease-in-out 0.5s',
          }}
          onClick={() => changeRightColla(!rightColla)}
        >
          {!rightColla ? <DoubleRightOutlined /> : <DoubleLeftOutlined />}
        </div>
        <div
          style={{
            width: rightColla ? 0 : '304px',
            transition: 'all ease-in-out 0.5s',
          }}
        ></div>
      </div>
    </div>
  );
};

export default connect((state: StateWithHistory<any>) => {
  return { pstate: state.editorTempModal, cstate: state.editorPcModal };
})(Container);
