/* global nvcReset, getNC, _nvc_nc */
import React, { Component } from "react"
import Routes from "./router"
import cookie from "js-cookie"
import { connect } from "react-redux"
import {
  setCurrentUser,
  startFetchUser,
  endFetchUser,
} from "src/store/userAction"
import {
  updateCaptchaState,
  closeCaptchaModal,
  showCaptchaModal,
  validationPassed,
  startFetchNoTrace,
  endFetchNoTrace,
} from "src/store/no-trace-validation/reducer"
import { initialState } from "src/store/userReducer"
import { withRouter } from "react-router-dom"
import { compose } from "redux"
import { getParam, http, browser, loadScript, getTimestamp } from "src/utils"
import { Toast } from "antd-mobile"
import { addDays } from "date-fns"
import stringify from "json-stringify-safe"

//拦截ajax请求，返回mock数据
/*import mock from 'src/utils/mock'
mock()*/

// 默认样式
import "./assets/css/index.scss"
// iconfont
import "./assets/font/iconfont.css"

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      isShowActivityEntry: 0,
      jumpUrl: "",
      entryImage: "",
      mkey: "",
    }
  }

  static displayName = "App"

  previousLocation = { pathname: "/", search: "", hash: "" }

  records = []

  pathnameBlacklist = ["/country", "/passport"]

  firstLoad = true

  componentDidMount() {
    let url = window.location.href
    if (url.indexOf("ccode") > -1) {
      if (!getParam("ccode").includes("%")) {
        cookie.set("ccode", getParam("ccode"), {
          expires: 1,
          domain: ".julyedu.com",
          path: "/",
        })
      }
    }

    //是否显示宝箱全局入口
    this.isShowGlobalEntryInTime()

    this.umengStatistic()
    //平台信息
    !getParam("version") && cookie.set("plat", "5", { domain: ".julyedu.com" })

    if (browser.isWeixin && browser.isIOS) {
      sessionStorage.setItem("enter_url", window.location.href)
    }

    this.utm()

    const { history } = this.props

    this.getUser()

    this.setNavigationRecord(this.props.location, this.props.history.action)
    this.setPreviousLocation()

    history.listen((location, action) => {
      this.firstLoad = false
      this.setNavigationRecord(location, action)
      this.utm()

      // if (cookie.get('uid') && this.props.user.hasError) {
      //   this.getUser()
      // }
      if (location.pathname.startsWith("/passport")) {
        window.localStorage.setItem(
          "binding_redirect",
          stringify(this.previousLocation)
        )
      }
      const { pathname, state } = location
      if (pathname.startsWith("/passport")) {
        location.state = {
          ...state,
          ...{
            from: {
              pathname: this.previousLocation.pathname,
              search: this.previousLocation.search,
              hash: this.previousLocation.hash,
            },
          },
        }
      } else {
        this.removeShareCodeCookie()
      }
    })
  }

  componentDidUpdate(prevProps, prevState) {
    this.setPreviousLocation()
    const {
      user,
      noTraceValidation: { isShowCaptcha, isFetching: isNoTraceFetching },
    } = this.props
    const redirect = new URLSearchParams(window.location.search).get("redirect")
    if (!user.hasError && redirect) {
      window.location.href = decodeURIComponent(redirect)
    }

    if (
      prevProps.noTraceValidation.isShowCaptcha !== isShowCaptcha &&
      isShowCaptcha
    ) {
      typeof nvcReset === "function" && nvcReset()
      typeof getNC === "function" &&
        getNC().then(() => {
          _nvc_nc.reset()
        })
    }

    if (!user.isFetching && !isNoTraceFetching) {
      document.body.style.pointerEvents = "auto"
    }
  }

  // 获取宝箱阶段
  getStage = () => {
    let ccode = cookie.get("ccode")
    http
      .get(`${API.home}/sys/anniversary/floating?ccode=${ccode}`)
      .then((res) => {
        const { code, data, msg } = res.data
        if (code === 200) {
          this.setState({
            isShowActivityEntry: false, // 2022.4.19下掉
            jumpUrl: data.jump_url,
            entryImage: data.image_path,
          })
        } else {
          Toast.info(msg, 2)
        }
      })
  }

  umengStatistic = () => {
    // 友盟统计
    const script = document.createElement("script")
    script.src =
      "https://s22.cnzz.com/z_stat.php?id=1265696973&web_id=1265696973"
    script.language = "JavaScript"
    document.body.appendChild(script)
  }

  removeShareCodeCookie = () => {
    cookie.remove("share_code", { path: "/", domain: ".julyedu.com" })
  }

  setNavigationRecord = (location, action) => {
    const { pathname, search, hash } = location
    let isLastRecord =
      location.pathname ===
      (this.records.length && this.records[this.records.length - 1].pathname)
    let needHistoryMutation =
      location.pathname !== this.previousLocation.pathname
    switch (action) {
      case "POP":
        if (needHistoryMutation) {
          this.firstLoad
            ? this.records.push({ pathname, search, hash })
            : this.records.pop()
        } else {
          this.records.length
            ? (this.records[this.records.length - 1] = location)
            : (this.records = [location])
        }
        break
      case "REPLACE":
        this.records.length > 1 &&
          (this.records[this.records.length - 1] = { pathname, search, hash })
        break
      default:
        !isLastRecord && this.records.push({ pathname, search, hash })
    }

    location.state && location.state.records
      ? (location.state.records = this.records)
      : location.state
      ? (location.state = {
          ...location.state,
          records: this.records,
        })
      : (location.state = { records: this.records })
  }

  utm = () => {
    // utm统计  m站全站统计广告投放、以及统计详情页浏览
    let zhihu_cb = getParam("cb")

    if (zhihu_cb) {
      let data = {
        zhihu_cb: zhihu_cb,
      }

      http.post(`${API["home"]}/sys/zhihu/firstRecord`, data).then((res) => {})
    }
  }

  getUser = () => {
    document.body.style.pointerEvents = "none"
    this.props.startFetchNoTrace()
    //获取用户信息
    this.props.startFetchUser()

    //微信
    let code = getParam("code")
    let oid = getParam("oid")
    if (code && !oid) {
      http
        .get(
          `${
            API["passport-api"]
          }/m/wx_loginInfo/code/${code}?redirect=${encodeURIComponent(
            window.location.href
          )}`
        )
        .then((res) => {
          let data = res.data
          if (data.errno === 200) {
            if (data.data.is_check) {
              this.props.updateCaptchaState({
                isNeedValidation: true,
              })
              this.setState({
                mkey: data.data.mkey,
              })
              this.setupNoTraceValidate()
            } else {
              this.props.endFetchNoTrace()
              this.props.updateCaptchaState({
                isNeedValidation: false,
                isFetching: false,
              })
              if (data.data["is_bind_mobile"]) {
                let redirectURI = new URLSearchParams(
                  window.location.search
                ).get("redirect")
                if (redirectURI) {
                  localStorage.setItem(
                    "binding_redirect",
                    JSON.stringify(redirectURI)
                  )
                  // return window.location.assign(data.data.url.slice(0, index) + '?' + se.toString())
                }
                window.location.assign(data.data.url)
              } else {
                this.handleLoginResponse(data.data)
              }
            }
          } else {
            this.props.endFetchNoTrace()
            this.props.updateCaptchaState({
              isNeedValidation: false,
              isFetching: false,
            })
            Toast.info(data.msg)
            this.props.setCurrentUser(initialState)
          }
        })
    } else {
      if (this.props.location.pathname !== "/my") {
        http.get(`${API.home}/m/user_info_sample/0`).then((res) => {
          this.props.endFetchNoTrace()
          this.props.setCurrentUser(this.transformUser(res))
        })
      }
    }
  }

  handleLoginResponse = (data) => {
    let { role, uid, token } = data
    let expires = addDays(new Date(), 90)
    cookie.set("role", role, { expires, domain: ".julyedu.com", path: "/" })
    cookie.set("uid", uid, { expires, domain: ".julyedu.com", path: "/" })
    cookie.set("token", token, { expires, domain: ".julyedu.com", path: "/" })

    const search = new URLSearchParams(window.location.search)
    search.delete("code")
    search.delete("aa")
    if (search.has("state") && search.get("state") === "STATE") {
      search.delete("state")
    }
    const loc = window.location
    loc.replace(loc.origin + loc.pathname + "?" + search.toString() + loc.hash)
  }

  setupNoTraceValidate = () => {
    let src =
      "//g.alicdn.com/sd/nvc/1.1.112/guide.js?t=" + getTimestamp(60 * 1000)
    const appkey = "FFFF0N000000000090FC"
    const scene = "nvc_register_h5"
    const _this = this

    window.NVC_Opt = {
      appkey: appkey,
      scene: scene,
      isH5: true,
      //二次验证的唤醒方式。true为浮层式，false为嵌入式。
      popUp: true,
      //声明二次验证需要渲染的目标元素ID。
      renderTo: "#global-captcha",
      //回调参数。
      nvcCallback: function (data) {
        _this.requestRegister(data)
        // 其中，data为getNVCVal()函数的值，该函数为二次验证滑动或者刮刮卡通过后的回调函数。
        // data与业务请求一同上传，由后端请求AnalyzeNvc接口并返回100或者900。
      },
    }

    loadScript(src, () => {
      let timer = setInterval(() => {
        if (window.getNVCVal) {
          let NVC = window.getNVCVal()
          this.requestRegister(NVC)
          clearInterval(timer)
        }
      }, 1000)
    })
  }

  requestRegister = (NVC) => {
    http
      .post(`${API["passport-api"]}/m/wxRegister`, {
        mkey: this.state.mkey,
        NVC,
      })
      .then((res) => {
        const { errno, msg, data } = res.data
        if (errno === 200) {
          this.props.validationPassed()
          this.handleLoginResponse(data)
        } else if (errno === 5002) {
          this.props.showCaptchaModal()
          typeof nvcReset === "function" && nvcReset()
          typeof getNC === "function" &&
            getNC().then(() => {
              _nvc_nc.reset()
            })
        } else {
          Toast.info(msg)
        }
        this.props.endFetchUser()
        this.props.endFetchNoTrace()
      })
  }

  setPreviousLocation = () => {
    const { location } = this.props
    let isInBlacklist = this.pathnameBlacklist.some((item) =>
      location.pathname.startsWith(item)
    )
    !isInBlacklist && (this.previousLocation = location)
  }

  transformUser = (res) => {
    let payload
    if (res.data.code === 200) {
      //移除红包统计cookie
      this.removeShareCodeCookie()
      const {
        msg,
        data: {
          avatar_file: avatar,
          user_name: username,
          is_vip: isVIP,
          uid,
          code,
        },
      } = res.data

      payload = {
        hasError: false,
        msg,
        data: {
          username,
          isVIP,
          avatar,
          uid,
          code,
        },
      }
    } else {
      payload = {
        hasError: true,
        msg: res.data.msg,
        code: res.data.code,
        data: {},
      }
    }
    return payload
  }

  transformWxUser = (res) => {
    let data = res.data
    if (data.errno === 200) {
      //移除红包统计cookie
      this.removeShareCodeCookie()
      let { uid, token, avatar_file: avatar, uname: username } = data.data

      return {
        hasError: false,
        data: {
          uid,
          token,
          avatar,
          username,
        },
        msg: data.msg,
      }
    } else {
      let { code, msg } = data.data
      return {
        code,
        msg,
        hasError: true,
        data: {},
      }
    }
  }

  closeGlobalEntry = () => {
    localStorage.setItem("globalEntryClosedTime", Date.now().toString())
    this.setState({
      isShowActivityEntry: 0,
    })
  }

  isShowGlobalEntryInTime = () => {
    const lastCloseTime = localStorage.getItem("globalEntryClosedTime")
    if (lastCloseTime) {
      const pastDate = new Date(parseInt(lastCloseTime))
      const now = new Date()
      if (
        now.getFullYear() > pastDate.getFullYear() ||
        now.getMonth() > pastDate.getMonth() ||
        now.getDate() > pastDate.getDate()
      ) {
        this.getStage()
      }
    } else {
      this.getStage()
    }
  }

  render() {
    const { isShowActivityEntry, entryImage, jumpUrl } = this.state
    const {
      noTraceValidation: { isShowCaptcha, isNeedValidation },
    } = this.props
    return (
      <>
        <Routes />
        {!!isShowActivityEntry && (
          <div className="year19-index">
            <i
              className={"iconfont iconiconfront-2"}
              onClick={this.closeGlobalEntry}
            ></i>
            <a href={jumpUrl}>
              <img src={entryImage} alt="" />
            </a>
          </div>
        )}
        {isNeedValidation && isShowCaptcha && (
          <div className="modal-cover">
            <div className="modal">
              <div>亲，系统正忙，滑动一下马上回来</div>
              <div id={"global-captcha"}></div>
              <i
                className="iconfont iconiconfront-2 close"
                onClick={this.props.closeCaptchaModal}
              ></i>
            </div>
          </div>
        )}
      </>
    )
  }
}

export default compose(
  connect(({ user, noTraceValidation }) => ({ user, noTraceValidation }), {
    setCurrentUser,
    startFetchUser,
    updateCaptchaState,
    closeCaptchaModal,
    showCaptchaModal,
    validationPassed,
    endFetchUser,
    startFetchNoTrace,
    endFetchNoTrace,
  }),
  withRouter
)(App)
