<template>
  <Layout class="author-page">
    <LayoutHeader slot='header' theme="white" class="author-page-header">
      <div ref="headerAuthor" class="header-author">
        <div class="h-name flex">
          <span class="h-name-b">{{authorBaseData.nickName}}</span>
          <span v-if="authorBaseData.sex" class="iconfont icon-women author-sex-icon" :class="`icon-${authorBaseData.sex}`"></span>
        </div>
        <div class="h-more">
          <div class="flex">
            <WidgetAvatar class="h-headico" :src="authorBaseData.headIco" :width="100" :height="100"></WidgetAvatar>
          </div>
          <div v-if="!isOwner" class="h-follow flex">
            <WidgetFollow class="widget-follow" :author-uid="autherInfo.authorUid" :follow="authorBaseData.hasAttention === 'Y'" @on-follow="follow => onFollow(follow)" :pos-id="sceneId"></WidgetFollow>
          </div>
        </div>
      </div>
    </LayoutHeader>

    <div class="fixed-tab">
      <FavTabBlock v-if="tabFixed" :tabs-num="tabsNum" :active-index="activeIndex" @change="changeTab"></FavTabBlock>
    </div>

    <cube-scroll
      class="main-container"
      ref="scroll"
      :options="scrollOpts"
      :scroll-events="['scroll', 'scroll-end', 'before-scroll-start']"
      @scroll="onScrollHandle"
      @scroll-end="onScrollEndHandle"
      @before-scroll-start="beforeScrollStartHandle">
      <div ref="authorProfile" class="author-profile">
        <span class="avatar-box">
          <WidgetAvatar :src="authorBaseData.headIco" :width="100" :height="100"></WidgetAvatar>
        </span>
        <div class="author-section">
          <ul class="author-fans">
            <li v-for="(item, key) in fansList" :key="key">
              <span class="num">{{authorBaseData[key] || 0}}</span>
              <p class="name"><span>{{item}}</span></p>
            </li>
          </ul>
          <div class="operate-wrap">
            <a v-if="isOwner" class="operate-btn btn-user-edit" :href="mineInfoUrl">编辑个人资料</a>
            <WidgetFollow v-if="!isOwner && authorBaseData.hasAttention" class="operate-btn" :author-uid="autherInfo.authorUid" :follow="authorBaseData.hasAttention === 'Y'" @on-follow="follow => onFollow(follow)" :pos-id="sceneId"></WidgetFollow>
          </div>
        </div>
      </div>
      <p v-if="authorBaseData.signature" class="author-desc">{{authorBaseData.signature}}</p>
      <div ref="tabBlock">
        <FavTabBlock :tabs-num="tabsNum" :active-index="activeIndex" @change="changeTab"></FavTabBlock>
      </div>
      <div ref="contantList" class="contant-list" :style="`min-height: ${listMinHeight}px;`">
        <p v-if="emptyTip" class="empty-tip">{{emptyTip}}</p>
        <WaterFall class="pannel-wrap" :list="list" :params="params" :tab="activeIndex"></WaterFall>
        <div v-if="loadStatus && !emptyTip" class="loading">
          <Loading v-if="loadStatus === 1" class="load-icon" :size="20"></Loading>
          <p v-else class="load-text">没有更多了</p>
        </div>
      </div>
    </cube-scroll>

    <a v-if="isOwner" class="publish hover-opacity" :class="{'scroll-opacity': scrolling}" :href="publishUrl"></a>
  </Layout>
</template>

<script>
import {assign, get} from 'lodash';
import {Scroll, Loading} from 'cube-ui';
import FavTabBlock from './components/fav-tab-block';
import WaterFall from './components/scroll-reveal';
import YAS from 'utils/yas-constants';

import {createNamespacedHelpers} from 'vuex';
const {mapState, mapActions, mapMutations} = createNamespacedHelpers('user');

export default {
  name: 'userpage',
  data() {
    return {
      scrollY: 0,
      scrolling: false,
      mineInfoUrl: '//m.yohobuy.com/home/mydetails?openby:yohobuy={"action":"go.mineinfo"}',
      publishUrl: '?openby:yohobuy={"action":"go.grasspublish"}',
      autherInfo: {},
      fansList: {
        attCount: '关注',
        fansCount: '粉丝',
        praiseAndfavorite: '获赞与收藏'
      },
      tabFixed: false,
      tabsNum: [0, 0],
      activeIndex: 0,
      listMinHeight: 0,
      fetchInfo: {},
      loadStatus: '',
      emptyTip: '',
      scrollOpts: {
        bounce: false,
      },
      sceneId: YAS.scene.author
    };
  },
  created() {
    this.CHANGE_AUTHOR_OWNER_STATUS(!this.$route.params.id);
  },
  mounted() {
    let $dom = this.$refs.headerAuthor;

    this.init(this.$route.params);

    this.listMinHeight = this.$el.offsetHeight - this.$refs.tabBlock.offsetHeight - $dom.offsetHeight;

    if ($dom.offsetHeight) {
      this._animeDuration = 300;
      import('animejs').then(({default: anime}) => {
        this._animeEl = anime({
          targets: $dom,
          translateY: -$dom.offsetHeight,
          easing: 'easeInOutSine',
          duration: this._animeDuration,
          autoplay: false
        });
      });
    }
  },
  activated() {
    if (this.$route.params.id && this.$route.params.id !== this.autherInfo.authorUid) {
      this.init(this.$route.params);
    }
  },
  beforeRouteUpdate(to, from, next) {
    if (this.$route.params.id !== to.params.authorUid) {
      this.init(to.params);
    }
    next();
  },
  computed: {
    ...mapState(['authorBaseData', 'isOwner']),
    list() {
      return get(this.fetchInfo, `${this.activeIndex}.list`) || [];
    },
    params() {
      return {
        params: {
          type: this.waterFallType,
          authorType: this.autherInfo.authorType,
          authorUid: this.autherInfo.authorUid,
        },
        query: {
          userName: this.authorBaseData.nickName
        }
      };
    },
    waterFallType() {
      return ['publish', 'fav'][this.activeIndex];
    }
  },
  methods: {
    ...mapMutations(['CHANGE_AUTHOR_OWNER_STATUS', 'CHANGE_AUTHOR_ATTENTION_STATUS']),
    ...mapActions(['autherBaseInfo', 'autherAritcleNum', 'autherPubList', 'autherFavList', 'autherMineBaseInfo', 'autherMineAritcleNum', 'autherMinePubList', 'autherMineFavList']),
    init(params) {
      params = params || {};

      this._apiNamePre = 'auther';

      this.CHANGE_AUTHOR_OWNER_STATUS(!this.$route.params.id);
      this.tabFixed = false;
      this.tabsNum = [0, 0];
      this.activeIndex = 0;
      this.fetchInfo = {};
      this.loadStatus = '';
      this.emptyTip = '';

      if (this.scrollY > 0) {
        if (this._animeEl) {
          this._animePlayed = false;
          this._animeEl.seek(0);
        }
        this.$refs.scroll.scrollTo(0, 0);
      }

      if (!params.id) {
        this._apiNamePre += 'Mine';

        this.checkLogin(uid => {
          this.fetchData(uid, 1);
        });
      } else {
        this.fetchData(params.id, params.type || 1);
      }
    },
    fetchData(authorUid, authorType, noBase) {
      this.autherInfo = {authorUid, authorType};

      this.fetchBaseInfo();
      this.fetchList(true);
    },
    checkLogin(cb) {
      try {
        this.$sdk.getUser().then(res => {
          if (get(res, 'uid') > 0) {
            return cb && cb(res.uid);
          } else {
            this.$sdk.goLogin();
          }
        });
      } catch (e) {
        console.log(e);
      }
    },
    onScrollHandle({y}) {
      this.scrollY = -y;

      let animePlayed = this.scrollY > this.$refs.authorProfile.offsetHeight;

      if (!this._animePlayed === !animePlayed) {
        return;
      }

      this.tabFixed = animePlayed;

      let start;
      let self = this;

      function step(timestamp) {
        if (!start) {
          start = timestamp
        };

        let progress = Math.floor(timestamp - start);

        self._animeEl.seek(animePlayed ? progress : self._animeDuration - progress);

        if (progress < self._animeDuration) {
          window.requestAnimationFrame(step);
        }
      };

      window.requestAnimationFrame(step);

      this._animePlayed = animePlayed;
    },
    onScrollEndHandle(scroll) {
      this.scrolling = false;
      if (1000 - scroll.y > this.$refs.contantList.offsetHeight) {
        this._listTimer && clearTimeout(this._listTimer);
        this._listTimer = setTimeout(() => {
          this.fetchList();
        }, 50);
      }
    },
    beforeScrollStartHandle() {
      this.scrolling = true;
    },
    changeTab(index) {
      if (this.activeIndex !== index) {
        this.activeIndex = index;
        this.loadStatus = '';
        this.emptyTip = '';

        let info = this.fetchInfo[index] || {};

        info.page = 1;
        info.lastedTime = '';

        this.fetchList();

        let top = this.$refs.authorProfile.offsetHeight;

        if (this.scrollY > top) {
          this.$nextTick(() => {
            this.$refs.scroll.scrollTo(0, -top - 1, 0);
          });
        }
      }
    },
    fetchBaseInfo() {
      this[this._apiNamePre + 'BaseInfo'](this.autherInfo);

      this[this._apiNamePre + 'AritcleNum'](this.autherInfo).then(res => {
        this.tabsNum = [get(res, 'data.articleCount'), get(res, 'data.favoriteCount')];
      });
    },
    async fetchList(wait) {
      this.fetchInfo = this.fetchInfo || [];

      if (this.syncing) {
        return;
      }

      let info = this.fetchInfo[this.activeIndex] || {};
      let result;

      info.page = info.page || 1;

      if (info.page > info.totalPage) {
        this.loadStatus = 2;
        return;
      }

      this.loadStatus = 1;

      let syncServiceName;

      if (this.activeIndex === 1) {
        syncServiceName = this._apiNamePre + 'FavList';
      } else {
        syncServiceName = this._apiNamePre + 'PubList';
      }

      if (this[syncServiceName]) {
        this.syncing = true;
        result = await this[syncServiceName](assign({
          limit: 20,
          page: info.page,
          lastedTime: info.lastedTime || ''
        }, this.autherInfo));

        this.syncing = false;
      }

      if (result && result.code === 200) {
        if (info.page === 1) {
          info.list = [];
        }

        info.list = (info.list || []).concat(result.data.list || []);
        info.page++;
        info.totalPage = result.data.totalPage || 1;
        info.lastedTime = result.data.lastedTime;

        this.setEmptyTip(info.list, result.data.totalCount);

        if (info.list.length) {
          info.list[0]._type = `${info.list[0].articleId}_${this.activeIndex}`;
        }
      }

      setTimeout(() => {
        if (info.page > info.totalPage) {
          this.loadStatus = 2;
        }

        this.fetchInfo[this.activeIndex] = info;
        this.fetchInfo = {...this.fetchInfo};
        setTimeout(() => {
          this.$refs.scroll.refresh();
        }, 100);
      }, wait ? 300 : 0);
    },
    setEmptyTip(list, totalCount) {
      let tip = '';

      if (!list.length && !totalCount) {
        switch (this.activeIndex) {
          case 0:
            tip = this.isOwner ? '发布你的第一篇潮人态度' : 'TA还没有分享过哦';
            break;
          case 1:
            tip = this.isOwner ? '快去收藏你的第一篇内容吧' : 'TA还没有收藏内容';
            break;
          default:
            break;
        }
      }

      this.emptyTip = tip;
    },
    onFollow(follow) {
      this.CHANGE_AUTHOR_ATTENTION_STATUS(follow);
    }
  },
  components: {
    CubeScroll: Scroll,
    Loading,
    FavTabBlock,
    WaterFall
  }
};
</script>


<style lang="scss">
  .author-page {
    box-sizing: border-box;
    color: #4a4a4a;
  }

  .author-page-header > .title {
    overflow: visible!important;
  }

  .fixed-tab {
    width: 100%;
    position: absolute;
    z-index: 2;
  }

  .header-author {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;

    .flex {
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .h-name {
      font-size: 36px;
      font-weight: 500;

      .h-name-b {
        max-width: 60%;
        line-height: 1.4;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        display: inline-block;
      }

      .author-sex-icon {
        font-size: 28px;
        padding-left: 10px;
        padding-right: 0;
      }

      .icon-man {
        color: #96d8f3;
      }

      .icon-women {
        color: #f7c3e1;
      }
    }

    .h-more {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 100%;
      left: 0;
    }

    .h-headico {
      width: 60px;
      height: 60px;
    }

    .h-follow {
      position: absolute;
      top: 0;
      right: -130px;
    }
  }


  .header-share {
    margin-right: 26px;
    color: #222;
    font-weight: bold;
  }

  .author-profile {
    padding: 24px 30px;
    display: flex;
    justify-content: space-between;
    overflow: hidden;

    .avatar-box {
      width: 150px;
      height: 150px;
      overflow: hidden;
      border-radius: 50%;

      > img {
        width: 100%;
        height: 100%;
        display: block;
      }
    }
  }

  .author-section {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  .author-fans {
    display: flex;
    justify-content: flex-end;
    padding-top: 4px;
    padding-right: 54px;

    li {
      margin-left: 140px;
      position: relative;

      &:first-child {
        margin-left: 0;
      }

      .num {
        min-width: 30px;
        font-size: 28px;
        font-weight: 500;
        padding-bottom: 6px;
        display: block;
        text-align: center;
      }

      .name {
        position: absolute;
        font-size: 20px;
        font-weight: 300;
        color: #9b9b9b;
        margin-left: 50%;
        word-break: keep-all;
        white-space: nowrap;

        > * {
          position: relative;
          left: -50%;
        }
      }
    }
  }

  .operate-wrap {
    text-align: right;

    .operate-btn {
      width: calc(100% - 20px);
      height: 50px;
      font-size: 23px;
      line-height: 50px;
      display: inline-block;
      box-sizing: border-box;
    }

    .btn-user-edit {
      color: #222;
      border: 1px solid #4a4a4a;
      border-radius: 8px;
      text-align: center;
    }
  }

  .author-desc {
    margin: 20px 30px;
    font-size: 24px;
    font-weight: 300;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .contant-list {
    position: relative;
  }

  .empty-tip {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28px;
    color: #ddd;
    position: absolute;
    top: 0;
    bottom: 240px;
  }

  .loading {
    padding: 20px 0;

    .load-icon > span {
      margin: auto;
    }

    .load-text {
      text-align: center;
    }
  }

  .publish {
    width: 100px;
    height: 100px;
    position: absolute;
    bottom: 52px;
    right: 40px;
    background-image: url('../../statics/image/userpage/publish.png');
    background-size: 100% 100%;
    z-index: 10;
    transition: all 600ms ease-in-out;

    &.scroll-opacity {
      opacity: 0.3;
    }
  }
</style>