import * as React from 'react'

import { openAppLofter } from 'nw-app-lofter'
import { isLofter } from 'nw-detect';

import { parse } from 'query-string-for-all';

import { callHandler } from 'nejsbridge/dist/bridge.lofter.es';

import safeAreaInsets from 'safe-area-insets';

import {
  Props,
  State,
  BlogInfo,
} from './type'

import { Popup } from '../common/popup';
import { Tabs, TabPane } from '../common/tabs';
import AddressModal from './address-modal';
import { 
  MissionTitle,
  MissionList,
  MissionDesc,
} from './missions';
import {
  AwardList,
} from './awards'

import { showMessage } from '../common/toast/toast'
import { InfoIcon, MissionArrowIcon, MissionInfoIcon } from '../common/icons'
import { goToLogin } from '../utils/login';
import { formatMonthDate, formatFullDate, formatAvatar } from '../utils/format';
import localParam from '../utils/localParam';
import log from '../utils/lofter-log'
import { appNavigate } from '../utils/navigate'
import { fetchTotalMission, convertSimplePrize } from './actions';
import { BaseComponent } from '../base-component';

import * as Styled from './index.style'

const urlData = parse(location.search);
const isDev = process.env.NODE_ENV === 'development';
const { rem } = Styled;

interface InfoBlockProps {
  points: number,
  icon: string,
  color?: string,
  blogInfo: BlogInfo,
}
export class InfoBlock extends React.Component<InfoBlockProps> {
  render() {
    const { blogInfo, icon, points, color } = this.props;
    return (
      <Styled.InfoBlock color={color}>
        <img src={formatAvatar(blogInfo.headImage)} alt="头像" className="avatar" />
        <div className="name">{blogInfo.blogNickName}</div>
        活动积分：
        <div className="points">
          <img src={icon} alt="图标" className="icon" />
          <span className="count">x{points}</span>
        </div>
      </Styled.InfoBlock>
    )
  }
}

export class ActivityMission extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    const { isEdit, viewOutApp, alwaysPopup, activityCode } = props;
    if (!isLofter() && !isDev && !isEdit && !viewOutApp && alwaysPopup) {
      this.openApp();
      return;
    }
    if (alwaysPopup) {
      if (urlData.show === 'award') {
        this.state.showAwardPopup = true;
        log.capture('cpnote-16', {
          category: 'cpnote',
          action: 100,
          scene: 'cpnote',
          activityId: 'cpnote-' + activityCode,
        })
      } else {
        log.capture('cpnote-9', {
          category: 'cpnote',
          action: 100,
          scene: 'cpnote',
          activityId: 'cpnote-' + activityCode,
        })
        this.state.showMissionPopup = true
      }
    }
    this.state.safeBottom = safeAreaInsets.bottom;
    document.body.style.backgroundColor = 'transparent'
  }

  static defaultProps = new Props()

  state = new State()

  missionScrollRef: HTMLElement | undefined;
  awardScrollRef: HTMLElement | undefined;

  awardAddressData: {
    activityCode: string,
    prizeActivityCode: string,
    prizeCode: string,
  } | undefined

  dataRequestTime: number = 0;

  getData = async ({
    time,
    callback,
  } : {
    time?: number,
    callback?: () => void
  } = {}) => {
    try {
      const res = await fetchTotalMission(this.props.activityCode, time);
      if (res.code === 200) {
        this.setState({
          isLogin: true,
          points: res.data.points,
          pointsIcon: res.data.pointsIcon,
          missionData: res.data.missionActivity,
          awardData: res.data.awardActivity,
          blogInfo: res.data.blogInfo,
        }, () => {
          this.setState({
            showScrollTip: this.missionScrollRef ? (
              this.missionScrollRef.scrollHeight > this.missionScrollRef.clientHeight
            ) : false
          })
          callback && callback();
        })
      } else {
        if (res.code !== 401) {
          showMessage({
            text: res.msg
          })
        }
      }
      console.log('activity data', time, res);
    } catch (error) {
      console.log('Get data failed', error)
      showMessage('活动太火爆了，请稍后再来哦~')
    }
  }

  openApp = () => {
    openAppLofter({
      path: 'webview',
      query: {
        url: location.href
      }
    })
  }

  checkAppAndLogin = (type: 'mission' | 'award', callback: () => void) => {
    if (window.location.host.indexOf('cms-yaolu.hz.netease.com') >= 0){
      callback();
      return;
    }
    // 如果站外，并且不是允许站外浏览，直接唤起app才能做任务
    if (!isLofter() && !this.props.viewOutApp && !this.props.isEdit) {
      this.openApp();
      return;
    }
    if (type === 'mission') {
      if (this.state.missionData && this.state.missionData.activityStatus === -1) {
        showMessage('活动还没开始哦~')
        return;
      }
      if (this.state.missionData && this.state.missionData.activityStatus === 1) {
        showMessage('活动已经结束啦~')
        return;
      }
    }

    if (type === 'award') {
      if (this.state.awardData && this.state.awardData.status === -1) {
        showMessage('活动还没开始哦~')
        return;
      }
      if (this.state.awardData && this.state.awardData.status === 1) {
        showMessage('活动已经结束啦~')
        return;
      }
    }
    
    if (!this.state.isLogin) {
      goToLogin(() => {
        this.getData({
          time: new Date().getTime(),
          callback
        });
      }, 'card')
      return;
    }
    // 为了兼容5.1设备不支持visibility api，每次拉起弹窗都更新一次数据
    this.getData({
      time: new Date().getTime(),
    });
    callback();
  }

  missionMaskClick = () => {
    const { isEdit, alwaysPopup } = this.props;
    if (!alwaysPopup) {
      this.setState({
        showMissionPopup: false,
      })
    }
    if (isEdit) return;
    if (isLofter()){
      callHandler('njb_closeCurrentWebview');
    } else {
      history.back();
    }
    
  }

  awardMaskClick = () => {
    const { isEdit, alwaysPopup } = this.props;
    if (!alwaysPopup) {
      this.setState({
        showAwardPopup: false,
      })
    }
    if (isEdit) return;
    if (isLofter()){
      callHandler('njb_closeCurrentWebview');
    } else {
      history.back();
    }
  }

  showAddressModal = ({
    activityCode,
    prizeActivityCode,
    prizeCode,
  } :{
    activityCode: string,
    prizeActivityCode: string,
    prizeCode: string,
  }) => {
    this.awardAddressData = {
      activityCode,
      prizeActivityCode,
      prizeCode
    };
    this.setState({
      showAddressModal: true,
    })
  }

  hideAddressModal = () => {
    this.awardAddressData = {
      activityCode: '',
      prizeActivityCode: '',
      prizeCode: ''
    };
    this.setState({
      showAddressModal: false,
    })
  }

  submitAddressPrize = (data: any, callback?: () => void) => {
    console.log('submitAddressPrize', data);
    if (!this.awardAddressData || !this.awardAddressData.activityCode || !this.awardAddressData.prizeCode) {
      console.warn('No award adress data preset');
      return;
    }
    convertSimplePrize({
      addressId: data.addressId,
      activityCode: this.awardAddressData.activityCode,
      prizeActivityCode: this.awardAddressData.prizeActivityCode,
      prizeCode: this.awardAddressData.prizeCode,
    }).then(() => {
      this.hideAddressModal();
      this.getData({
        time: new Date().getTime(),
      });
      callback && callback();
    })
  }

  monitorVisibility = () => {
    if (this.props.isEdit) return;
    const handleVisibilitychange = () => {
      if (!document.hidden) {
        console.log('monitorVisibility update', new Date().getTime());
        this.getData({
          time: new Date().getTime(),
        });
      }
    };
    document.addEventListener('visibilitychange', handleVisibilitychange);
  }

  // loadFont = () => {
  //   const { point : { font } } = this.props
  //   if (font) {
  //     const style = document.createElement('style');
  //     style.innerText = `@font-face {
  //       font-family: "Point Font";
  //       src: url("${font}") format("truetype");
  //     }`;
  //     document.head.appendChild(style);
  //   }
  // }

  componentDidMount() {
    // if (this.props.isEdit) {
    //   this.watch()
    // }
    // this.loadFont();
    this.monitorVisibility();
    this.getData({
      time: new Date().getTime(),
    });
    safeAreaInsets.onChange((style: any) => {
      this.setState({
        safeBottom: style.bottom,
      })
    })
  }

  watch = () => {
    let el = document.getElementById('viewport-left')
    let vwEl = document.getElementById('viewport')
    let left = vwEl!.getBoundingClientRect().left
    this.setState({
      viewportLeft: left
    })
    const config = { attributes: true, childList: true}
    const callback = (mutationList: any) => {
      mutationList.forEach((mutation: any) => {
        switch(mutation.type) {
          case 'childList':
            this.setState({
              viewportLeft: vwEl!.getBoundingClientRect().left
            })
            break;
        }
      })
    }
    let observer = new MutationObserver(callback)
    observer.observe(el!, config)
  }

  goPointRule = () => {
    const { pointRuleUrl, isEdit } = this.props;
    if (pointRuleUrl && !isEdit) {
      appNavigate(pointRuleUrl);
    }
  }

  goExchangeRule = () => {
    const { exchangeRuleUrl, isEdit } = this.props;
    if (exchangeRuleUrl && !isEdit) {
      appNavigate(exchangeRuleUrl);
    }
  }

  goCreate = () => {
    if (!isLofter()) {
      this.openApp();
      return;
    }
    const { isEdit, createBtn } = this.props;
    if (!isEdit) {
      window.location.href = `lofter://www.lofter.com/post/create/?publish=text&tag=${createBtn.tag}&content=${createBtn.content}`
    }
  }

  showMissionPopup = () => {
    const { activityCode } = this.props;
    log.capture('cpnote-16', {
      category: 'cpnote',
      action: 100,
      scene: 'cpnote',
      activityId: 'cpnote-' + activityCode,
    })
    this.setState({
      showMissionPopup: true
    })
  }
  showAwardPopup = () => {
    const { activityCode } = this.props;
    log.capture('cpnote-9', {
      category: 'cpnote',
      action: 100,
      scene: 'cpnote',
      activityId: 'cpnote-' + activityCode,
    })
    this.setState({
      showAwardPopup: true
    })
  }

  render() {
    const {
      activityCode,
      style,
      isEdit = false,
      createBtn,
      missionPanel,
      awardPanel,
      previewMission,
      previewAward,
      previewAddress,
      mainColor = '#000',
      addressModal,
      bgOutApp,
      alwaysPopup,
      mission,
      award,
    } = this.props
    const {
      viewportLeft,
      missionData,
      awardData,
      points,
      pointsIcon,
      blogInfo,
      safeBottom,
    } = this.state;

    let {
      showMissionPopup,
      showAwardPopup,
      showAddressModal,
    } = this.state;

    if (isEdit && previewMission) {
      showMissionPopup = true
    }
    if (isEdit && previewAward) {
      showAwardPopup = true
    }
    if (isEdit && previewAddress) {
      showAddressModal = true
    }

    const maskBg = !isLofter() && bgOutApp?.url ? bgOutApp.url : undefined
    
    return (
      <div 
        style={{
          ...style,
        }}
      >
        <BaseComponent {...this.props}>
          {!alwaysPopup && <Styled.MissionContainer isEdit={isEdit}>
            <div 
              id="missionBtn" 
              style={{
                width: mission.width + 'rem',
                height: mission.height + 'rem',
                left: mission.left + 'rem',
                top: mission.top + 'rem',
              }}
              onClick={this.showMissionPopup}
            >任务热区</div>
            <div 
              id="awardBtn"
              style={{
                width: award.width + 'rem',
                height: award.height + 'rem',
                left: award.left + 'rem',
                top: award.top + 'rem',
              }}
              onClick={this.showAwardPopup}
            >兑换热区</div>
          </Styled.MissionContainer>}
          <Popup 
            overflow="visible" 
            height="70%" 
            gapWidth="0" 
            isEdit={isEdit} 
            show={showMissionPopup} 
            close={this.missionMaskClick} 
            scrollRef={this.missionScrollRef}
            maskBg={maskBg}
          >
            {missionPanel.titleImage && missionPanel.titleImage.url && <MissionTitle image={missionPanel.titleImage.url} />}
            <Styled.RuleBtn 
              onClick={this.goPointRule}
              color={mainColor}
              safeBottom={safeBottom}
            >
              <MissionInfoIcon className="info-icon" />
              <span className="text">
                积分规则
              </span>
              <MissionArrowIcon className="go-icon" />
            </Styled.RuleBtn>
            {(missionPanel.topGap && typeof missionPanel.topGap === 'number') ? <Styled.Gap style={{height: `${missionPanel.topGap}rem`}}></Styled.Gap> : null}
            <Styled.PopContent>
              <Tabs navStyle={{ margin: `${rem(24)} ${rem(32)} 0` }} defaultValue={0} ref={(ref: HTMLElement) => {
                this.missionScrollRef = ref
              }} color={mainColor}>
                {
                  missionData && missionData.tabList ? missionData.tabList.map((tab, index) => {
                    return (
                      <TabPane key={index} title={tab.tabName} value={index}>
                        <InfoBlock 
                          points={points}
                          color="#C6BA88"
                          icon={pointsIcon}
                          blogInfo={blogInfo}
                        />
                        {
                          tab.tabDesc && (
                            <MissionDesc 
                            color="#2E2E2E"
                            >
                              {tab.tabDesc}
                            </MissionDesc>
                          )
                        }
                        <MissionList
                          isEdit={isEdit}
                          activityCode={activityCode}
                          color={mainColor}
                          list={tab.missionInfoList}
                          missionData={missionData}
                          blogInfo={blogInfo}
                          pointsIcon={pointsIcon}
                          refreshData={this.getData}
                        />
                      </TabPane>
                    )
                  }) : null
                }
              </Tabs>
              <Styled.MissionScrollTip 
                show={this.state.showScrollTip}
              >
                滚动查看更多
                <img className="icon" src="https://lofter.lf127.net/1694519218249/Vector.png" />
              </Styled.MissionScrollTip>
            </Styled.PopContent>
            {
              createBtn.text && <Styled.CreateBtn 
                onClick={this.goCreate}
                color={mainColor}
                safeBottom={safeBottom}
              >
                {createBtn.text}
              </Styled.CreateBtn>
            }
          </Popup>
          <Popup 
            overflow="visible" 
            height="64%" 
            gapWidth="0" 
            isEdit={isEdit} 
            show={showAwardPopup} 
            close={this.awardMaskClick} 
            scrollRef={this.awardScrollRef}
            maskBg={maskBg}
          >
            {awardPanel.titleImage && awardPanel.titleImage.url && <MissionTitle image={awardPanel.titleImage.url} />}
            <Styled.RuleBtn 
              onClick={this.goExchangeRule}
              color={mainColor}
              safeBottom={safeBottom}
            >
              <MissionInfoIcon className="info-icon" />
              <span className="text">
                兑换规则
              </span>
              <MissionArrowIcon className="go-icon" />
            </Styled.RuleBtn>
            {(awardPanel.topGap && typeof awardPanel.topGap === 'number') ? <Styled.Gap style={{height: `${awardPanel.topGap}rem`}}></Styled.Gap> : null}
            <Styled.PopContent 
              className="award" 
              safeBottom={safeBottom + 132} 
              ref={ref => {
                if (!ref) return;
                this.awardScrollRef = ref
              }}
            >
              {
                awardData && <InfoBlock 
                  points={points}
                  color="#C6BA88"
                  icon={pointsIcon}
                  blogInfo={blogInfo}
                />
              }
              {
                awardData && <AwardList
                  color={mainColor}
                  list={awardData.items}
                  points={points}
                  pointsIcon={pointsIcon}
                  awardData={awardData}
                  activityCode={activityCode}
                  refreshData={this.getData}
                  blogInfo={blogInfo}
                  showAddressModal={this.showAddressModal}
                />
              }
            </Styled.PopContent>
            <AddressModal 
              show={showAddressModal} 
              onCancel={this.hideAddressModal} 
              onOk={this.submitAddressPrize}
              color={mainColor}
              buttonImage={addressModal.buttonImage}
              isEdit={isEdit}
            />
          </Popup>
        </BaseComponent>
      </div>
    )
  }
}