import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { CaretUpOutlined, CaretDownOutlined } from "@ant-design/icons";
import styles from "./index.module.scss";
import SpinLoding from "@/components/SpinLoding";
import { Route, Switch, useLocation } from "react-router-dom";
import AuthRoute from "@/components/AuthRoute";
import classNames from "classnames";
import history from "@/utils/history";
import { Button, Form, Input, Modal, Popconfirm } from "antd";
import { Base64 } from "js-base64";
import encodeStr from "@/utils/pass";
import { getDictListAPI, passWordEditAPI } from "@/store/action/login";
import { getTokenInfo, removeTokenInfo } from "@/utils/storage";
import { useDispatch, useSelector } from "react-redux";
import inco1Ac from "@/assets/img/inco1Ac.png";
import inco2Ac from "@/assets/img/inco2Ac.png";
import inco3Ac from "@/assets/img/inco3Ac.png";
import { MessageFu } from "@/utils/message";
import logoImg from "@/assets/img/logo.png";
import { barrageGetUnauditedAPI } from "@/store/action/B4Barrage";
import { RootState } from "@/store";
import { getPermissionsAPI } from "@/store/action/C2Role";

const NotFound = React.lazy(() => import("@/components/NotFound"));

function Layout() {
  const dispatch = useDispatch();

  // 进页面获取弹幕管未审核个数
  useEffect(() => {
    dispatch(barrageGetUnauditedAPI());
  }, [dispatch]);

  const barrageNum = useSelector(
    (state: RootState) => state.barrageReducer.stateNum
  );

  type ListTempType = {
    title: string;
    incoAc: any;
    son: {
      id: number;
      name: string;
      path: string;
      done: boolean;
      Com: React.LazyExoticComponent<
        React.MemoExoticComponent<() => JSX.Element>
      >;
    }[];
  }[];

  const listTemp = useMemo(() => {
    const arr: ListTempType = [
      {
        title: "数据统计",
        incoAc: inco1Ac,
        son: [
          {
            id: 110,
            name: "热度统计",
            path: "/",
            done: false,
            Com: React.lazy(() => import("../A1Hot")),
          },
        ],
      },
      {
        title: "内容管理",
        incoAc: inco2Ac,
        son: [
          {
            id: 220,
            name: "场景管理",
            path: "/scene",
            done: false,
            Com: React.lazy(() => import("../B1Scene")),
          },
          {
            id: 230,
            name: "馆藏管理",
            path: "/goods",
            done: false,
            Com: React.lazy(() => import("../B2Goods")),
          },
          {
            id: 240,
            name: "万物墙管理",
            path: "/wall",
            done: false,
            Com: React.lazy(() => import("../B3Wall")),
          },
          {
            id: 250,
            name: "弹幕管理",
            path: "/barrage",
            done: false,
            Com: React.lazy(() => import("../B4Barrage")),
          },
          {
            id: 260,
            name: "题库管理",
            path: "/topic",
            done: false,
            Com: React.lazy(() => import("../B5Topic")),
          },
          {
            id: 270,
            name: "智能导览管理",
            path: "/smart",
            done: false,
            Com: React.lazy(() => import("../B6Smart")),
          },
        ],
      },
    ];

    return arr;
  }, []);

  // 是超级管理员
  useEffect(() => {
    const userInfo = getTokenInfo().user;
    if (userInfo.isAdmin === 1) {
      listTemp.push({
        title: "系统管理",
        incoAc: inco3Ac,
        son: [
          {
            id: 800,
            name: "用户管理",
            path: "/user",
            done: true,
            Com: React.lazy(() => import("../C1User")),
          },
          {
            id: 900,
            name: "角色管理",
            path: "/role",
            done: true,
            Com: React.lazy(() => import("../C2Role")),
          },
          {
            id: 1000,
            name: "操作日志",
            path: "/log",
            done: true,
            Com: React.lazy(() => import("../C3Log")),
          },
        ],
      });
    }
  }, [listTemp]);

  const authPageArr = useSelector(
    (state: RootState) => state.loginStore.authPageArr
  );

  // 权限的数据和页面判断
  useEffect(() => {
    authPageArr.forEach((v1) => {
      v1.children?.forEach((v2) => {
        if (v2.authority) {
          listTemp.forEach((v3) => {
            v3.son.forEach((v4) => {
              if (v2.id === v4.id) v4.done = true;
            });
          });
        }
      });
    });
    const arr = listTemp.map((v1) => {
      return {
        ...v1,
        son: v1.son.filter((v2) => v2.done),
      };
    });
    setList(arr);
  }, [authPageArr, listTemp]);

  const [list, setList] = useState(listTemp);

  // 进页面看看第一个页面有权限的是哪一个

  const timeRef = useRef(0);

  useEffect(() => {
    const userInfo = getTokenInfo().user;
    if (userInfo.isAdmin !== 1) {
      clearTimeout(timeRef.current);
      timeRef.current = window.setTimeout(() => {
        const newList: any = [];
        list.forEach((v1) => {
          v1.son.forEach((v2) => {
            newList.push(v2);
          });
        });

        if (newList[0] && newList[0].id !== 110)
          history.replace(newList[0].path);
      }, 100);
    }
  }, [list]);

  // 进页面获取所有下拉信息和权限信息
  useEffect(() => {
    dispatch(getDictListAPI());
    dispatch(getPermissionsAPI());
  }, [dispatch]);

  // 点击跳转
  const pathCutFu = useCallback((path: string) => {
    history.push(path);
  }, []);

  // 当前路径选中的左侧菜单
  const location = useLocation();
  const [path, setPath] = useState("");

  useEffect(() => {
    const arr = location.pathname.split("/");
    let pathTemp = "/";
    if (arr[1]) pathTemp = "/" + arr[1];

    setPath(pathTemp);
  }, [location]);

  // 第一级菜单选中高亮
  const row1ActiveFu = useCallback(
    (title: string) => {
      let flag = false;
      list.forEach((v1) => {
        v1.son.forEach((v2) => {
          if (v2.path === path && v1.title === title) flag = true;
        });
      });
      return flag;
    },
    [list, path]
  );

  const userInfo = useMemo(() => {
    return getTokenInfo().user;
  }, []);

  // 修改密码相关
  const [open, setOpen] = useState(false);

  // 拿到新密码的输入框的值
  const oldPasswordValue = useRef("");

  const checkPassWord = (rule: any, value: any = "") => {
    if (value !== oldPasswordValue.current)
      return Promise.reject("新密码不一致!");
    else return Promise.resolve(value);
  };

  const onFinish = async (values: any) => {
    // 通过校验之后发送请求
    if (values.oldPassword === values.newPassword)
      return MessageFu.warning("新旧密码不能相同!");
    const obj = {
      oldPassword: encodeStr(Base64.encode(values.oldPassword)),
      newPassword: encodeStr(Base64.encode(values.newPassword)),
    };
    const res: any = await passWordEditAPI(obj);
    if (res.code === 0) {
      MessageFu.success("修改成功!");
      loginExit();
    }
  };

  // 点击退出登录
  const loginExit = () => {
    removeTokenInfo();
    history.push("/login");
  };

  return (
    <div className={styles.Layout}>
      {/* 左边 */}
      <div className="layoutLeft">
        <div className="layoutLeftTop">
          <img src={logoImg} alt="" />
        </div>
        {/* 左边主体 */}
        <div className="layoutLeftMain">
          {list.map((v1) => (
            <div className="mainBoxL2RowBox" key={v1.title}>
              <div
                style={{
                  display: v1.son.every((v) => !v.done) ? "none" : "flex",
                }}
                className={classNames(
                  "mainBoxL2RowBoxTit",
                  row1ActiveFu(v1.title) ? "activeRow1" : ""
                )}
              >
                <img src={v1.incoAc} alt="" />
                <div className="txt">{v1.title}</div>
              </div>
              {v1.son.map((v2) => (
                <div
                  key={v2.id}
                  onClick={() => pathCutFu(v2.path)}
                  className={classNames(
                    "mainBoxL2Row",
                    v2.path === path ? "active" : ""
                  )}
                >
                  {v2.id === 250 && barrageNum ? (
                    <div className="rowTip">{barrageNum}</div>
                  ) : null}
                  <div className="txt">{v2.name}</div>
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>
      {/* 右边 */}
      <div className="layoutRight">
        <div className="layoutRightTop">
          {/* 用户相关 */}
          <div className="user">
            {userInfo.realName}
            <div className="userInco userInco1">
              <CaretUpOutlined />
            </div>
            <div className="userInco userInco2">
              <CaretDownOutlined />
            </div>
            <div className="userSet">
              <span onClick={() => setOpen(true)}>修改密码</span>
              <Popconfirm
                placement="bottom"
                title="确定退出吗?"
                okText="确定"
                cancelText="取消"
                onConfirm={loginExit}
              >
                退出登录
              </Popconfirm>
            </div>
          </div>
        </div>
        {/* 右边主体 */}
        <div className="layoutRightMain">
          {/* 二级路由页面 */}
          <div className="mainBoxR">
            <React.Suspense fallback={<SpinLoding />}>
              <Switch>
                {list.map((v1) => {
                  return v1.son.map((v2) => (
                    <AuthRoute
                      key={v2.id}
                      exact
                      path={v2.path}
                      component={v2.Com}
                    />
                  ));
                })}

                <Route path="*" component={NotFound} />
              </Switch>
            </React.Suspense>
          </div>
        </div>
      </div>

      {/* 点击修改密码打开的对话框 */}
      <Modal
        destroyOnClose
        open={open}
        title="修改密码"
        onCancel={() => setOpen(false)}
        footer={
          [] // 设置footer为空，去掉 取消 确定默认按钮
        }
      >
        <Form
          name="basic"
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 16 }}
          onFinish={onFinish}
          autoComplete="off"
        >
          <Form.Item
            label="旧密码"
            name="oldPassword"
            rules={[{ required: true, message: "不能为空!" }]}
          >
            <Input.Password maxLength={15} />
          </Form.Item>

          <Form.Item
            label="新密码"
            name="newPassword"
            rules={[
              { required: true, message: "不能为空!" },
              { min: 6, max: 15, message: "密码长度为6-15个字符!" },
            ]}
          >
            <Input.Password
              maxLength={15}
              onChange={(e) => (oldPasswordValue.current = e.target.value)}
            />
          </Form.Item>

          <Form.Item
            label="确定新密码"
            name="checkPass"
            rules={[{ validator: checkPassWord }]}
          >
            <Input.Password maxLength={15} />
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 14, span: 16 }}>
            <Button onClick={() => setOpen(false)}>取消</Button>
            &emsp;
            <Button type="primary" htmlType="submit">
              确定
            </Button>
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}

// 使用 React.memo 来优化组件，避免组件的无效更新，类似 类组件里面的PureComponent
const MemoLayout = React.memo(Layout);
export default MemoLayout;
