import {
  smartDisplayAPI,
  smartGetConfigAPI,
  smartGetListAPI,
  smartRemoveAPI,
  smartSetConfigAPI,
  smartSortAPI,
} from "@/store/action/B6Smart";
import { MessageFu } from "@/utils/message";
import { Button, Popconfirm, Switch, Table, Tooltip } from "antd";
import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { ExclamationCircleFilled } from "@ant-design/icons";
import styles from "./index.module.scss";

// 表格拖动排序-----------------
import { DndProvider, useDrag, useDrop } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "@/store";
import SmartAutoAdd from "./SmartAutoAdd";
import { SmartTableType } from "@/types";
import SmartHotTable from "./SmartHotTable";

function Smart() {
  const dispatch = useDispatch();
  // 进页面获取配置信息
  const smartGetConfigFu = useCallback(async () => {
    const res = await smartGetConfigAPI();
    const data = JSON.parse(res.data.content);
    setValue(data.value);
  }, []);

  useEffect(() => {
    smartGetConfigFu();
    dispatch(smartGetListAPI("play"));
  }, [dispatch, smartGetConfigFu]);

  // 开启和关闭自动播报
  const [value, setValue] = useState(true);

  const isAutoFu = useCallback(
    async (val: boolean) => {
      const obj = {
        content: JSON.stringify({ value: val }),
      };
      const res = await smartSetConfigAPI(obj);
      if (res.code === 0) {
        MessageFu.success("操作成功!");
        smartGetConfigFu();
      }
    },
    [smartGetConfigFu]
  );

  // 切换表格中的启用停用状态
  const isEnabledClickFu = useCallback(
    async (val: boolean, id: number) => {
      const isDisable = val ? 1 : 0;
      const res: any = await smartDisplayAPI(id, isDisable);
      if (res.code === 0) dispatch(smartGetListAPI("play"));
    },
    [dispatch]
  );

  // 从仓库中获取列表数据
  const results = useSelector(
    (state: RootState) => state.smartReducer.autoList
  );

  // 点击编辑或者新增
  const editTableFu = useCallback(
    (id: number) => {
      if (id === -1 && results.length >= 20)
        return MessageFu.warning("最多支持上传20条播报！");
      setEditId(id);
    },
    [results.length]
  );

  // 点击删除
  const delTableFu = useCallback(
    async (id: number) => {
      const res: any = await smartRemoveAPI(id);
      if (res.code === 0) {
        MessageFu.success("删除成功!");
        dispatch(smartGetListAPI("play"));
      }
    },
    [dispatch]
  );

  // --------表格数据
  const columns = useMemo(() => {
    return [
      {
        title: "活动标题",
        dataIndex: "name",
      },
      {
        title: "活动正文",
        render: (item: SmartTableType) =>
          item.description!.length >= 50 ? (
            <span style={{ cursor: "pointer" }} title={item.description}>
              {item.description!.substring(0, 50) + "..."}
            </span>
          ) : (
            item.description
          ),
      },
      {
        title: "展示状态",
        render: (item: SmartTableType) => (
          <Switch
            checkedChildren="启用"
            unCheckedChildren="停用"
            checked={item.display === 1}
            onChange={(val) => isEnabledClickFu(val, item.id)}
          />
        ),
      },
      {
        title: "操作",
        render: (item: SmartTableType) => (
          <>
            <Button
              size="small"
              type="text"
              onClick={() => editTableFu(item.id)}
            >
              编辑
            </Button>

            <Popconfirm
              title="删除后无法恢复，是否删除?"
              okText="删除"
              cancelText="取消"
              onConfirm={() => delTableFu(item.id)}
            >
              <Button size="small" type="text" danger>
                删除
              </Button>
            </Popconfirm>
          </>
        ),
      },
    ];
  }, [delTableFu, editTableFu, isEnabledClickFu]);

  // 表格拖动排序-----------------
  interface DraggableBodyRowProps
    extends React.HTMLAttributes<HTMLTableRowElement> {
    index: number;
    moveRow: (dragIndex: number, hoverIndex: number) => void;
  }

  const type = "DraggableBodyRow";

  const DraggableBodyRow = useCallback(
    ({
      index,
      moveRow,
      className,
      style,
      ...restProps
    }: DraggableBodyRowProps) => {
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const ref = useRef<HTMLTableRowElement>(null);
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const [{ isOver, dropClassName }, drop] = useDrop({
        accept: type,
        collect: (monitor) => {
          const { index: dragIndex } = monitor.getItem() || {};
          if (dragIndex === index) {
            return {};
          }
          return {
            isOver: monitor.isOver(),
            dropClassName:
              dragIndex < index ? " drop-over-downward" : " drop-over-upward",
          };
        },
        drop: (item: { index: number }) => {
          moveRow(item.index, index);
        },
      });
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const [, drag] = useDrag({
        type,
        item: { index },
        collect: (monitor) => ({
          isDragging: monitor.isDragging(),
        }),
      });
      drop(drag(ref));

      return (
        <tr
          ref={ref}
          className={`${className}${isOver ? dropClassName : ""}`}
          style={{ cursor: "move", ...style }}
          {...restProps}
        />
      );
    },
    []
  );

  const components = {
    body: {
      row: DraggableBodyRow,
    },
  };

  const moveRow = useCallback(
    async (dragIndex: number, hoverIndex: number) => {
      if (dragIndex === hoverIndex) return;
      // 交互位置-之前的id
      const beforeId = results[dragIndex].id;
      const afterId = results[hoverIndex].id;

      const res = await smartSortAPI(beforeId, afterId);

      if (res.code === 0) dispatch(smartGetListAPI("play"));
    },
    [dispatch, results]
  );

  // 新增和编辑播报
  const [editId, setEditId] = useState(0);

  const addTableFu = useCallback(() => {
    // 先把仓库表格的数据清空，在发请求重新拿数据，让表格滚动到顶部
    dispatch({ type: "smart/getAutoList", payload: [] });
    dispatch(smartGetListAPI("play"));
  }, [dispatch]);

  return (
    <div className={styles.Smart}>
      <div className="pageTitlt">智能导览管理</div>
      {/* 上面的表格 */}
      <div className="smartTopBox">
        <div className="titleTxt">
          导览播报
          <Tooltip title="按住鼠标可拖动表格调整顺序">
            <div className="inco" hidden={results.length < 2}>
              <ExclamationCircleFilled />
            </div>
          </Tooltip>
        </div>
        <div className="openOrCloseBox">
          <div className="openOrCloseBoxLL">
            自动播报：
            <Switch
              checkedChildren="开启"
              unCheckedChildren="关闭"
              checked={value}
              onChange={(val) => isAutoFu(val)}
            />
            <div className="tit">
              功能开启后，智能导览将按序自动播放下述内容
            </div>
          </div>
          <div className="openOrCloseBoxRR">
            <Button type="primary" onClick={() => editTableFu(-1)}>
              新增播报
            </Button>
          </div>
        </div>
        {/* 表格主体 */}
        <div className="tableAutoBox">
          <DndProvider backend={HTML5Backend}>
            <Table
              scroll={{ y: 300 }}
              columns={columns}
              dataSource={results}
              components={components}
              rowKey="id"
              pagination={false}
              onRow={(_, index) => {
                const attr = {
                  index,
                  moveRow,
                };
                return attr as React.HTMLAttributes<any>;
              }}
            />
          </DndProvider>
        </div>
      </div>
      {/* 下面的表格 */}
      <SmartHotTable />
      {/* 新增和编辑播报 */}
      {editId ? (
        <SmartAutoAdd
          id={editId}
          closeMoalFu={() => setEditId(0)}
          addTableFu={addTableFu}
          editTableFu={() => dispatch(smartGetListAPI("play"))}
        />
      ) : null}
    </div>
  );
}

const MemoSmart = React.memo(Smart);

export default MemoSmart;
