<template>
  <div class="mch-project-list full">
    <div class="toolbar flex-between">
      <div class="title">项目列表</div>
      <div>
        <Search v-model="keyword" />
        <div class="inline" style="margin-left: 20px;">
          <span>过滤：</span>
          <Dropdown trigger="custom" :visible="dataTypeDropdownVisible" @on-clickoutside="dataTypeDropdownVisible=false" v-if="enableDataTypeFilter">
            <div class="control flex-between" :class="{active:dataTypeFilters.length}" @click="dataTypeDropdownVisible=!dataTypeDropdownVisible">
              <div class="label">数据类型</div>
              <Icon type="ios-arrow-down"></Icon>
            </div>
            <template #list>
              <DropdownMenu>
                <DropdownItem v-for="item in dataTypes" :key="item.value"><Checkbox :modelValue="dataTypeFilters.includes(item.value)" @on-change="dataTypeFilterChange($event, item)">{{item.name}}</Checkbox></DropdownItem>
              </DropdownMenu>
            </template>
          </Dropdown>
          <Dropdown trigger="custom" :visible="tagDropdownVisible" @on-clickoutside="tagDropdownVisible=false">
            <div class="control flex-between" :class="{active:tagFilters.length}" @click="tagDropdownVisible=!tagDropdownVisible">
              <div class="label">标签</div>
              <Icon type="ios-arrow-down"></Icon>
            </div>
            <template #list>
              <DropdownMenu>
                <DropdownItem v-if="!tags.length">暂无标签</DropdownItem>
                <DropdownItem v-for="item in tags" :key="item"><Checkbox :modelValue="tagFilters.includes(item)" @on-change="tagFilterChange($event, item)">{{item}}</Checkbox></DropdownItem>
              </DropdownMenu>
            </template>
          </Dropdown>
        </div>
        <div class="inline" style="margin-left: 20px;">
          <span>排序：</span>
          <Dropdown trigger="click" @on-click="sortChange">
            <div class="control flex-between">
              <div class="label">{{ (sorts.find(d => d.value === sortBy)).name }}</div>
              <Icon type="ios-arrow-down"></Icon>
            </div>
            <template #list>
              <DropdownMenu>
                <DropdownItem :name="item.value" :selected="sortBy===item.value" v-for="item in sorts" :key="item.value">{{item.name}}</DropdownItem>
              </DropdownMenu>
            </template>
          </Dropdown>
        </div>
        <div class="inline" style="margin-left: 20px;">
          <span>显示：</span>
          <RadioGroup :model-value="viewMode" @on-change="viewModeChange" type="button">
            <Radio label="card" title="卡片模式">
              <Icon type="md-apps" size="16"/>
            </Radio>
            <Radio label="list" title="列表模式">
              <Icon type="md-list" size="16"/>
            </Radio>
            <Radio label="map" title="地图模式">
              <Icon type="md-map" size="16"/>
            </Radio>
        </RadioGroup>
        </div>
        <Button class="btn" type="primary" icon="md-add" @click="showCreateDlg" v-if="!isReadOnly" style="margin-left: 20px;">新建项目</Button>
      </div>
    </div>
    <div class="list" v-if="displayList.length">
      <Grid :border="false" padding="10px" :col="cols" v-if="viewMode==='card'">
        <GridItem v-for="item in displayList" :key="item.project_id" style="height: 235px;">
          <ProjectItem :item="item" :list="list" :isReadOnly="isReadOnly" :sortBy="sortBy" @on-click="clickProject(item)" @on-rename="renameProject"
            @on-delete="deletePeoject" @on-tags="updateTags"/>
        </GridItem>
      </Grid>
      <div class="view-list" v-else-if="viewMode==='list'">
        <ProjectItem type="list" :item="item" :list="list" :isReadOnly="isReadOnly" :sortBy="sortBy" @on-click="clickProject(item)" @on-rename="renameProject"
            @on-delete="deletePeoject" @on-tags="updateTags" v-for="item in displayList" :key="item.project_id"/>
      </div>
      <ViewMap :list="displayList" @on-click="clickProject" v-else-if="viewMode==='map'"/>
    </div>
    <div class="list empty" v-else>

    </div>
    <CreateProjectModal ref="modal" @on-ok="createDlgOk"/>
  </div>
</template>
  
<script>
import elementResizeDetectorMaker from 'element-resize-detector'
import ProjectItem from './ProjectItem.vue'
import CreateProjectModal from './CreateProjectModal.vue'
import Search from '../search'
import constants from './constants'
import _ from 'lodash'
import ViewMap from './ViewMap.vue'
export default {
  props: {
    list: {
      type: Array,
      default: []
    },
    isReadOnly: {
      type: Boolean,
      default: false
    },
    enableDataTypeFilter: {
      type: Boolean,
      default: true
    },
    dataTypeFilters: {
      type: Array,
      default: []
    },
    tagFilters: {
      type: Array,
      default: []
    },
    sortBy: {
      type: String,
      default: 'updatedAt'
    },
    viewMode: {
      type: String,
      default: 'card'
    }
  },
  components: {
    ProjectItem,
    CreateProjectModal,
    Search,
    ViewMap
  },
  methods: {
    showCreateDlg() {
      let index = -1
      this.list.forEach(item => {
        let i = -1
        if (item.name === '新建项目') {
          i = 0
        } else {
          let j = Number(item.name.replace('新建项目_', ''))
          if (!Number.isNaN(j)) {
            i = j
          }
        }
        index = Math.max(index, i)
      })
      this.$refs.modal.show({
        name: index !== -1 ? `新建项目_${index + 1}` : '新建项目'
      })
    },
    createDlgOk(name) {
      if (!name) {
        this.$Message.warning('项目名称不能为空')
        return
      }
      let fileNamepatn = /\||<|>|\?|\*|:|\/|\\|"/
      if(fileNamepatn.test(name) ){
        this.$Message.warning('名称不能包含特殊字符')
        return
      }
      let item = this.list.find(d => d.name === name)
      if (item) {
        this.$Message.warning('当前项目名已存在')
        return
      }
      this.$emit('on-create', name)
      this.$refs.modal.dlgShow = false
    },
    clickProject(item) {
      this.$emit('on-click', item)
    },
    renameProject(data) {
      this.$emit('on-rename', data)
    },
    deletePeoject(data) {
      this.$emit('on-delete', data)
    },
    updateTags(data) {
      this.$emit('on-tags', data)
    },
    viewModeChange(name) {
      this.$emit('on-mode-change', name)
    },
    initCardBox() {
      let el = this.$el.querySelector('.list')
      this.cols = Math.floor(el.offsetWidth / 300)
    },
    intersectArray(arrA, arrB) { // 两个数组中相同的元素
      let result = []
      arrA.forEach(d => {
        if (arrB.includes(d)) {
          result.push(d)
        }
      })
      return result
    },
    dataTypeFilterChange(checked, item) {
      let dataTypes = _.cloneDeep(this.dataTypeFilters)
      if (checked && !dataTypes.includes(item.value)) {
        dataTypes.push(item.value)
      } else if (!checked) {
        let index = dataTypes.indexOf(item.value)
        index !== -1 && dataTypes.splice(index, 1)
      }
      this.$emit('on-filter', {
        type: 'data_type',
        value: dataTypes
      })
    },
    tagFilterChange(checked, value) {
      let tags = _.cloneDeep(this.tagFilters)
      if (checked && !tags.includes(value)) {
        tags.push(value)
      } else if (!checked) {
        let index = tags.indexOf(value)
        index !== -1 && tags.splice(index, 1)
      }
      this.$emit('on-filter', {
        type: 'tag',
        value: tags
      })
    },
    sortChange(value) {
      this.$emit('on-sort', value)
    }
  },
  data() {
    return {
      dlgShow: false,
      projectName: '',
      cols: 4,
      keyword: '',
      dataTypes: constants.dataTypes,
      sorts: constants.sorts,
      dataTypeDropdownVisible: false,
      tagDropdownVisible: false
    }
  },
  mounted() {
    this.initCardBox()
    var erd = elementResizeDetectorMaker();
    erd.listenTo(this.$el, element => {
      this.initCardBox()
    });
  },
  computed: {
    displayList() {
      let trimedKeyword = this.keyword.trim()
      let tmp = []
      this.list.forEach(item => {
        let {name, dataTypes = [], tags = []} = item
        if (trimedKeyword && name.indexOf(trimedKeyword) == -1) {
          return
        }
        if (this.dataTypeFilters.length && !this.intersectArray(dataTypes, this.dataTypeFilters).length) {
          return
        }
        if (this.tagFilters.length && !this.intersectArray(tags, this.tagFilters).length) {
          return
        }
        tmp.push(item)
      })
      let sortedList = _.sortBy(tmp, this.sortBy)
      if (this.sortBy === 'name') {
        return sortedList
      } else {
        return sortedList.reverse()
      }
    },
    tags() {
      let arr = []
      this.list.forEach(d => {
        let tags = d.tags || []
        tags.forEach(tag => {
          if (!arr.includes(tag)) {
            arr.push(tag)
          }
        })
      })
      return arr
    }
  }
}
</script>
  