<template>
  <div class="proof-list">
    <van-image src="@/assets/addproof.png" width="50px" fit="contain" class="add-proof" @click="showAddProof = true;"></van-image>
    <header>
      <span style="font-size:18px;">存证列表</span>
      <div @click="showFilterPicker = true">
        <common-svg name="shaixuan"></common-svg>
        <span>筛选</span>
      </div>
    </header>
    <van-list
      v-model="loading"
      :finished="finished"
      @load="getList"
    > 
      <van-image v-if="!list.length && !loading && isSy" src="@/assets/emptyProof.png" fit="contain"></van-image>
      <van-empty 
        v-if="!list.length && !loading"
        description="您还未添加存证"
        image="@/assets/empty.png">
      </van-empty>
      <proof-item 
        v-else   
        v-for="(proof) of list" 
        :proof="proof"
        :key="proof.id"
        @show-more-action="showMoreAction"
        @click.native="goProofDetail(proof)"
        @edit-increment-proof="editIncrementProof"
        ></proof-item>
    </van-list>
    <van-popup 
      v-model="show" 
      round 
      class="more-action"
      position="bottom"
    >
      <van-grid :column-num="3" :gutter="10" :border="false">
         <van-grid-item 
          v-for="(item, index) in actionList"
          :key="index"
          icon="photo-o"
          :text="currentProof.status === ChainStatus.FAILURE && item.text === '上链' ? `重新${item.text}`:`${item.text}`"
          @click="select(item.key)">
          <template #icon>
            <common-svg :name="item.icon" width="44px" height="44px"></common-svg>
          </template>
        </van-grid-item>
      </van-grid>
      <van-button block round @click="show = false;">取消</van-button>
    </van-popup>
    <van-popup v-model="showFilterPicker" :close-on-popstate="true" round position="bottom">
      <van-picker
        show-toolbar
        :columns="columns"
        @cancel="showFilterPicker = false"
        @confirm="onConfirmFilter"
      />
    </van-popup>
    <add-baseinfo v-if="showAddProof" v-model="proofName" :templateInfo.sync="templateInfo" @cancle="showAddProof = false;proofName='';templateInfo = {id:'',name: ''}" @next="addProofHandler" @select-template="showSelectTemplate = true;"></add-baseinfo>
    <select-template v-if="showSelectTemplate" @next="nextSelectedTemplate" @cancel="showSelectTemplate = false;" @preview="preview" @add-folder="showAddFolder = true;"></select-template>
    <transition name="van-slide-up">
      <add-folder v-if="showAddFolder" @cancel="showAddFolder = false" @next="addFolder"></add-folder>
    </transition>
    <transition name="van-slide-up">
      <preview-template :data="detail" v-if="showPreview" @cancel="showPreview = false" @employ="employ"></preview-template>
    </transition> 
  </div>
  
</template>
<script lang="ts">
import { Component, Prop, Vue, Inject } from 'vue-property-decorator';
import { List, Popup, Button, Image, Picker, Grid, GridItem, Empty, Dialog } from 'vant';
import { ChainStatus } from '@/const/enum';
import { ActionList, ChainStatusStr } from '@/const/constants';
import SelectTemplate from '@/views/template/components/SelectTemplate.vue';
import PreviewTemplate from '@/views/template/components/PreviewTemplate.vue';
import AddFolder from '@/views/template/components/AddFolder.vue';
import AddBaseinfo from './components/AddBaseinfo.vue';
@Component({
  components: {
    [Picker.name]: Picker,
    [Image.name]: Image,
    [Button.name]: Button,
    [List.name]: List,
    [Popup.name]: Popup,
    [Grid.name]: Grid,
    [GridItem.name]: GridItem,
    [Empty.name]: Empty,
    [Dialog.Component.name]: Dialog.Component,
    SelectTemplate,
    PreviewTemplate,
    AddFolder,
    AddBaseinfo,
  },
})
export default class Index extends Vue {

  @Inject('isSy') private isSy!: boolean;
  @Inject('goToBrowser') private goToBrowser!: (proof: any) => void;
  private show: boolean = false;
  private showFilterPicker: boolean = false;
  private columns: any[] =  [{text: '全部', status: []}];
  private chainStatus: number[] | number = [];

  private currentProof: any = {};

  private list: any[] = [];
  private total: number = 0;
  private page: number = 1;

  private loading: boolean = false;
  private finished: boolean = false;

  private showSelectTemplate: boolean = false;
  private showPreview: boolean = false;
  private currentTemplate: any = {};
  private detail: any = {};

  private showAddFolder: boolean = false;
  private showAddProof: boolean = false;

  private proofName: string = '';
  private templateInfo: any = {
    id: '',
    name: '',
  };

  private baseProof: any = '';
  private preProof: any = '';
  private isZengliang: boolean = false;
  private async addProofHandler() {
    let query: any = {
      templateId: this.templateInfo.id,
      proofName: this.proofName,
    };
    if ( this.isZengliang ) {
      query = {...query, baseProof: JSON.stringify(this.baseProof), preProof: JSON.stringify(this.preProof)};
    }
    this.$router.push({ name: 'ProofDetail', query});
  }
  private async addFolder( { folderName }: any) {
     this.showAddFolder = false ;
     await this.$api.template.addFolder(folderName);
     this.showSelectTemplate = false;
  }
  private nextSelectedTemplate({ templateId, templateName }: any) {
    this.templateInfo.id = templateId;
    this.templateInfo.name = templateName;
    this.showPreview = false;
    this.showSelectTemplate = false;
  }
  private preview(currentTemplate: any) {
    this.currentTemplate = currentTemplate;
    this.detail = JSON.parse(this.currentTemplate.detail)[0];
    this.showPreview = true;
  }
  private employ() {
    this.nextSelectedTemplate({
      templateId: this.currentTemplate.id,
      templateName: this.currentTemplate.name,
    });
    this.showSelectTemplate = false;
  }
  get ChainStatus() {
    return ChainStatus;
  }
  get actionList() {
    const {blockChain, edit, del, del2, copy, blockquery , copyhash, zengliang } = ActionList;
    const obj: any = {
      [ChainStatus.NONE]: [blockChain, edit, copy, del],
      [ChainStatus.CHAINING]: [ copy],
      [ChainStatus.SUCCESS]: [ blockquery, copyhash, del2, zengliang],
      [ChainStatus.FAILURE]: [blockChain, edit, copy, del],
    };
    return obj[this.currentProof.status];
  }
  private select(type: string) {
    const obj: any = {
      blockChain: () => { this.blockChainProof(this.currentProof); },
      edit: () => { this.goProofDetail(this.currentProof); },
      del: () => { this.delProof(this.currentProof.id); },
      copy: () => { this.copyProof(this.currentProof); },
      blockquery: () => { this.goToBrowser(this.currentProof); },
      copyhash: () => { this.copyHash(this.currentProof); },
      del2: () => { this.abandonProof(this.currentProof.id); },
      zengliang: () => { this.increment(this.currentProof); },
    };
    this.show = false;
    obj[type]();
  }
  private async getList() {
    const { chainStatus } = this;
    const params = {
      status: Array.isArray(chainStatus) ? chainStatus : [ chainStatus ],
    };
    const res = await this.$api.proof.list(this.page++, params);
    this.total = res.total;
    this.list = [...this.list, ...(res.results || [])];
    // 加载状态结束
    this.loading = false;

    // 数据全部加载完成
    if (this.list.length >= this.total) {
      this.finished = true;
    }
  }

  private mounted() {
    Object.keys(ChainStatusStr).forEach((key: string) => {
      this.columns.push(
        { text: ChainStatusStr[key],
         status: Number(key),
        });
    });
  }
  private editIncrementProof(data: any) {
    const { incrementProof, preProof, baseProof } = data;
    this.$router.push({name: 'ProofDetail',
                      query: { proofId: incrementProof.id,
                                preProof: JSON.stringify(preProof),
                                baseProof: JSON.stringify(baseProof) }});
  }
  private goProofDetail(proof: any) {
    if ([ChainStatus.SUCCESS].includes(proof.status) ) {
      this.goToBrowser(proof);
    } else {
      this.$router.push({ name: 'ProofDetail', query: { proofId: proof.id }});
    }
  }
  private showMoreAction(data: any) {
    this.show = true;
    this.currentProof = data;
  }
  private onConfirmFilter(value: any) {
    this.chainStatus = value.status;
    this.resetList();
    this.showFilterPicker = false;
  }
  private resetList() {
    this.total = 0;
    this.list = [];
    this.finished = false;
    this.page = 1;
    this.loading = true;
    this.getList();
  }
  private delProof(proofId: number) {
    this.$dialog.confirm({
      title: '提示',
      message: '删除后，信息无法找回，确定要删除吗？',
      beforeClose: (action, done) => {
        if ( action === 'confirm' ) {
          this.$api.proof.delete(proofId).then((res: any) => {
            this.$toast.success('删除成功');
            this.resetList();
            done();
          }).catch((err: any) => {
            done();
          });
        } else {
          done();
        }
      },
    });
  }
  private abandonProof(proofId: number) {
    this.$confirmdel().then((res: any) => {
      this.$api.proof.abandon(proofId, '暂无原因').then(() => {
            this.$toast.success('已放入回收站');
            this.resetList();
      });
    });
  }
  private  blockChainProof(proof: any) {
    this.$confirmchain().then((res: any) => {
       this.$api.proof.sendBlockChian(proof.id).then(() => {
            this.$toast.success('提交上链成功');
            this.resetList();
       });
    });
  }
  private async copyProof(proof: any) {
    await this.$api.proof.add(proof.name, JSON.parse(proof.detail), proof.note);
    this.$toast.success('复制成功');
    this.resetList();
  }
  private async reName(proof: any) {
    this.$toast('重命名成功');
  }
  private copyHash(proof: any) {
    this.$copyText(proof.hash);
    this.$toast('hash地址复制成功');
  }
  private async increment(proof: any) {
    const { increment_num } = proof;
    if ( increment_num > 0 ) {
      const { results } = await this.$api.proof.incrementList(this.currentProof.hash);
      const preProof = results[0];
      if (!preProof.hash) {
        this.$toast('请先上链上一条存证');
        return Promise.reject('请先上链上一条存证');
      }
      this.preProof = preProof;
    } else {
      this.preProof = proof;
    }
    this.baseProof = proof;
    this.showAddProof = true;
    this.isZengliang = true;
  }
}
</script>
<style scoped lang="scss">
  .proof-list{
    position: relative;
    box-sizing: border-box;
    padding: 11px 14px;
    background: #F9FBFF;
    margin-bottom: calc( #{ $tabHeight } + 50px);
  }
  .add-proof{
    position: fixed;
    right: 20px;
    bottom: 60px;
    z-index: 500;
  }
  header{
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 13px;
    color: #353535;
    font-size: 14px;
  }
  .more-action{
    padding: 20px;
    box-sizing: border-box;
    .content{
      display: grid;
      grid-gap: 10px;
      grid-template-columns: repeat(3,100px);
    }
  }
</style>