<template>
  <div class="app-container">
    <el-card shadow="never">
      <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
        <el-form-item prop="monitorName">
          <template slot="label">{{ vsT("queryMonitorName") }}</template>
          <el-input
            v-model="queryParams.monitorName"
            :placeholder="vsT('queryMonitorNamePh')"
            clearable
            style="width: 220px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item prop="queryOwnerKey">
          <template slot="label">{{ vsT("queryOwner") }}</template>
          <el-select
            v-model="queryOwnerKey"
            filterable
            remote
            reserve-keyword
            clearable
            :placeholder="vsT('queryOwnerPh')"
            :remote-method="searchOwner"
            :loading="ownerLoading"
            style="width: 280px"
            @focus="searchOwner('')"
          >
            <el-option
              v-for="item in ownerOptions"
              :key="ownerOptionKey(item)"
              :label="ownerOptionLabel(item)"
              :value="ownerOptionKey(item)"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ vsCommon("search") }}</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ vsCommon("reset") }}</el-button>
          <el-button
            v-hasPermi="['videoSurveillance:livestockMonitor:add']"
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
          >{{ vsCommon("add") }}</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <br />

    <el-card shadow="never">
      <el-table v-loading="loading" :data="tableList" border>
        <el-table-column :label="vsT('colMonitorName')" prop="monitorName" align="center" min-width="120" :show-overflow-tooltip="true" />
        <el-table-column :label="vsT('colOwner')" align="center" min-width="200" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.ownerType" :type="ownerTypeTagType(scope.row.ownerType)" size="mini" class="owner-type-tag">
              {{ ownerTypeName(scope.row.ownerType) }}
            </el-tag>
            <span>{{ scope.row.ownerName || dash }}</span>
          </template>
        </el-table-column>
        <el-table-column :label="vsT('colInstallLocation')" prop="installLocation" align="center" min-width="120" :show-overflow-tooltip="true" />
        <el-table-column :label="vsCommon('colOp')" align="center" class-name="small-padding fixed-width" width="300" fixed="right">
          <template slot-scope="scope">
            <el-button type="text" size="mini" @click="handleLiveView">{{ vsT("actionLiveView") }}</el-button>
            <el-button
              v-hasPermi="['videoSurveillance:livestockMonitor:query']"
              type="text"
              size="mini"
              @click="handleView(scope.row)"
            >{{ vsCommon("view") }}</el-button>
            <el-button
              v-hasPermi="['videoSurveillance:livestockMonitor:edit']"
              type="text"
              size="mini"
              @click="handleEdit(scope.row)"
            >{{ vsCommon("edit") }}</el-button>
            <el-button
              v-hasPermi="['videoSurveillance:livestockMonitor:remove']"
              type="text"
              size="mini"
              @click="handleDelete(scope.row)"
            >{{ vsCommon("delete") }}</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>

    <el-dialog :title="dialogTitle" :visible.sync="open" width="560px" append-to-body @close="cancel">
      <el-form :key="formKey" ref="form" :model="form" label-width="110px">
        <el-form-item prop="monitorName" :rules="formRules.monitorName">
          <template slot="label">{{ vsT("formMonitorName") }}</template>
          <el-input v-model="form.monitorName" :placeholder="vsT('phMonitorName')" maxlength="10" show-word-limit />
        </el-form-item>
        <el-form-item prop="ownerSelectKey" :rules="formRules.ownerSelectKey">
          <template slot="label">{{ vsT("formOwner") }}</template>
          <el-select
            v-model="form.ownerSelectKey"
            filterable
            remote
            reserve-keyword
            :placeholder="vsT('phOwner')"
            :remote-method="searchOwner"
            :loading="ownerLoading"
            style="width: 100%"
            @focus="searchOwner('')"
          >
            <el-option
              v-for="item in ownerOptions"
              :key="ownerOptionKey(item)"
              :label="ownerOptionLabel(item)"
              :value="ownerOptionKey(item)"
            />
          </el-select>
        </el-form-item>
        <el-form-item prop="installLocation" :rules="formRules.installLocation">
          <template slot="label">{{ vsT("formInstallLocation") }}</template>
          <el-input v-model="form.installLocation" :placeholder="vsT('phInstallLocation')" maxlength="10" show-word-limit />
        </el-form-item>
        <el-form-item prop="ipAddress" :rules="formRules.ipAddress">
          <template slot="label">{{ vsT("formIpAddress") }}</template>
          <el-input v-model="form.ipAddress" :placeholder="vsT('phIpAddress')" maxlength="20" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">{{ vsCommon("ok") }}</el-button>
        <el-button @click="cancel">{{ vsCommon("cancel") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="vsCommon('viewTitle')" :visible.sync="viewOpen" width="560px" append-to-body>
      <el-form label-width="110px" size="small">
        <el-form-item :label="vsT('viewMonitorName')">
          <span>{{ viewRow.monitorName || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewOwner')">
          <el-tag v-if="viewRow.ownerType" :type="ownerTypeTagType(viewRow.ownerType)" size="mini" class="owner-type-tag">
            {{ ownerTypeName(viewRow.ownerType) }}
          </el-tag>
          <span>{{ viewRow.ownerName || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewInstallLocation')">
          <span>{{ viewRow.installLocation || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewIpAddress')">
          <span>{{ viewRow.ipAddress || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsCommon('colCreate')">
          <span>{{ viewRow.createTime ? parseTime(viewRow.createTime) : dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewCreateBy')">
          <span>{{ viewRow.createBy || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewUpdateBy')">
          <span>{{ viewRow.updateBy || dash }}</span>
        </el-form-item>
        <el-form-item :label="vsT('viewUpdateTime')">
          <span>{{ viewRow.updateTime ? parseTime(viewRow.updateTime) : dash }}</span>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button
          v-hasPermi="['videoSurveillance:livestockMonitor:edit']"
          type="primary"
          @click="handleEditFromView"
        >{{ vsCommon("edit") }}</el-button>
        <el-button @click="viewOpen = false">{{ vsCommon("close") }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import videoSurveillanceLocaleMixin from "@/mixins/videoSurveillanceLocaleMixin"
import {
  listLivestockMonitor,
  getLivestockMonitor,
  addLivestockMonitor,
  updateLivestockMonitor,
  delLivestockMonitor,
  listLivestockMonitorOwnerOptions
} from "@/api/videoSurveillance/livestockMonitor"

const IPV4_REG = /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/

function createEmptyForm() {
  return {
    id: undefined,
    monitorName: undefined,
    ownerSelectKey: undefined,
    installLocation: undefined,
    ipAddress: undefined
  }
}

export default {
  name: "VideoSurveillanceLivestockMonitor",
  mixins: [videoSurveillanceLocaleMixin],
  data() {
    return {
      vsNs: "livestockMonitor",
      loading: false,
      open: false,
      viewOpen: false,
      viewRow: {},
      dialogEdit: false,
      formKey: 0,
      total: 0,
      tableList: [],
      ownerOptions: [],
      ownerLoading: false,
      ownerSearchTimer: null,
      queryOwnerKey: undefined,
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        monitorName: undefined,
        ownerType: undefined,
        ownerId: undefined
      },
      form: createEmptyForm()
    }
  },
  computed: {
    dash() {
      return this.$t("videoSurveillance.status.dash")
    },
    dialogTitle() {
      return this.dialogEdit ? this.vsT("dialogEdit") : this.vsT("dialogAdd")
    },
    formRules() {
      return {
        monitorName: [
          { required: true, message: this.vsT("ruleMonitorNameRequired"), trigger: "blur" },
          { validator: this.validateMonitorName, trigger: "blur" }
        ],
        ownerSelectKey: [
          { required: true, message: this.vsT("ruleOwnerRequired"), trigger: "change" }
        ],
        installLocation: [
          { required: true, message: this.vsT("ruleInstallLocationRequired"), trigger: "blur" },
          { validator: this.validateInstallLocation, trigger: "blur" }
        ],
        ipAddress: [
          { required: true, message: this.vsT("ruleIpRequired"), trigger: "blur" },
          { validator: this.validateIpAddress, trigger: "blur" }
        ]
      }
    }
  },
  created() {
    this.getList()
  },
  beforeDestroy() {
    if (this.ownerSearchTimer) {
      clearTimeout(this.ownerSearchTimer)
    }
  },
  methods: {
    ownerTypeName(ownerType) {
      if (ownerType === 1) {
        return this.$t("videoSurveillance.status.ownerType1")
      }
      if (ownerType === 2) {
        return this.$t("videoSurveillance.status.ownerType2")
      }
      return this.dash
    },
    ownerOptionKey(item) {
      return `${item.ownerType}-${item.ownerId}`
    },
    ownerOptionLabel(item) {
      const typeName = item.ownerTypeName || this.ownerTypeName(item.ownerType)
      return `[${typeName}] ${item.ownerName || ""}`
    },
    parseOwnerKey(key) {
      if (!key) {
        return { ownerType: undefined, ownerId: undefined }
      }
      const idx = String(key).indexOf("-")
      if (idx < 0) {
        return { ownerType: undefined, ownerId: undefined }
      }
      return {
        ownerType: parseInt(String(key).slice(0, idx), 10),
        ownerId: parseInt(String(key).slice(idx + 1), 10)
      }
    },
    ensureOwnerOptionInList(ownerType, ownerId, ownerName, ownerTypeName) {
      if (ownerType == null || ownerId == null) {
        return
      }
      const key = `${ownerType}-${ownerId}`
      if (this.ownerOptions.some((o) => this.ownerOptionKey(o) === key)) {
        return
      }
      this.ownerOptions = [
        {
          ownerType,
          ownerId,
          ownerName: ownerName || "",
          ownerTypeName: ownerTypeName || this.ownerTypeName(ownerType)
        },
        ...this.ownerOptions
      ]
    },
    searchOwner(keyword) {
      if (this.ownerSearchTimer) {
        clearTimeout(this.ownerSearchTimer)
      }
      this.ownerSearchTimer = setTimeout(() => {
        this.ownerLoading = true
        const kw = keyword != null ? String(keyword).trim() : ""
        listLivestockMonitorOwnerOptions({ keyword: kw || undefined })
          .then((res) => {
            this.ownerOptions = Array.isArray(res.data) ? res.data : []
          })
          .finally(() => {
            this.ownerLoading = false
          })
      }, 300)
    },
    validateMonitorName(rule, value, callback) {
      const text = value != null ? String(value).trim() : ""
      if (!text) {
        callback(new Error(this.vsT("ruleMonitorNameRequired")))
        return
      }
      if (text.length > 10) {
        callback(new Error(this.vsT("ruleMonitorNameLen")))
        return
      }
      callback()
    },
    validateInstallLocation(rule, value, callback) {
      const text = value != null ? String(value).trim() : ""
      if (!text) {
        callback(new Error(this.vsT("ruleInstallLocationRequired")))
        return
      }
      if (text.length > 10) {
        callback(new Error(this.vsT("ruleInstallLocationLen")))
        return
      }
      callback()
    },
    validateIpAddress(rule, value, callback) {
      const text = value != null ? String(value).trim() : ""
      if (!text) {
        callback(new Error(this.vsT("ruleIpRequired")))
        return
      }
      if (text.length > 20) {
        callback(new Error(this.vsT("ruleIpLen")))
        return
      }
      if (!IPV4_REG.test(text)) {
        callback(new Error(this.vsT("ruleIpFormat")))
        return
      }
      callback()
    },
    buildListQuery() {
      const q = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      }
      const name = this.queryParams.monitorName != null ? String(this.queryParams.monitorName).trim() : ""
      if (name) {
        q.monitorName = name
      }
      const parsed = this.parseOwnerKey(this.queryOwnerKey)
      if (parsed.ownerType != null && !isNaN(parsed.ownerType) && parsed.ownerId != null && !isNaN(parsed.ownerId)) {
        q.ownerType = parsed.ownerType
        q.ownerId = parsed.ownerId
      }
      return q
    },
    buildPayload() {
      const parsed = this.parseOwnerKey(this.form.ownerSelectKey)
      return {
        monitorName: String(this.form.monitorName).trim(),
        ownerType: parsed.ownerType,
        ownerId: parsed.ownerId,
        installLocation: String(this.form.installLocation).trim(),
        ipAddress: String(this.form.ipAddress).trim()
      }
    },
    resetFormModel() {
      this.form = createEmptyForm()
    },
    fillFormFromData(data) {
      const ownerSelectKey =
        data.ownerType != null && data.ownerId != null ? `${data.ownerType}-${data.ownerId}` : undefined
      this.ensureOwnerOptionInList(data.ownerType, data.ownerId, data.ownerName, data.ownerTypeName)
      this.form = Object.assign(createEmptyForm(), {
        id: data.id,
        monitorName: data.monitorName,
        ownerSelectKey,
        installLocation: data.installLocation,
        ipAddress: data.ipAddress
      })
    },
    getList() {
      this.loading = true
      listLivestockMonitor(this.buildListQuery())
        .then((res) => {
          this.tableList = res.rows || []
          this.total = res.total != null ? res.total : 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    resetQuery() {
      this.queryParams.monitorName = undefined
      this.queryParams.ownerType = undefined
      this.queryParams.ownerId = undefined
      this.queryOwnerKey = undefined
      this.resetForm("queryForm")
      this.handleQuery()
    },
    handleAdd() {
      this.formKey += 1
      this.resetFormModel()
      this.dialogEdit = false
      this.open = true
      this.searchOwner("")
      this.$nextTick(() => {
        if (this.$refs.form) {
          this.$refs.form.clearValidate()
        }
      })
    },
    handleEdit(row) {
      getLivestockMonitor(row.id).then((res) => {
        const data = res.data || {}
        this.formKey += 1
        this.dialogEdit = true
        this.fillFormFromData(data)
        this.open = true
        this.viewOpen = false
        this.searchOwner(data.ownerName || "")
        this.$nextTick(() => {
          if (this.$refs.form) {
            this.$refs.form.clearValidate()
          }
        })
      })
    },
    handleEditFromView() {
      this.handleEdit(this.viewRow)
    },
    handleView(row) {
      getLivestockMonitor(row.id).then((res) => {
        this.viewRow = res.data || {}
        this.viewOpen = true
      })
    },
    handleLiveView() {
      this.$modal.msgWarning(this.vsT("msgLiveNotOpen"))
    },
    handleDelete(row) {
      this.$modal
        .confirm(this.vsT("confirmDelete"))
        .then(() => delLivestockMonitor(row.id))
        .then(() => {
          this.$modal.msgSuccess(this.vsCommon("msgDelOk"))
          this.viewOpen = false
          this.getList()
        })
        .catch(() => {})
    },
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        const payload = this.buildPayload()
        if (this.dialogEdit) {
          payload.id = this.form.id
          updateLivestockMonitor(payload).then(() => {
            this.$modal.msgSuccess(this.vsCommon("msgModOk"))
            this.open = false
            this.getList()
          })
        } else {
          addLivestockMonitor(payload).then(() => {
            this.$modal.msgSuccess(this.vsCommon("msgAddOk"))
            this.open = false
            this.getList()
          })
        }
      })
    },
    cancel() {
      this.open = false
      this.resetFormModel()
    }
  }
}
</script>

<style scoped>
.owner-type-tag {
  margin-right: 6px;
  vertical-align: middle;
}
</style>
