<!-- 会计科目选择弹出层组件 zhao -->
<template>
  <van-popup v-model="popupVisible" position="bottom" :style="{'height': height || 'unset',}">
      <van-search
        v-model="searchValue"
        placeholder="按科目编码/名称筛选"
        @input="onSearch"
      />

    <van-tabs v-model="active" @change="onTabChanged">
      <van-tab :title="item.subjectName" :name="item.subjectId" v-for="(item, index) in subjects" :key="index">
        <SubjectTreeChooserNodeItem :ref="'tree' + index" :subjects="item.children" @clicked="onItemClicked" :can-select-non-leaf="canSelectNonLeaf"></SubjectTreeChooserNodeItem>
      </van-tab>
    </van-tabs>
  </van-popup>
</template>

<script>
import request from "@/utils/request";
import SubjectTreeChooserNodeItem from "./SubjectTreeChooserNodeItem";

export default {
  name: "SubjectTreeChooser",
  components: {SubjectTreeChooserNodeItem},
  props: [
    'value', 'visible', 'height', 'canSelectNonLeaf',
  ],
  watch: {
    value: function (newVal, oldVal) {
      if(newVal != this.internalValue)
      {
        this.internalValue = newVal;
        this.syncIndex();
      }
    },
    visible: function(newVal, oldVal) {
      if(this.popupVisible !== newVal)
      {
        this.popupVisible = newVal;
        if(newVal)
          this.syncIndex();
      }
    },
    popupVisible: function(newVal, oldVal) {
      if(newVal !== this.visible)
        this.$emit('update:visible', newVal);
    },
  },
  created() {
    this.getSubjects();
  },
  data() {
    return {
      popupVisible: false,
      internalValue: this.value,
      searchValue: '',
      active: '1',
      subjects: [],
    };
  },
  methods: {
    getSubjects() {
      this.subjects = [];
      let map = {};
      this.getDicts('subject_type').then((resp) => {
        this.subjects = resp.data.map((x) => {
          let item = {
            subjectId: x.dictValue,
            subjectName: x.dictLabel,
            subjectNameAll: x.dictLabel,
            subjectType: x.dictValue,
            subjectLevel: 0,
            children: [],
            visible: true,
          };
          map[x.dictValue] = item;
          return item;
        });
        let url = '/finance/subject/listAll'; // '/open/villageAffairs/public/subjects/153'
        request(url).then((resp) => {
          let list = this.makeTree(resp.rows || resp.data);
          for(let v of list)
          {
            if(v.subjectId.length === 3)
            {
              map[v.subjectType].children.push(v);
            }
          }
        })
      });
    },
    onItemClicked(subject) {
      if(this.canSelectNonLeaf || subject.is_last === 'Y')
      {
        this.internalValue = subject.subjectId
        this.$emit('input', subject.subjectId);
        this.$emit('select', subject);
        this.close();
      }
    },
    onItemToggle({subject, on}) {
    },
    onCancel() {
      this.close();
    },
    makeTree(list) {
      function isnull(p) {
        return p === null || p === undefined || p === '';
      }
      function makeTree_r(l, p) {
        const isRoot = isnull(p);
        let res = [];
        for(let v of l)
        {
          if((isRoot && isnull(v.parentId)) || (!isRoot && v.parentId == p))
          {
            let arr = makeTree_r(l, v.subjectId);
            if(arr.length > 0)
              v.children = arr;
            else
              delete v.children;
            res.push(v);
          }
        }
        return res;
      }
      return makeTree_r(list.map((x) => {
        x.visible = true;
        return x;
      }));
    },
    onSearch(value) {
      function handleTree_r(l, func) {
        let res = 0;
        for(let v of l)
        {
          let r = func(v) ? 1 : 0;
          if(v.children && Array.isArray(v.children) && v.children.length > 0)
          {
            r += handleTree_r(v.children, func);
          }
          v.visible = r > 0;
          res += r;
        }
        return res;
      }

      for(let v of this.subjects)
      {
        if(v.subjectId === this.active && value)
        {
          handleTree_r(v.children, (x) => x.subjectId.startsWith(value) || x.subjectName.indexOf(value) !== -1);
        }
        else
        {
          handleTree_r(v.children, (x) => true);
        }
      }
    },
    onTabChanged() {
      this.searchValue = '';
      this.onSearch();
    },
    folderAll() { // TODO: not work
      for(let i in this.subjects)
      {
        if(this.$refs['tree' + i])
          this.$refs['tree' + i][0].folderAll();
      }
    },
    close() {
      this.popupVisible = false;
      this.folderAll();
      this.searchValue = '';
      this.active = '1';
      this.$emit('cancel');
    },
    syncIndex() {
      if(this.subjects.length === 0 || !this.internalValue)
        return;
      this.active = this.internalValue[0];
    },
  },
}
</script>

<style scoped>
</style>
