<template>
  <div class="app-container">
    <!--工具栏-->
    <div class="head-container">
      <div class="filter-container">
        <el-input
          v-model="query.name"
          clearable
          size="small"
          placeholder="请输入飞行器名称"
          style="width: 200px"
          class="filter-item"
        />
        <el-select
          v-model="query.employeesId"
          placeholder="请选择负责人"
          clearable
          size="small"
          style="width: 200px"
          class="filter-item"
        >
          <el-option
            v-for="employee in employeeOptions"
            :key="employee.id"
            :label="employee.name"
            :value="employee.id"
          />
        </el-select>
        <el-select
          v-model="query.areaId"
          placeholder="请选择区域"
          size="small"
          style="width: 200px"
          class="filter-item"
        >
          <el-option
            v-for="area in areaOptions"
            :key="area.id"
            :label="area.name"
            :value="area.id"
          />
        </el-select>
        <el-button
          class="filter-item"
          size="small"
          type="primary"
          icon="el-icon-search"
          @click="crud.toQuery"
          >查询</el-button
        >
        <el-button
          v-permission="permission.add"
          class="filter-item"
          size="small"
          type="success"
          icon="el-icon-plus"
          @click="crud.toAdd"
          v-if="checkPer(permission.add)"
          >新增飞行器</el-button
        >
      </div>
    </div>
    <!--表单渲染-->
    <el-dialog
      append-to-body
      :close-on-click-modal="false"
      :before-close="crud.cancelCU"
      :visible.sync="crud.status.cu > 0"
      :title="crud.status.title"
      width="580px"
    >
      <el-form
        ref="form"
        :inline="true"
        :model="form"
        :rules="rules"
        size="small"
        label-width="100px"
      >
        <el-form-item label="飞行器名称" prop="name">
          <el-input v-model="form.name" style="width: 150px" />
        </el-form-item>
        <el-form-item label="型号" prop="model">
          <el-input v-model="form.model" style="width: 150px" />
        </el-form-item>
        <el-form-item label="类型" prop="useType">
          <el-select v-model="form.useType" style="width: 150px">
            <el-option :value="0" label="载物飞行" />
            <el-option :value="1" label="载人飞行" />
            <el-option :value="2" label="其他" />
          </el-select>
        </el-form-item>
        <el-form-item label="区域" prop="areaId">
          <el-select
            v-model="form.areaId"
            @change="changeArea"
            style="width: 150px"
          >
            <el-option
              v-for="area in areaOptions"
              :key="area.id"
              :label="area.name"
              :value="area.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="景区" prop="scenicId">
          <el-select v-model="form.scenicId" style="width: 150px">
            <el-option
              v-for="scenic in scenicOptions"
              :key="scenic.id"
              :label="scenic.name"
              :value="scenic.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="负责人" prop="employeesId">
          <el-select v-model="form.employeesId" style="width: 150px">
            <el-option
              v-for="employee in employeeOptions"
              :key="employee.id"
              :label="employee.name"
              :value="employee.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="remarks" :label-width="'100px'">
          <el-input
            type="textarea"
            :rows="2"
            placeholder="请输入备注"
            v-model="form.remarks"
            style="width: 150px"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="设备图片" prop="deviceImages" style="width: 100%">
          <div class="upload-container">
            <el-upload
              ref="uploadRef"
              action="#"
              list-type="picture-card"
              :show-file-list="false"
              :on-change="handleChange"
              :auto-upload="false"
              accept="image/*"
              :class="{ 'upload-item': true }"
            >
              <div
                style="
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  justify-content: center;
                  margin-top: -20px;
                "
              >
                <i class="el-icon-plus" style="font-size: 30px" />
                <span style="margin: 5px 0 -20px; line-height: 20px">上传</span>
              </div>
            </el-upload>
            <div
              v-for="(image, index) in form.deviceImages"
              :key="index"
              class="preview-item"
            >
              <img :src="image.fileFullPath" class="preview-image" alt="" />
              <span class="preview-actions">
                <span
                  class="preview-action"
                  @click="handlePictureCardPreview(image.fileFullPath)"
                >
                  <i class="el-icon-zoom-in" />
                </span>
                <span class="preview-action" @click="handleRemoveImage(index)">
                  <i class="el-icon-delete" />
                </span>
              </span>
            </div>
          </div>
          <el-dialog append-to-body :visible.sync="dialogVisible" top="20vh">
            <div>
              <img
                :src="dialogImageUrl"
                style="width: 100%"
                alt="Preview Image"
              />
            </div>
          </el-dialog>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="text" @click="crud.cancelCU">取消</el-button>
        <el-button
          :loading="crud.status.cu === 2"
          type="primary"
          @click="crud.submitCU"
          >确认</el-button
        >
      </div>
    </el-dialog>
    <!--表格渲染-->
    <el-table
      ref="table"
      v-loading="crud.loading"
      :data="crud.data"
      row-key="id"
      @select="crud.selectChange"
      @select-all="crud.selectAllChange"
      @selection-change="crud.selectionChangeHandler"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column label="飞行器名称" prop="name" />
      <el-table-column label="型号" prop="model" />
      <el-table-column label="类型" prop="useType">
        <template slot-scope="scope">
          {{
            scope.row.useType === 0
              ? "载物行动"
              : scope.row.useType === 1
              ? "载人行动"
              : "其他"
          }}
        </template>
      </el-table-column>
      <el-table-column label="负责人" prop="username" />
      <el-table-column label="区域" prop="areaName" />
      <el-table-column label="景区" prop="scenicName" />
      <el-table-column label="创建时间" prop="createTime" width="180" />
      <el-table-column label="操作" width="150" align="center" fixed="right">
        <template slot-scope="scope">
          <el-button size="mini" type="text" @click="handleView(scope.row)">
            查看
          </el-button>
          <el-button
            size="mini"
            type="text"
            @click="crud.toEdit(scope.row)"
            v-permission="permission.edit"
            v-if="checkPer(permission.edit)"
          >
            修改
          </el-button>
          <el-button
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-permission="permission.del"
            v-if="checkPer(permission.del)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--分页-->
    <div class="pagination-container">
      <el-pagination
        :background="true"
        :current-page.sync="page.page"
        :page-size.sync="page.size"
        :layout="'total, sizes, prev, pager, next, jumper'"
        :page-sizes="[10, 20, 50, 100]"
        :total="page.total"
        @size-change="crud.sizeChangeHandler"
        @current-change="crud.pageChangeHandler"
      />
    </div>
  </div>
</template>

<script>
import CRUD, { presenter, header, form, crud } from "@crud/crud";
import udOperation from "@crud/UD.operation";
import crudAircraft from "@/api/aircraft";
import { allAreas } from "@/api/system/area";
import { getList, getDetail } from "@/api/system/pilot";
import { allScenic } from "@/api/system/scenic";
import { upload } from "@/utils/upload";
import { mapGetters } from "vuex";
import rrOperation from "@crud/RR.operation";
// crud交由presenter持有
const defaultForm = {
  id: 1,
  name: null,
  brand: null,
  model: null,
  useType: 0,
  areaId: null,
  scenicId: null,
  employeesId: null,
  deviceImages: [],
  remark: "",
  createTime: null,
};
export default {
  name: "aircraft",
  components: { udOperation },
  cruds() {
    return CRUD({
      title: "飞行器",
      url: "aerocraftAdminApi/aircraft/device/page",
      crudMethod: {
        ...crudAircraft,
        getList: crudAircraft.getDevicePage,
      },
      optShow: {
        search: true,
      },
      queryOnPresenterCreated: true, // 启用初始化时自动查询
      page: {
        // 配置分页参数名称
        page: "current",
        size: "size",
      },
      // 配置查询参数
      query: {
        employeesId: undefined,
        areaId: undefined,
        name: undefined,
      },
      initData: (crud, data) => {
        crud.page.total = data.total;
        // 确保每条记录的id是字符串类型
        const records = data.records || [];
        crud.data = records.map(item => ({
          ...item,
          id: item.id ? item.id.toString() : ''
        }));
        // username字段需要通过getList()获取
        crud.data.forEach((item) => {
          if (item.employeesId) {
            getList().then((res) => {
              res.content.forEach((employee) => {
                if (employee.id === item.employeesId) {
                  item.username = employee.username;
                }
              });
            });
          } else {
            item.username = "未知";
          }
        });
      },
    });
  },
  mixins: [presenter(), header(), form(defaultForm), crud()],
  data() {
    return {
      dialogVisible: false,
      dialogImageUrl: "",
      uploadDisabled: false,
      // ini
      page: {
        page: 1,
        size: 10,
        total: 5,
      },
      areaOptions: [],
      scenicOptions: [],
      employeeOptions: [],
      // 默认数据
      query: {
        name: "",
        employeesId: undefined,
        areaId: undefined,
        current: 1,
        size: 10,
      },
      defaultData: [],
      permission: {
        add: ["admin", "aircraft:add"],
        edit: ["admin", "aircraft:edit"],
        del: ["admin", "aircraft:del"],
      },
      rules: {
        name: [
          { required: true, message: "请输入飞行器名称", trigger: "blur" },
        ],
        brand: [{ required: true, message: "品牌不能为空", trigger: "blur" }],
        model: [{ required: true, message: "请输入型号", trigger: "blur" }],
        useType: [{ required: true, message: "请选择类型", trigger: "change" }],
        areaId: [{ required: true, message: "请选择区域", trigger: "change" }],
        scenicId: [
          { required: true, message: "请选择景区", trigger: "change" },
        ],
        employeesId: [
          { required: true, message: "请选择负责人", trigger: "change" },
        ],
        deviceImages: [
          {
            required: true,
            message: "请上传设备图片",
            trigger: "change",
            type: "array",
          },
        ],
      },
    };
  },
  computed: {
    ...mapGetters(["imagesUploadApi", "baseApi"]),
  },
  created() {
    // 获取区域列表
    this.getAreas();
    // 获取飞行员列表
    this.getEmployees();
  },
  methods: {
    // 获取区域列表
    async getAreas() {
      try {
        const res = await allAreas();
        if (res) {
          this.areaOptions = res.map((area) => ({
            id: area.id,
            name: area.name,
          }));
        }
      } catch (error) {
        this.$message.error("获取区域列表失败");
        console.error("获取区域列表失败:", error);
        this.areaOptions = [];
      }
    },

    // 切换区域时获取景区列表
    changeArea(value) {
      // 清空景区选择
      this.query.scenicId = undefined;
      // 获取对应区域的景区列表
      allScenic({ areaId: value }).then((res) => {
        if (res) {
          this.scenicOptions = (res || []).map((scenic) => ({
            id: scenic.id,
            name: scenic.name,
          }));
        } else {
          this.scenicOptions = [];
        }
      });
    },

    // 获取负责人列表
    async getEmployees() {
      try {
        const res = await getList();
        if (res) {
          this.employeeOptions = res.content.map((employee) => ({
            id: employee.id,
            name: employee.username,
          }));
        }
      } catch (error) {
        this.$message.error("获取负责人列表失败");
        console.error("获取负责人列表失败:", error);
        this.employeeOptions = [];
      }
    },

    [CRUD.HOOK.beforeToEdit](crud, form) {
      // 获取对应的景区列表
      if (form.areaId) {
        allScenic({ areaId: form.areaId }).then((res) => {
          if (res) {
            this.scenicOptions = (res || []).map((scenic) => ({
              id: scenic.id,
              name: scenic.name,
            }));
          } else {
            this.scenicOptions = [];
          }
        });
      } else {
        this.scenicOptions = [];
      }
      // 获取对应的负责人列表
      if (form.employeesId) {
        getList().then((res) => {
          if (res) {
            this.employeeOptions = res.content.map((employee) => ({
              id: employee.id,
              name: employee.username,
            }));
          } else {
            this.employeeOptions = [];
          }
        });
      } else {
        this.employeeOptions = [];
      }
    },

    [CRUD.HOOK.beforeSubmit]() {
      // 设置brand的值与name相同
      this.form.brand = this.form.name;
      return true;
    },

    [CRUD.HOOK.beforeRefresh]() {
      // 设置分页参数
      this.crud.params.current = this.page.page;
      this.crud.params.size = this.page.size;

      // 设置查询参数
      this.crud.params.employeesId = this.query.employeesId;
      this.crud.params.areaId = this.query.areaId;
      this.crud.params.name = this.query.name;
      return true;
    },

    [CRUD.HOOK.afterRefresh]() {
      // 更新分页数据
      const response = this.crud.data;

      if (response) {
        // 确保有total字段
        if (response.total !== undefined) {
          this.page.total = Number(response.total);
        }
        // 确保records数组存在且是数组类型
        if (response && Array.isArray(response)) {
          // 创建一个Promise数组来存储所有的详情请求
          const detailPromises = response.map(item => {
            if (!item || !item.id) return Promise.resolve(null);
            const stringId = item.id.toString();
            return crudAircraft.getDeviceDetail(stringId).then(res => {
              if (!res) return null;
              return {
                ...item,
                ...res,
                id: stringId
              };
            });
          });

          // 等待所有详情请求完成后再更新数据
          Promise.all(detailPromises).then(detailedData => {
            // 过滤掉空值并确保每个项都有一个有效的字符串id
            this.crud.data = detailedData.filter(item => item && item.id && typeof item.id === 'string');
          }).catch(error => {
            console.error('获取设备详情失败:', error);
            this.$message.error('获取设备详情失败');
          });
        } else {
          // 如果没有records字段或不是数组,设置为空数组避免报错
          this.crud.data = [];
        }
      } else {
        // 如果响应为空,也设置为空数组
        this.crud.data = [];
        this.page.total = 0;
      }
    },

    handleView(row) {
      const tempRow = { areaName: row.areaName, scenicName: row.scenicName, username: row.username };
      this.$router.push({
        path: "/system/aircraftDetail/index",
        query: {
          id: row.id,
          data: JSON.stringify(tempRow)
        },
      });
    },

    // 预览图片
    handlePictureCardPreview(url) {
      this.dialogImageUrl = url;
      this.dialogVisible = true;
    },

    // 删除图片
    handleRemoveImage(index) {
      this.form.deviceImages.splice(index, 1);
    },

    // 触发图片上传
    handleChange(file, uploadFiles) {
      if (file.raw.type.includes("image")) {
        this.loading = true;
        try {
          upload(this.imagesUploadApi, file.raw).then((res) => {
            if (res.status === 200) {
              const data = res.data;
              // 构造deviceImages对象
              const deviceImage = {
                fileFullPath: data.fileFullPath,
                fileSize: file.raw.size,
                fileType: file.raw.type.split("/")[1],
                newFileName: data.newFileName,
                sourceFileName: file.raw.name,
              };
              // 将新图像添加到现有数组
              if (!this.form.deviceImages) {
                this.form.deviceImages = [];
              }
              this.form.deviceImages.push(deviceImage);
              this.$message.success("图片上传成功！");
              this.loading = false;
            } else {
              this.$message.error("图片上传失败！");
              this.loading = false;
              return;
            }
          });
        } catch (error) {
          this.loading = false;
          this.$message.error("图片上传失败！");
        }
      } else {
        this.$confirm("图片的格式不正确，请重新选择！", "提示", {
          confirmButtonText: "确定",
          type: "warning",
        });
        uploadFiles.pop();
      }
    },

    handleDelete(row) {
      this.$confirm(`此操作将永久删除飞行器"${row.name}"，是否继续？`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          crudAircraft.del(row.id).then(() => {
            this.$notify({
              title: "成功",
              type: "success",
              message: "删除成功!",
            });
            this.crud.refresh();
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
  },
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.upload-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-start;
}

.upload-item {
  ::v-deep .el-upload--picture-card {
    width: 110px !important;
    height: 110px !important;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
  }
}

.preview-item {
  position: relative;
  width: 110px;
  height: 110px;
  border: 1px solid #c0ccda;
  border-radius: 6px;

  .preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 6px;
  }

  .preview-actions {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    cursor: default;
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0;
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 6px;
    transition: opacity 0.3s;

    &:hover {
      opacity: 1;
    }

    .preview-action {
      color: #fff;
      font-size: 18px;
      margin: 0 7px;
      cursor: pointer;

      &:hover {
        opacity: 0.8;
      }
    }
  }
}
// .pagination-container {
//   position: fixed;
//   bottom: 0;
//   right: 0;
//   left: 200px;
//   height: 150px;
//   background: white;
//   padding: 10px;
//   text-align: left;
//   box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.08);
// }
// .el-pagination {
//   padding: 2px 25px;
// }
.app-container {
  padding-bottom: 60px;
}
::v-deep .el-input-number .el-input__inner {
  text-align: left;
}
::v-deep .vue-treeselect__control,
::v-deep .vue-treeselect__placeholder,
::v-deep .vue-treeselect__single-value {
  height: 30px;
  line-height: 30px;
}
</style>
