<template>
  <basic-container class="transport-ship-page">
    <div class="ship-toolbar">
      <div class="ship-toolbar__actions">
        <el-button
          type="primary"
          icon="el-icon-plus"
          plain
          v-if="hasPermission('transport_ship_add')"
          @click="openShip()"
        >
          新增
        </el-button>
        <el-button
          type="primary"
          icon="el-icon-download"
          plain
          v-if="hasPermission('transport_ship_export')"
          @click="handleExport"
        >
          导出
        </el-button>
        <el-button
          type="danger"
          icon="el-icon-delete"
          plain
          v-if="hasPermission('transport_ship_delete')"
          @click="handleDelete"
        >
          批量删除
        </el-button>
      </div>
      <el-radio-group v-model="query.expireStatus" class="ship-stat" @change="handleExpireChange">
        <el-radio-button label="">全部（{{ expiryStat.total }}）</el-radio-button>
        <el-radio-button label="within30">30天内到期（{{ expiryStat.within30 }}）</el-radio-button>
        <el-radio-button label="expired">已到期（{{ expiryStat.expired }}）</el-radio-button>
      </el-radio-group>
    </div>

    <avue-crud
      :option="option"
      :table-loading="loading"
      :data="data"
      v-model:page="page"
      v-model="form"
      ref="crud"
      :permission="permissionList"
      @search-change="searchChange"
      @search-reset="searchReset"
      @selection-change="selectionChange"
      @current-change="currentChange"
      @size-change="sizeChange"
      @refresh-change="refreshChange"
      @on-load="onLoad"
    >
      <template #shipName="{ row }">
        <el-button type="primary" link @click="openShip(row, true)">
          {{ row.shipName }}
        </el-button>
      </template>
      <template #status="{ row }">
        <el-tag :type="row.status === 1 ? 'primary' : 'info'">
          {{ row.status === 1 ? '启用' : '停用' }}
        </el-tag>
      </template>
      <template #nationalityCertEndDate="{ row }">
        <span :class="getDateClass(row, 'nationalityCertEndDate', 'nationalityCertLongTerm')">
          {{ formatEndDate(row.nationalityCertEndDate, row.nationalityCertLongTerm) }}
        </span>
      </template>
      <template #safeManningCertEndDate="{ row }">
        <span :class="getDateClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')">
          {{ formatEndDate(row.safeManningCertEndDate, row.safeManningCertLongTerm) }}
        </span>
      </template>
      <template #businessTransportCertEndDate="{ row }">
        <span
          :class="
            getDateClass(row, 'businessTransportCertEndDate', 'businessTransportCertLongTerm')
          "
        >
          {{ formatEndDate(row.businessTransportCertEndDate, row.businessTransportCertLongTerm) }}
        </span>
      </template>
      <template #leaseEndDate="{ row }">
        <span :class="getDateClass(row, 'leaseEndDate', 'leaseLongTerm')">
          {{ formatEndDate(row.leaseEndDate, row.leaseLongTerm) }}
        </span>
      </template>
      <template #menu="{ row }">
        <el-button
          type="primary"
          text
          icon="el-icon-edit"
          v-if="hasPermission('transport_ship_edit')"
          @click="openShip(row)"
        >
          修改
        </el-button>
        <el-button
          type="primary"
          text
          icon="el-icon-view"
          v-if="hasPermission('transport_ship_view')"
          @click="openShip(row, true)"
        >
          综合台账
        </el-button>
        <el-button
          type="primary"
          text
          :icon="row.status === 1 ? 'el-icon-close' : 'el-icon-check'"
          v-if="hasPermission('transport_ship_status')"
          @click="handleStatus(row)"
        >
          {{ row.status === 1 ? '停用' : '启用' }}
        </el-button>
      </template>
    </avue-crud>

    <el-dialog
      :title="dialogTitle"
      append-to-body
      v-model="shipBox"
      width="92%"
      top="4vh"
      @closed="resetShip"
    >
      <el-form
        ref="shipForm"
        :model="shipForm"
        :rules="formRules"
        label-position="right"
        :disabled="readonly"
        class="ship-form"
      >
        <div class="section-title">基础船舶信息</div>
        <el-row :gutter="18">
          <el-col :span="6">
            <el-form-item label="船舶名" prop="shipName">
              <el-input v-model="shipForm.shipName" maxlength="50" show-word-limit />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="船舶识别号" prop="shipIdentifierNo">
              <el-input
                v-model="shipForm.shipIdentifierNo"
                maxlength="50"
                show-word-limit
                @input="
                  shipForm.shipIdentifierNo = String(shipForm.shipIdentifierNo || '').toUpperCase()
                "
              />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="所属组织" prop="organizationName">
              <el-input v-model="shipForm.organizationName" maxlength="50" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="船检登记号" prop="shipInspectionNo">
              <el-input v-model="shipForm.shipInspectionNo" maxlength="50" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="船舶类型" prop="shipType">
              <el-select v-model="shipForm.shipType" filterable allow-create default-first-option>
                <el-option
                  v-for="item in shipTypeOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="状态" prop="status">
              <el-select v-model="shipForm.status">
                <el-option label="启用" :value="1" />
                <el-option label="停用" :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="shipForm.remark" type="textarea" maxlength="200" show-word-limit />
            </el-form-item>
          </el-col>
        </el-row>

        <div class="section-title">国籍证信息</div>
        <el-row :gutter="18">
          <el-col :span="8">
            <el-form-item label="国籍证有效期至" prop="nationalityCertEndDate">
              <el-date-picker
                v-model="shipForm.nationalityCertEndDate"
                type="date"
                value-format="YYYY-MM-DD"
                :disabled="shipForm.nationalityCertLongTerm === 1"
              />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="长期有效" prop="nationalityCertLongTerm">
              <el-checkbox
                v-model="shipForm.nationalityCertLongTerm"
                :true-label="1"
                :false-label="0"
                >是</el-checkbox
              >
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <image-upload-field
              label="国籍证图片"
              prop="nationalityCertImage"
              :value="shipForm.nationalityCertImage"
              :readonly="readonly"
              :headers="uploadHeaders"
              large
              @success="url => setImage('nationalityCertImage', url)"
            />
          </el-col>
        </el-row>

        <div class="section-title">安全配员证信息</div>
        <el-row :gutter="18">
          <el-col :span="8">
            <el-form-item label="最低安全配员证书有效期至" prop="safeManningCertEndDate">
              <el-date-picker
                v-model="shipForm.safeManningCertEndDate"
                type="date"
                value-format="YYYY-MM-DD"
                :disabled="shipForm.safeManningCertLongTerm === 1"
              />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="长期有效" prop="safeManningCertLongTerm">
              <el-checkbox
                v-model="shipForm.safeManningCertLongTerm"
                :true-label="1"
                :false-label="0"
                >是</el-checkbox
              >
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <image-upload-field
              label="最低安全配员证书图片"
              prop="safeManningCertImage"
              :value="shipForm.safeManningCertImage"
              :readonly="readonly"
              :headers="uploadHeaders"
              large
              @success="url => setImage('safeManningCertImage', url)"
            />
          </el-col>
        </el-row>

        <div class="section-title">营业运输证信息</div>
        <el-row :gutter="18">
          <el-col :span="8">
            <el-form-item label="营业运输证有效期至" prop="businessTransportCertEndDate">
              <el-date-picker
                v-model="shipForm.businessTransportCertEndDate"
                type="date"
                value-format="YYYY-MM-DD"
                :disabled="shipForm.businessTransportCertLongTerm === 1"
              />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="长期有效" prop="businessTransportCertLongTerm">
              <el-checkbox
                v-model="shipForm.businessTransportCertLongTerm"
                :true-label="1"
                :false-label="0"
                >是</el-checkbox
              >
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <image-upload-field
              label="营业运输证图片"
              prop="businessTransportCertImage"
              :value="shipForm.businessTransportCertImage"
              :readonly="readonly"
              :headers="uploadHeaders"
              large
              @success="url => setImage('businessTransportCertImage', url)"
            />
          </el-col>
        </el-row>

        <div class="section-title">承租信息</div>
        <el-row :gutter="18">
          <el-col :span="8">
            <el-form-item label="承租有效期至" prop="leaseEndDate">
              <el-date-picker
                v-model="shipForm.leaseEndDate"
                type="date"
                value-format="YYYY-MM-DD"
                :disabled="shipForm.leaseLongTerm === 1"
              />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="长期有效" prop="leaseLongTerm">
              <el-checkbox v-model="shipForm.leaseLongTerm" :true-label="1" :false-label="0"
                >是</el-checkbox
              >
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <image-upload-field
              label="承租合同图片"
              prop="leaseContractImage"
              :value="shipForm.leaseContractImage"
              :readonly="readonly"
              :headers="uploadHeaders"
              large
              @success="url => setImage('leaseContractImage', url)"
            />
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="shipBox = false">取消</el-button>
        <el-button type="primary" v-if="!readonly" :loading="submitLoading" @click="handleSubmit"
          >确定</el-button
        >
      </template>
    </el-dialog>
  </basic-container>
</template>

<script>
import { mapGetters } from 'vuex';
import NProgress from 'nprogress';
import { option } from '@/option/transportCapacity/transport-ship';
import {
  getList,
  getDetail,
  submit,
  remove,
  changeStatus,
  getExpiryStat,
} from '@/api/transportCapacity/transport-ship';
import { exportBlob } from '@/api/common';
import { getToken } from '@/utils/auth';
import { downloadXls } from '@/utils/util';

const emptyForm = () => ({
  id: '',
  shipName: '',
  shipIdentifierNo: '',
  organizationName: '',
  shipInspectionNo: '',
  shipType: '',
  nationalityCertEndDate: '',
  nationalityCertLongTerm: 0,
  nationalityCertImage: '',
  safeManningCertEndDate: '',
  safeManningCertLongTerm: 0,
  safeManningCertImage: '',
  businessTransportCertEndDate: '',
  businessTransportCertLongTerm: 0,
  businessTransportCertImage: '',
  leaseEndDate: '',
  leaseLongTerm: 0,
  leaseContractImage: '',
  remark: '',
  status: 1,
});

const imageUploadField = {
  name: 'ImageUploadField',
  props: {
    label: String,
    prop: String,
    value: String,
    readonly: Boolean,
    headers: Object,
    large: Boolean,
  },
  emits: ['success'],
  methods: {
    handleSuccess(res) {
      if (res.code === 200 && res.data) {
        this.$emit('success', res.data.link || res.data.url || res.data.domain || '');
      } else {
        this.$message.error(res.msg || '上传失败');
      }
    },
    beforeUpload(file) {
      const validType = ['image/jpeg', 'image/png', 'image/jpg', 'image/bmp'].includes(file.type);
      const validSize = file.size / 1024 / 1024 < 5;
      if (!validType) this.$message.error('仅支持 JPG、PNG、BMP 图片');
      if (!validSize) this.$message.error('图片大小不能超过 5MB');
      return validType && validSize;
    },
  },
  template: `
    <el-form-item :label="label" :prop="prop">
      <el-upload
        class="ship-uploader"
        :class="{ 'ship-uploader--large': large }"
        action="/api/blade-resource/oss/endpoint/put-file"
        name="file"
        :headers="headers"
        :show-file-list="false"
        :disabled="readonly"
        :before-upload="beforeUpload"
        :on-success="handleSuccess"
      >
        <img v-if="value" :src="value" class="ship-uploader__image" />
        <div v-else class="ship-uploader__empty">上传证件图片</div>
      </el-upload>
    </el-form-item>
  `,
};

export default {
  components: { ImageUploadField: imageUploadField },
  data() {
    return {
      option,
      form: {},
      query: { expireStatus: '' },
      searchForm: {},
      loading: true,
      submitLoading: false,
      data: [],
      ids: '',
      selectionList: [],
      page: { pageSize: 10, currentPage: 1, total: 0 },
      expiryStat: { total: 0, within30: 0, expired: 0 },
      shipBox: false,
      readonly: false,
      shipForm: emptyForm(),
      uploadHeaders: {
        'Blade-Auth': `bearer ${getToken()}`,
        'Blade-Requested-With': 'BladeHttpRequest',
      },
      shipTypeOptions: ['干货船', '集装箱船', '散货船', '油船', '拖轮', '驳船'],
      formRules: {
        shipName: [{ required: true, message: '请输入船舶名', trigger: 'blur' }],
        shipIdentifierNo: [{ required: true, message: '请输入船舶识别号', trigger: 'blur' }],
        organizationName: [{ required: true, message: '请输入所属组织', trigger: 'blur' }],
        shipType: [{ required: true, message: '请选择船舶类型', trigger: 'change' }],
        nationalityCertEndDate: [
          { validator: this.validateNationalityCertEndDate, trigger: 'change' },
        ],
        safeManningCertEndDate: [
          { validator: this.validateSafeManningCertEndDate, trigger: 'change' },
        ],
        businessTransportCertEndDate: [
          { validator: this.validateBusinessTransportCertEndDate, trigger: 'change' },
        ],
        remark: [{ max: 200, message: '备注最多200字', trigger: 'blur' }],
      },
    };
  },
  computed: {
    ...mapGetters(['permission', 'userInfo']),
    isAdmin() {
      const authority = this.userInfo.authority || '';
      return authority.includes('admin');
    },
    permissionList() {
      return {
        addBtn: this.hasPermission('transport_ship_add'),
        viewBtn: this.hasPermission('transport_ship_view'),
        delBtn: this.hasPermission('transport_ship_delete'),
        editBtn: this.hasPermission('transport_ship_edit'),
      };
    },
    dialogTitle() {
      if (this.readonly) return '船舶综合台账';
      return this.shipForm.id ? '修改船舶' : '新增船舶';
    },
  },
  methods: {
    hasPermission(code) {
      return this.isAdmin || this.permission?.[code] === true;
    },
    validateNationalityCertEndDate(rule, value, callback) {
      if (this.shipForm.nationalityCertLongTerm !== 1 && !value)
        return callback(new Error('请选择国籍证有效期至'));
      callback();
    },
    validateSafeManningCertEndDate(rule, value, callback) {
      if (this.shipForm.safeManningCertLongTerm !== 1 && !value)
        return callback(new Error('请选择最低安全配员证书有效期至'));
      callback();
    },
    validateBusinessTransportCertEndDate(rule, value, callback) {
      if (this.shipForm.businessTransportCertLongTerm !== 1 && !value)
        return callback(new Error('请选择营业运输证有效期至'));
      callback();
    },
    openShip(row, readonly = false) {
      this.readonly = readonly;
      if (!row?.id) {
        this.shipForm = emptyForm();
        this.shipBox = true;
        return;
      }
      getDetail(row.id).then(res => {
        this.shipForm = { ...emptyForm(), ...(res.data.data || {}) };
        this.shipBox = true;
      });
    },
    resetShip() {
      this.shipForm = emptyForm();
      this.readonly = false;
      this.submitLoading = false;
      this.$refs.shipForm?.clearValidate();
    },
    setImage(prop, url) {
      this.shipForm[prop] = url;
      this.$refs.shipForm?.validateField(prop);
    },
    handleSubmit() {
      this.$refs.shipForm.validate(valid => {
        if (!valid) return;
        this.submitLoading = true;
        submit(this.shipForm)
          .then(() => {
            this.$message.success('操作成功');
            this.shipBox = false;
            this.onLoad(this.page);
          })
          .finally(() => {
            this.submitLoading = false;
          });
      });
    },
    handleStatus(row) {
      const status = row.status === 1 ? 2 : 1;
      const text = status === 1 ? '启用' : '停用';
      this.$confirm(`是否${text}该船舶?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        changeStatus(row.id, status).then(() => {
          this.$message.success('操作成功');
          this.onLoad(this.page);
        });
      });
    },
    handleDelete() {
      if (this.selectionList.length === 0) {
        this.$message.warning('请选择至少一条数据');
        return;
      }
      this.$confirm('是否删除选中的船舶数据?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        remove(this.ids).then(() => {
          this.$message.success('操作成功');
          this.onLoad(this.page);
        });
      });
    },
    handleExpireChange() {
      this.page.currentPage = 1;
      this.onLoad(this.page);
    },
    refreshStat() {
      getExpiryStat(this.buildQuery(false)).then(res => {
        this.expiryStat = {
          total: res.data.data?.total || 0,
          within30: res.data.data?.within30 || 0,
          expired: res.data.data?.expired || 0,
        };
      });
    },
    searchReset() {
      this.searchForm = {};
      this.query = { expireStatus: this.query.expireStatus };
      this.onLoad(this.page);
    },
    searchChange(params, done) {
      this.searchForm = params;
      this.page.currentPage = 1;
      this.onLoad(this.page, params);
      done();
    },
    selectionChange(list) {
      this.selectionList = list;
      this.ids = list.map(item => item.id).join(',');
    },
    selectionClear() {
      this.selectionList = [];
      this.ids = '';
      this.$refs.crud?.toggleSelection();
    },
    currentChange(currentPage) {
      this.page.currentPage = currentPage;
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    refreshChange() {
      this.onLoad(this.page, this.searchForm);
    },
    onLoad(page, params = {}) {
      this.loading = true;
      getList(page.currentPage, page.pageSize, this.buildQuery(true, params))
        .then(res => {
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          this.selectionClear();
          this.refreshStat();
        })
        .finally(() => {
          this.loading = false;
        });
    },
    buildQuery(includeExpire = true, params = {}) {
      const query = { ...params, ...this.searchForm };
      if (includeExpire && this.query.expireStatus) query.expireStatus = this.query.expireStatus;
      return query;
    },
    handleExport() {
      this.$confirm('是否导出船舶数据?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        NProgress.start();
        exportBlob(
          '/blade-transport/transport-ship/export-transport-ship',
          this.buildExportParams()
        )
          .then(res => {
            downloadXls(res.data, `船舶管理${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
          })
          .finally(() => {
            NProgress.done();
          });
      });
    },
    buildExportParams() {
      return { ...this.buildQuery(true), ids: this.ids, [this.website.tokenHeader]: getToken() };
    },
    formatEndDate(date, longTerm) {
      if (longTerm === 1) return '长期有效';
      return date || '-';
    },
    getDateClass(row, dateProp, longTermProp) {
      if (row[longTermProp] === 1 || !row[dateProp]) return '';
      const today = this.$dayjs();
      const endDate = this.$dayjs(row[dateProp]);
      if (endDate.isBefore(today, 'day')) return 'date-danger';
      if (endDate.diff(today, 'day') <= 30) return 'date-warning';
      return '';
    },
  },
};
</script>

<style lang="scss" scoped>
.transport-ship-page {
  .ship-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 12px;
  }

  .ship-toolbar__actions {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .ship-stat {
    flex-shrink: 0;
  }

  :deep(.el-table th .cell),
  :deep(.el-table td .cell) {
    white-space: nowrap;
  }
}

.ship-form {
  .section-title {
    margin: 18px 0 14px;
    padding-left: 10px;
    border-left: 3px solid #e74b5f;
    color: #303133;
    font-weight: 600;
    line-height: 18px;
  }

  .section-title:first-child {
    margin-top: 0;
  }

  :deep(.el-date-editor.el-input),
  :deep(.el-date-editor.el-input__wrapper),
  :deep(.el-select),
  :deep(.el-input) {
    width: 100%;
  }
}

:deep(.ship-uploader .el-upload) {
  width: 100%;
  height: 170px;
  border: 1px dashed #c0c4cc;
  background: #fafafa;
  overflow: hidden;
}

:deep(.ship-uploader--large .el-upload) {
  height: 260px;
}

:deep(.ship-uploader__image) {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

:deep(.ship-uploader__empty) {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #606266;
}

.date-warning {
  color: #f56c6c;
  font-weight: 600;
}

.date-danger {
  color: #d40000;
  font-weight: 600;
}

@media (max-width: 1200px) {
  .transport-ship-page {
    .ship-toolbar {
      align-items: flex-start;
      flex-direction: column;
    }
  }
}
</style>
