import React, { useCallback, useEffect, useRef, useState } from 'react'
import { CaretRightOutlined } 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 } from 'antd'
import { Base64 } from 'js-base64'
import encodeStr from '@/utils/pass'
import { passWordEditAPI } from '@/store/action/layout'
import { getTokenInfo, removeTokenInfo } from '@/utils/storage'
import { MessageFu } from '@/utils/message'
import NotFound from '@/components/NotFound'

import { RouterType, RouterTypeRow } from '@/types'
import tabLeftArr from './data'
import MyPopconfirm from '@/components/MyPopconfirm'
import { Z1_APIgetAuthByUserId } from '@/store/action/Z1user'
import { UserListType } from '../Z1user/Z1auth'

function Layout() {
  // 当前路径选中的左侧菜单
  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 getUserAuthFu = useCallback(async () => {
    const userInfo = getTokenInfo().user

    const res = await Z1_APIgetAuthByUserId(userInfo.id)
    if (res.code === 0) {
      // 这里后台返回的一层的数据。懒得改逻辑，手动修改成2级的数据
      // res.data = [
      //   {
      //     id: Date.now(),
      //     name: '',
      //     children: res.data
      //   }
      // ]

      const isOkIdArr: number[] = [
        // 101, 102, 103, 104, 105, 106, 107, 108
      ]
      const tempList: UserListType[] = res.data || []
      // console.log(123, tempList);
      tempList.forEach(v => {
        if (v.children) {
          v.children.forEach(c => {
            if (c.authority) isOkIdArr.push(c.id)
          })
        }
      })
      // 是管理员
      if (userInfo.isAdmin === 1) {
        isOkIdArr.push(2100)
        isOkIdArr.push(2200)
      }

      const tempArr: RouterTypeRow = []

      tabLeftArr.forEach(v1 => {
        if (v1.son && v1.son[0]) {
          v1.son.forEach(v2 => {
            if (isOkIdArr.includes(v2.id)) {
              tempArr.push(v2)
            }
          })
        }
      })

      setRouterCom(tempArr)

      // 如果当前页面没有权限了，跳转有权限的第一个页面
      const urlAll = window.location.hash
      const isNowPath = urlAll.replace('#', '')
      const pathArr = tempArr.map(v => v.path)
      if (!pathArr.includes(isNowPath)) {
        history.push(pathArr[0])
      }

      const resList = tabLeftArr.map(v => ({
        ...v,
        son: v.son.filter(c => isOkIdArr.includes(c.id))
      }))

      setList(resList)
    }
  }, [])

  useEffect(() => {
    getUserAuthFu()
  }, [getUserAuthFu])

  // 左侧菜单 信息
  const [list, setList] = useState([] as RouterType)

  // 路由信息（过滤之后的）
  const [RouterCom, setRouterCom] = useState<RouterTypeRow>([])

  // useEffect(() => {
  //   console.log(123, list);
  // }, [list]);

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

  // 修改密码相关
  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')
  }

  // 点击用户 出来 退出登录 修改密码
  const [isUserBtnShow, setIsUserBtnShow] = useState(false)

  return (
    <div className={styles.Layout}>
      {/* 左边 */}
      <div className='layoutLeft'>
        <div className='layoutLeftTop'>
          <h2>横琴民生事务局</h2>
          <h2>健康教育课堂预约</h2>
        </div>
        {/* 左边主体 */}
        <div className='layoutLeftMain'>
          {list.map(v => (
            <div
              className={classNames('layoutLRowBox')}
              key={v.id}
              hidden={!v.son.length}
            >
              <div className='layoutLRowBoxTxt'>{v.name}</div>
              {v.son.map(v2 => (
                <div
                  key={v2.id}
                  className={classNames(
                    'layoutLRowBoxRow',
                    path === v2.path ? 'active' : ''
                  )}
                  onClick={() => pathCutFu(v2.path)}
                  dangerouslySetInnerHTML={{ __html: v2.name }}
                ></div>
              ))}
            </div>
          ))}
        </div>
      </div>
      {/* 右边 */}
      <div className='layoutRight'>
        <div className='layoutRightTop'>
          {/* 用户相关 */}
          <div
            className={classNames('user', isUserBtnShow ? 'userShow' : '')}
            onMouseLeave={() => setIsUserBtnShow(false)}
          >
            <div className='userNameBox' onClick={() => setIsUserBtnShow(true)}>
              {getTokenInfo().user.realName || getTokenInfo().user.userName || '匿名'}

              <div className='userInco userInco2'>
                <CaretRightOutlined />
              </div>
            </div>

            <div className='userSet'>
              <div>
                <span onClick={() => setOpen(true)}>修改密码</span>
                <MyPopconfirm
                  txtK='退出登录'
                  onConfirm={loginExit}
                  Dom='退出登录'
                  loc='bottom'
                />
              </div>
            </div>
          </div>
        </div>
        {/* 右边主体 */}
        <div className='layoutRightMain'>
          {/* 二级路由页面 */}
          <div className='mainBoxR'>
            <React.Suspense fallback={<SpinLoding />}>
              <Switch>
                {RouterCom.map(v => (
                  <AuthRoute key={v.id} exact path={v.path} component={v.Com} />
                ))}

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

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

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

          <Form.Item
            label='确定新密码'
            name='checkPass'
            rules={[{ validator: checkPassWord }]}
            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
          >
            <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
