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, FormInstance, Input, Modal } from 'antd'
// import { Base64 } from 'js-base64'
// import encodeStr from '@/utils/pass'
import { passWordEditAPI, getLeftMenuAPI } from '@/store/action/layout'
import { getTokenInfo, removeTokenInfo } from '@/utils/storage'
import { MessageFu } from '@/utils/message'
import logoImg from '@/assets/img/logo.png'
import NotFound from '@/components/NotFound'

import { RouterType, RouterTypeRow } from '@/types'
import tabLeftArr from './data'
import MyPopconfirm from '@/components/MyPopconfirm'
import { UserListType } from '@/types/api/Z1user'
import PreviewOperate from '@/components/PreviewOperate'
import { RootState } from '@/store'
import { useSelector } from 'react-redux'

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 { isOpenPreview, src } = useSelector((state: RootState) => state.A0Layout.editPreview)

  // 获取用户权限信息
  const getUserAuthFu = useCallback(async () => {
    const userInfo = getTokenInfo().user

    const res = await getLeftMenuAPI()
    const isOkIdArr: any[] = []

    // 测试环境
    // tabLeftArr.forEach(v1 => {
    //   v1.son.forEach(v2 => {
    //     isOkIdArr.push(v2)
    //   })
    // })

    // setRouterCom(isOkIdArr)
    // setList(tabLeftArr)

    if (res.code === 0) {
      const tempList: UserListType[] = res.data || []
      tempList.forEach(v => {
        if (v.children) {
          v.children.forEach(c => {
            isOkIdArr.push(c.id)
          })
        } else {
          isOkIdArr.push(v.id)
        }
      })

      // 是管理员
      if (userInfo.status === 1) {
        isOkIdArr.push(18)
      }

      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>([])

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

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

  // 拿到新密码的输入框的值
  const oldPasswordValue = useRef('')
  // form表单的ref
  const formRef = useRef<FormInstance>(null)

  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 = {
      confirmPwd: values.checkPass,
      pwdOld: values.oldPassword,
      pwd: values.newPassword
    }
    const res: any = await passWordEditAPI(obj)
    if (res.message === '密码错误') {
      return formRef.current?.setFields([
        {
          name: 'oldPassword',
          errors: ['密码错误']
        }
      ])
    }
    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'>
          <img src={logoImg} alt='' />
        </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)}
                >
                  {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
          ref={formRef}
          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} placeholder='请输入内容，6-15个字' />
          </Form.Item>

          <Form.Item
            label='新密码'
            name='newPassword'
            rules={[
              { required: true, message: '不能为空!' },
              { min: 6, max: 15, message: '密码长度需为6-15个字符!' },
              {
                pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,15}$/,
                message: '密码必须包含数字和字母!'
              }
            ]}
            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
          >
            <Input.Password
              maxLength={15}
              placeholder='请输入内容，6-15个字'
              onChange={e => (oldPasswordValue.current = e.target.value)}
            />
          </Form.Item>

          <Form.Item
            label='确定新密码'
            name='checkPass'
            rules={[{ required: true, validator: checkPassWord }]}
            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
          >
            <Input.Password maxLength={15} placeholder='请输入内容，6-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>

      {/* 点击表格的预览操作，打开弹窗 */}
      {isOpenPreview && <PreviewOperate src={src} />}
    </div>
  )
}

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