<template>
  <div class="app-container">
    <div class="filter-container" style="position: relative">

      <floating-window :class="{'is_fixed': isFixed}" >
        <el-dropdown @command="handleCommand">
          <img width="50px" height="50px" src="@/assets/navigation.png" alt="导航.png" />
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="detail">食物更新</el-dropdown-item>
            <el-dropdown-item command="unit">单位管理</el-dropdown-item>
            <el-dropdown-item command="modifier">规格管理</el-dropdown-item>
            <el-dropdown-item command="list">食物列表</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </floating-window>

      <el-row>
        营养素:
        <el-select
          ref="nutrientSelect"
          v-model="params.nutrientId"
          filterable
          remote
          reserve-keyword
          :default-first-option="true"
          style="width: 200px;margin-left: 10px;"
          placeholder="请输入营养素关键词"
          :remote-method="queryNutrients"
          :loading="loading"
          @change="nutrientChanged"
        >
          <el-option v-for="item in nutrients" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
        计量:
        <el-radio v-model="params.radio" :label="0" @change="radioChange(params)">值</el-radio>
        <el-radio v-model="params.radio" :label="1" @change="radioChange(params)">范围</el-radio>
        <el-radio v-model="params.radio" :label="2" @change="radioChange(params)">误差</el-radio>
        <div v-if="params.radio === 1" style="display: inline-block">
          大于等于:
          <el-input v-model="params.quantityMin" style="width: 80px;" class="filter-item" @focus="getInputFocus" />
          小于等于:
          <el-input v-model="params.quantityMax" style="width: 80px;" class="filter-item" @focus="getInputFocus" />
        </div>
        <div v-else-if="params.radio === 2" style="display: inline-block">
          基准：
          <el-input v-model="params.quantity" style="width: 80px;" class="filter-item" @focus="getInputFocus" />
          ±：
          <el-input v-model="params.stdError" style="width: 80px;" class="filter-item" @focus="getInputFocus" />
        </div>
        <el-input
          v-else
          v-model="params.quantity"
          style="width: 80px;"
          class="filter-item"
          @focus="getInputFocus"
        />
        <el-autocomplete
          class="inline-input"
          v-model="params.unit"
          :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, params.nutrientId, cb)}"
          @input="handleUnitChanged"
          placeholder="单位关键词"
        />
        <div v-show="showNutrientSource" style="display: inline-block">
          <el-select
            v-model="params.nutrientSource"
            placeholder="请选择营养素来源"
          >
            <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
          </el-select>
        </div>
        <div v-show="showNRV" style="display: inline-block">
          NRV%:
          <el-input
            v-model="params.nrvPercent"
            style="width: 80px;"
            class="filter-item"
          />
        </div>
      </el-row>
      <el-row style="margin-top: 10px">
        <div v-show="!isPercentByVolumeUnit(params)" style="display: inline-block">
          Nv_Spec计量:
          <el-input
            v-model="params.nvSpec"
            style="width: 80px;"
            class="filter-item"
            @focus="getInputFocus"
          />
          <el-autocomplete
            class="inline-input"
            v-model="params.nvSpecUnit"
            :fetch-suggestions="queryUnits"
            placeholder="单位关键词"
          />
        </div>
        信息来源：
        <el-autocomplete
          v-model="params.source"
          :fetch-suggestions="querySources"
          placeholder="请输入信息来源"
        />
        <el-button
          class="filter-item"
          style="margin-left: 10px;"
          type="primary"
          :disabled="!canEdit"
          @click="addNutrient">
          添加
        </el-button>
        <el-button
          class="filter-item"
          style="margin-left: 10px;"
          type="success"
          :disabled="!canEdit"
          @click="handleImport">
          导入营养素
        </el-button>
      </el-row>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%;margin-top: 10px"
      @cell-dblclick="handleEdit"
    >
      <el-table-column type="index" label="序号" align="center" width="60px" />
      <el-table-column label="营养素名称" align="center">
        <template slot-scope="{row}">
          <span>{{ row.nutrientName }}</span>
        </template>
      </el-table-column>
      <el-table-column label="营养素计量" align="center" :width="150">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-radio v-model="row.radio" :label="0" @change="radioChange(row)">值</el-radio>
            <el-radio v-model="row.radio" :label="1" @change="radioChange(row)">范围</el-radio>
            <el-radio v-model="row.radio" :label="2" @change="radioChange(row)">误差</el-radio>
            <div v-if="row.radio === 1" style="display: inline-block">
              大于等于:
              <el-input v-model="row.quantityMin" @focus="getInputFocus" />
              小于等于:
              <el-input v-model="row.quantityMax" @focus="getInputFocus" />
            </div>
            <div v-else-if="row.radio === 2" style="display: inline-block">
              基准：
              <el-input v-model="row.quantity" @focus="getInputFocus" />
              ±：
              <el-input v-model="row.stdError" @focus="getInputFocus" />
            </div>
            <el-input
              v-else
              v-model="row.quantity"
              style="width: 80px;"
              class="filter-item"
              @focus="getInputFocus"
            />
          </template>
          <span v-else>{{ row | nutrientQuantityFilter }}</span>
        </template>
      </el-table-column>
      <el-table-column label="计量单位" align="center" width="150">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-autocomplete
              v-model="row.unit"
              @input="handleRowUnitChanged(row)"
              :fetch-suggestions="(query, cb) => {queryNutrientUnits(query, row.nutrientId, cb)}"
              placeholder="单位关键词"
            />
            <el-select
              clearable
              v-show="showRowNutrientSource"
              v-model="row.nutrientSource"
              placeholder="请选择营养素来源"
            >
              <el-option v-for="item in nutrientSources" :key="item" :label="item" :value="item" />
            </el-select>
          </template>
          <span v-else>{{ row.nutrientSource ? `${row.unit}(${row.nutrientSource})` : row.unit }}</span>
        </template>
      </el-table-column>
      <el-table-column label="NRV%" align="center" width="80">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-input v-show="!isPercentByVolumeUnit(row)" v-model="row.nrvPercent"/>
          </template>
          <span v-else>{{ row.nrvPercent }}</span>
        </template>
      </el-table-column>
      <el-table-column label="Nv_Spec" align="center" width="80">
        <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
          <template v-if="row.edit">
            <el-input v-model="row.nvSpec" class="filter-item" @focus="getInputFocus" />
          </template>
          <span v-else>{{ row.nvSpec }}</span>
        </template>
      </el-table-column>
      <el-table-column label="计量单位" align="center" width="150">
        <template slot-scope="{row}" v-if="!isPercentByVolumeUnit(row)">
          <template v-if="row.edit">
            <el-autocomplete v-model="row.nvSpecUnit" :fetch-suggestions="queryUnits" placeholder="单位关键词" />
          </template>
          <span v-else>{{ row.nvSpecUnit }}</span>
        </template>
      </el-table-column>
      <el-table-column label="信息来源" align="center" width="200">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-autocomplete
              v-model="row.source"
              :fetch-suggestions="querySources"
              placeholder="请输入信息来源"
            />
          </template>
          <span v-else>{{ row.source }}</span>
        </template>
      </el-table-column>
      <el-table-column label="信息来源备注" align="center" width="200">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-input type="text" :rows="2" v-model="row.sourceNote" @focus="getInputFocus" />
          </template>
          <span v-else>{{ row.sourceNote }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="320" fixed="right">
        <template slot-scope="{row}">
          <template v-if="row.edit">
            <el-button
              type="success"
              size="mini"
              @click="confirmEdit(row)"
            >
              提交
            </el-button>
            <el-button
              type="danger"
              size="mini"
              @click="fetchData"
            >
              取消
            </el-button>
          </template>
          <template v-else>
            <el-button size="mini" type="primary" :disabled="!canEdit" @click="handleEdit(row)">编辑</el-button>
            <el-button size="mini" type="primary" :disabled="!canEdit" @click="updateSort(row, 0)">上移</el-button>
            <el-button size="mini" type="primary" :disabled="!canEdit" @click="updateSort(row, 1)">下移</el-button>
            <el-button size="mini" type="danger" :disabled="!canEdit" @click="confirmRemoveNutrient(row)">
              删除
            </el-button>
          </template>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog title="导入营养素" :visible.sync="dialogFormVisible" v-loading="importLoading">
      <el-form ref="dialogForm" label-position="left" style="width: 80%; margin-left:50px;">
        <el-radio :label="0" v-model="importType" @change="handleImportTypeChange" >从模板导入</el-radio>
        <el-radio :label="1" v-model="importType" @change="handleImportTypeChange" style="margin-bottom: 10px">从食物导入</el-radio>
        <el-form-item prop="importId">
          <el-select
            v-model="importId"
            class="filter-item"
            filterable
            remote
            reserve-keyword
            placeholder="请输入关键词"
            :loading="importLoading"
            :remote-method="queryImportItems"
            style="width: 100%"
          >
            <el-option v-for="item in importItems" :key="`import${item.id}`" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="submitImport">
          提交
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getNutrientList, addFoodNutrient, updateFoodNutrient, removeFoodNutrient,
  updateFoodNutrientSort, confirmDeleteFoodNutrient, importNutrientsFromTemplate,
  getList as getFoodList, importNutrientFromSimilarFood, getDetail } from '@/api/food'
import FloatingWindow from '@/components/FloatingWindow'
import { getList, getNutrientUnits, getNutrientSources } from '@/api/nutrient'
import { getList as getUnits } from '@/api/unit'
import { getNutrientTemplates } from '@/api/nutrientTemplate'
import store from '@/store'

// 特殊营养素 若单位不为baseUnit，则需要填写来源
const SPECIAL_NUTRIENT_NAMES = ['维生素A', '维生素D', '维生素E', '烟酸', '叶酸']

export default {
  name: 'AddNutrient',
  components: { FloatingWindow },
  mounted() {
    window.addEventListener('scroll', this.initHeight);
  },
  //回调中移除监听
  destroyed() {
    window.removeEventListener('scroll', this.handleScroll)
  },
  created() {
    this.foodId = this.$route.params && this.$route.params.id
    this.fetchData()
    this.queryNutrients()
  },
  filters: {
    nutrientQuantityFilter(row) {
      if (row.stdError) {
        return `${row.quantity} ± ${row.stdError}`
      }else if (row.quantityMin && row.quantityMax) {
        return `${row.quantityMin} ~ ${row.quantityMax}`
      } else if (row.quantityMin) {
        return `≥${row.quantityMin}`
      } else if (row.quantityMax) {
        return `≤${row.quantityMax}`
      } else {
        return row.quantity
      }
    }
  },
  data() {
    return {
      tableKey: 0,
      listLoading: false,
      units: [],
      foodId: '',
      list: [],
      nutrients: [],
      params: { source: '营养标签', radio: 0, nvSpec: 100, nvSpecUnit: '克' },
      loading: false,
      unitLoading: false,
      sources: [{ value: "营养标签" }, { value: "食品官方资料" }, { value: "计算值" }],
      dialogFormVisible: false,
      importType: 0,
      importId: '',
      importLoading: false,
      importItems: [],
      isFixed: false,
      offsetTop: 0,
      showNutrientSource: false,
      showRowNutrientSource: false,
      nutrientSources: [],
      showNRV: false,
      canEdit: true
    }
  },
  methods: {
    fetchData() {
      this.listLoading = true
      getNutrientList(this.foodId).then(res => {
        this.list = res.data
        this.listLoading = false
        if (this.list.length > 0) {
          this.$set(this.params, "nvSpec", this.list[0].nvSpec)
          this.$set(this.params, "nvSpecUnit", this.list[0].nvSpecUnit)
        } else {
          this.$set(this.params, 'nvSpec', 100)
          this.$set(this.params, 'nvSpecUnit', '克')
        }
      })
      getDetail(this.foodId).then(res => {
        if (!store.getters.isAdmin && res.data.userId !== store.getters.userId) {
          this.canEdit = false
        }
      })
    },
    addNutrient() {
      this.params.foodId = this.foodId
      addFoodNutrient(this.foodId, this.params).then(res => {
        this.params = { source: '营养标签', radio: 0 }
        this.fetchData()
        this.$notify.success('添加营养素成功')
        this.$refs.nutrientSelect.focus()
      }).catch(res => {
        this.$message.error(res.data.message)
      })
    },
    confirmEdit(row) {
      updateFoodNutrient(this.foodId, row.nutrientId, row).then(res => {
        this.fetchData()
        this.$notify.success('提交成功')
      }).catch(res => {
        this.$message.error(res.data.message)
      })
    },
    confirmRemoveNutrient(row) {
      confirmDeleteFoodNutrient(row.foodId, row.nutrientId).then(res => {
        if (!res.data) {
          this.$confirm('由于单位转换的原因，删除此条营养素关联数据，将会导致该食物被删除，是否继续？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.removeNutrient(row)
          })
        } else {
          this.removeNutrient(row)
        }
      }).catch(res => {
        this.$message.error(res.data.message)
      })
    },
    removeNutrient(row) {
      removeFoodNutrient(row.foodId, row.nutrientId).then(res => {
        this.fetchData()
        this.$notify.success('删除营养素成功')
        this.$refs.nutrientSelect.focus()
      }).catch(res => {
        this.$message.error(res.data.message)
      })
    },
    queryNutrients(query) {
      getList({ query }).then(res => {
        this.nutrients = res.data.list
      }).catch(() => {
        this.nutrients = []
      })
    },
    queryNutrientUnits(query, nutrientId, cb) {
      let units = []
      getNutrientUnits(nutrientId, { query }).then(res => {
        res.data.forEach(item => units.push({ value: item }))
        cb(units)
      })
    },
    queryUnits(query, cb) {
      let units = []
      getUnits({ query }).then(res => {
        res.data.list.forEach(item => units.push({ value: item.name }))
        cb(units)
      })
    },
    updateSort(row, type) {
      updateFoodNutrientSort(this.foodId, row.nutrientId, { type }).then(res => {
        this.$notify.success('提交成功')
        this.fetchData()
      }).catch(res => {
        this.$message.error(res.data.message)
      })
    },
    querySources(query, cb) {
      let sources = this.sources
      let results = query ? sources.filter(this.sourcesFilter(query)) : sources;
      cb(results)
    },
    sourcesFilter(query) {
      return (restaurant) => {
        return (restaurant.value.toLowerCase().indexOf(query.toLowerCase()) === 0);
      };
    },
    handleEdit(row) {
      if (!this.canEdit) {
        return
      }
      this.$set(row, 'edit', true)
      if (row.quantityMax || row.quantityMin) {
        this.$set(row, 'radio', 1)
      } else if (row.stdError) {
        this.$set(row, 'radio', 2)
      } else {
        this.$set(row, 'radio', 0)
      }
      this.handleRowUnitChanged(row)
    },
    radioChange(row) {
      this.$set(row, 'stdError', '')
      this.$set(row, 'quantityMin', '')
      this.$set(row, 'quantityMax', '')
      this.$set(row, 'quantity', '')
    },
    nutrientChanged(value) {
      for (let nutrient of this.nutrients) {
        if (nutrient.id === value) {
          this.$set(this.params, 'unit', nutrient.baseUnit)
          if (nutrient.nrvUnit) {
            this.showNRV = true
          } else {
            this.showNRV = false
          }
          break
        }
      }
    },
    getInputFocus(event) {
      event.currentTarget.select();
    },
    handleImport() {
      this.query = ''
      this.importId = ''
      this.importType = 0
      this.importItems = []
      this.queryImportItems()
      this.dialogFormVisible = true
    },
    handleImportTypeChange() {
      this.importId = ''
      this.importItems = []
      this.queryImportItems()
    },
    queryImportItems(query=''){
      this.importType === 0 ? this.queryTemplates(query) : this.queryFoods(query)
    },
    queryTemplates(query='') {
      this.importLoading = true
      getNutrientTemplates({ query }).then(res => {
        this.importItems = res.data.list
        if (this.importItems.length > 0) {
          this.importId = this.importItems[0].id
        }
        this.importLoading = false
      }).catch(() => {
        this.importItems = []
        this.importLoading = false
      })
    },
    queryFoods(query='') {
      this.importLoading = true
      getFoodList({ query: query, orderBy: 0, pageNum: 1, pageSize: 20 }).then(res => {
        this.importItems = res.data.list
        this.importLoading = false
      }).catch(() => {
        this.importItems = []
        this.importLoading = false
      })
    },
    submitImport() {
      this.importLoading = true
      const resPromise = this.importType === 0 ?
        importNutrientsFromTemplate(this.foodId, { templateId: this.importId }) :
        importNutrientFromSimilarFood(this.foodId, { foodId: this.importId })
      resPromise.then(res => {
        this.fetchData()
        this.$notify.success("提交成功")
        this.dialogFormVisible = false
        this.importLoading = false
      }).catch(res => {
        this.$message.error(res.data.message)
        this.importLoading = false
        this.dialogFormVisible = false
      })
    },
    initHeight() {
      // 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 (被卷曲的高度)
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
      this.isFixed = scrollTop > this.offsetTop;
    },
    handleCommand(value) {
      let path = ''
      if (value === 'detail') {
        path = `/food/edit/${this.foodId}`
      } else if (value === 'unit') {
        path = `/food/${this.foodId}/unit`
      } else if (value === 'nutrient') {
        path = `/food/${this.foodId}/nutrient`
      } else if (value === 'modifier') {
        path = `/food/${this.foodId}/modifier`
      } else if (value === 'list') {
        path = store.getters.isAdmin ? '/food' : '/food/entry'
      }
      if (path) {
        this.$router.push({ path: path })
      }
    },
    isPercentByVolumeUnit(row) {
      return row && row.unit === '%Vol'
    },
    isSpecialNutrient(nutrientId) {
      let nutrient = null
      for (let i = 0; i < this.nutrients.length; i++) {
        if (this.nutrients[i].id === nutrientId) {
          nutrient = this.nutrients[i]
          break
        }
      }

      // 如果特殊营养素单位不等于baseUnit，则显示来源
      return nutrient && SPECIAL_NUTRIENT_NAMES.indexOf(nutrient.name) > -1
    },
    handleUnitChanged() {
      if (this.isSpecialNutrient(this.params.nutrientId)) {
        getNutrientSources(this.params.nutrientId, { unit: this.params.unit }).then(res => {
          this.nutrientSources = res.data
          if (this.nutrientSources.length > 0){
            this.params.nutrientSource = this.nutrientSources[0]
            this.showNutrientSource = true
          } else {
            this.showNutrientSource = false
            this.params.nutrientSource = null
          }
        })
      } else {
        this.showNutrientSource = false
        this.params.nutrientSource = null
      }
    },
    handleRowUnitChanged(row) {
      if (SPECIAL_NUTRIENT_NAMES.indexOf(row.nutrientName) > -1) {
        getNutrientSources(row.nutrientId, { unit: row.unit }).then(res => {
          this.nutrientSources = res.data
          if (this.nutrientSources.length > 0){
            if (!row.nutrientSource) {
              row.nutrientSource = this.nutrientSources[0]
            }
            this.showRowNutrientSource = true
          } else {
            this.showRowNutrientSource = false
            row.nutrientSource = null
          }
        })
      } else {
        this.showRowNutrientSource = false
        row.nutrientSource = null
      }
    }
  }
}
</script>

<style scoped>

</style>
