<template>
  <basic-container class="transport-ship-page">
    <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 #menu-left>
        <el-button
          type="primary"
          icon="el-icon-plus"
          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>
      </template>
      <template #expireStatus-search>
        <div class="transport-ship-page__expiry-tags">
          <el-check-tag
            v-for="item in expiryTagOptions"
            :key="item.value"
            :checked="query.expireStatus === item.value"
            @change="handleExpireChange(item.value)"
          >
            {{ item.label }}（{{ expiryStat[item.statKey] || 0 }}）
          </el-check-tag>
        </div>
      </template>
      <template #shipName="{ row }">
        <el-button type="primary" link @click="openShip(row, true)">
          {{ row.shipName }}
        </el-button>
      </template>
      <template #organizationName="{ row }">
        {{ String(row.organizationName || '').replace(/^[\s\u3000]+/, '') }}
      </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="
            getCertificateExpiryClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')
          "
        >
          {{ formatEndDate(row.safeManningCertEndDate, row.safeManningCertLongTerm) }}
        </span>
      </template>
      <template #businessTransportCertEndDate="{ row }">
        <span
          :class="
            getCertificateExpiryClass(
              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-link type="primary" v-if="hasPermission('transport_ship_edit')" @click="openShip(row)">
          修改
        </el-link>
        <el-link
          type="primary"
          v-if="hasPermission('transport_ship_view')"
          @click="openShipLedger(row)"
        >
          综合台账
        </el-link>
        <el-link
          type="primary"
          v-if="hasPermission('transport_ship_status')"
          @click="handleStatus(row)"
        >
          {{ row.status === 1 ? '停用' : '启用' }}
        </el-link>
      </template>
    </avue-crud>

    <ship-ledger v-model="shipLedgerBox" :ship="ledgerShip" />

    <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"
        label-width="auto"
        :disabled="readonly"
        class="ship-form"
      >
        <section-card title="基础船舶信息">
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="船舶所属组织" prop="organizationName">
                <el-select
                  v-model="shipForm.organizationName"
                  filterable
                  clearable
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in organizationOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="船名" prop="shipName">
                <el-input v-model="shipForm.shipName" maxlength="20" show-word-limit />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="安放龙骨日期/建造完工日期" prop="keelLayingDate">
                <div class="date-range-inline">
                  <el-date-picker
                    v-model="shipForm.keelLayingDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    @change="validateField('keelLayingDate')"
                  />
                  <span>至</span>
                  <el-date-picker
                    v-model="shipForm.buildCompletionDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    @change="validateField('keelLayingDate')"
                  />
                </div>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="总长" prop="totalLength">
                <el-input
                  v-model="shipForm.totalLength"
                  @input="normalizeNonNegativeDecimal('totalLength')"
                >
                  <template #suffix>m</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="船宽" prop="shipWidth">
                <el-input
                  v-model="shipForm.shipWidth"
                  @input="normalizeNonNegativeDecimal('shipWidth')"
                >
                  <template #suffix>m</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="型深" prop="moldedDepth">
                <el-input
                  v-model="shipForm.moldedDepth"
                  @input="normalizeNonNegativeDecimal('moldedDepth')"
                >
                  <template #suffix>m</template>
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="最大船高" prop="maxShipHeight">
                <el-input
                  v-model="shipForm.maxShipHeight"
                  @input="normalizeNonNegativeDecimal('maxShipHeight')"
                >
                  <template #suffix>m</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="空载吃水" prop="lightDraft">
                <el-input
                  v-model="shipForm.lightDraft"
                  @input="normalizeNonNegativeDecimal('lightDraft')"
                >
                  <template #suffix>t</template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="满载吃水" prop="fullLoadDraft">
                <el-input
                  v-model="shipForm.fullLoadDraft"
                  @input="normalizeNonNegativeDecimal('fullLoadDraft')"
                >
                  <template #suffix>t</template>
                </el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="航区" prop="navigationArea">
                <div class="navigation-area-field">
                  <el-select v-model="shipForm.navigationArea" placeholder="请选择">
                    <el-option label="A级" value="A级" />
                    <el-option label="B级" value="B级" />
                  </el-select>
                  <el-tooltip effect="light" placement="top" popper-class="ship-navigation-tooltip">
                    <template #content>
                      <table class="navigation-cargo-table">
                        <tbody>
                          <tr>
                            <th rowspan="2">参考<br />载货量</th>
                            <th>航区</th>
                            <th>A级</th>
                            <th>B级</th>
                            <th>FA</th>
                            <th>FB</th>
                          </tr>
                          <tr>
                            <th>载货量(t)</th>
                            <td>864.00</td>
                            <td>864.00</td>
                            <td>965.00</td>
                            <td>1015.00</td>
                          </tr>
                        </tbody>
                      </table>
                    </template>
                    <el-icon class="navigation-info-icon"><InfoFilled /></el-icon>
                  </el-tooltip>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
        </section-card>

        <section-card title="船舶证书信息">
          <div class="cert-block">
            <div class="cert-block__title">船舶所有权证书</div>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="登记号码" prop="ownershipRegistrationNo">
                  <el-input v-model="shipForm.ownershipRegistrationNo" maxlength="50" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="初次登记号码" prop="initialRegistrationNo">
                  <el-input v-model="shipForm.initialRegistrationNo" maxlength="50" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="船舶所有人" prop="shipOwner">
                  <el-input v-model="shipForm.shipOwner" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="取得所有权日期" prop="ownershipAcquisitionDate">
                  <el-date-picker
                    v-model="shipForm.ownershipAcquisitionDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="船舶识别号" prop="shipIdentifierNo">
                  <el-input
                    v-model="shipForm.shipIdentifierNo"
                    maxlength="50"
                    @input="
                      shipForm.shipIdentifierNo = String(
                        shipForm.shipIdentifierNo || ''
                      ).toUpperCase()
                    "
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="cert-block">
            <div class="cert-block__title">内河船舶安全与环保证书</div>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="总吨" prop="grossTonnage">
                  <el-input-number
                    v-model="shipForm.grossTonnage"
                    :min="0"
                    :precision="2"
                    :controls="false"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="净吨" prop="netTonnage">
                  <el-input-number
                    v-model="shipForm.netTonnage"
                    :min="0"
                    :precision="2"
                    :controls="false"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="船检登记号" prop="shipInspectionNo">
                  <el-input v-model="shipForm.shipInspectionNo" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="船舶类型" prop="shipType">
                  <el-select v-model="shipForm.shipType" placeholder="请选择船舶类型" clearable>
                    <el-option label="散货船" value="散货船" />
                    <el-option label="集装箱船" value="集装箱船" />
                    <el-option label="杂货船" value="杂货船" />
                    <el-option label="油船" value="油船" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="cert-block">
            <div class="cert-block__title">船舶国籍证书</div>
            <el-row :gutter="18">
              <el-col :span="16">
                <el-form-item label="证书有效期自" prop="nationalityCertStartDate">
                  <div class="date-range-inline">
                    <el-date-picker
                      v-model="shipForm.nationalityCertStartDate"
                      type="date"
                      value-format="YYYY-MM-DD"
                    />
                    <span>至</span>
                    <el-date-picker
                      v-model="shipForm.nationalityCertEndDate"
                      type="date"
                      value-format="YYYY-MM-DD"
                      @change="validateField('nationalityCertStartDate')"
                    />
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="cert-block">
            <div class="cert-block__title">内河船舶最低安全配员证书</div>
            <el-row :gutter="18">
              <el-col :span="16">
                <el-form-item label="证书有效期自" prop="safeManningCertStartDate">
                  <div class="date-range-inline">
                    <el-date-picker
                      v-model="shipForm.safeManningCertStartDate"
                      type="date"
                      value-format="YYYY-MM-DD"
                    />
                    <span>至</span>
                    <el-date-picker
                      v-model="shipForm.safeManningCertEndDate"
                      type="date"
                      value-format="YYYY-MM-DD"
                      @change="validateField('safeManningCertStartDate')"
                    />
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="cert-block">
            <div class="cert-block__title">光船租赁登记证明书</div>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="起租日期" prop="leaseStartDate">
                  <el-date-picker
                    v-model="shipForm.leaseStartDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="终止日期" prop="leaseEndDate">
                  <el-date-picker
                    v-model="shipForm.leaseEndDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    @change="validateField('leaseStartDate')"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="船舶承租人" prop="shipLessee">
                  <el-input v-model="shipForm.shipLessee" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="cert-block">
            <div class="cert-block__title">船舶营业运输证书</div>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="证书编号" prop="businessTransportCertNo">
                  <el-input v-model="shipForm.businessTransportCertNo" maxlength="50" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="发证日期" prop="businessTransportCertIssueDate">
                  <el-date-picker
                    v-model="shipForm.businessTransportCertIssueDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="有效期至" prop="businessTransportCertEndDate">
                  <el-date-picker
                    v-model="shipForm.businessTransportCertEndDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="18">
              <el-col :span="8">
                <el-form-item label="船舶经营人" prop="shipOperator">
                  <el-input v-model="shipForm.shipOperator" maxlength="50" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <el-row class="cert-upload-grid" :gutter="18">
            <el-col :span="8">
              <image-upload-field
                label="船舶所有权证书"
                prop="ownershipCertImage"
                :value="shipForm.ownershipCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('ownershipCertImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="内河船舶安全与环保证书"
                prop="safetyCertImage"
                :value="shipForm.safetyCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('safetyCertImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="船舶国籍证书"
                prop="nationalityCertImage"
                :value="shipForm.nationalityCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('nationalityCertImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="内河船舶最低安全配员证书"
                prop="safeManningCertImage"
                :value="shipForm.safeManningCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('safeManningCertImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <div class="cert-upload-spacer"></div>
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="光船租赁登记证书"
                prop="leaseContractImage"
                :value="shipForm.leaseContractImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('leaseContractImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="船舶营业运输证"
                prop="businessTransportCertImage"
                :value="shipForm.businessTransportCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="ship"
                @success="url => setImage('businessTransportCertImage', url)"
              />
            </el-col>
          </el-row>
        </section-card>
      </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 { InfoFilled } from '@element-plus/icons-vue';
import { option } from '@/option/transportCapacity/transport-ship';
import { getDeptTree } from '@/api/system/dept';
import {
  getList,
  getDetail,
  submit,
  remove,
  changeStatus,
  getExpiryStat,
} from '@/api/transportCapacity/transport-ship';
import { exportBlob } from '@/api/common';
import { getToken } from '@/utils/auth';
import { getUploadHeaders } from '@/utils/upload';
import { downloadXls } from '@/utils/util';
import ImageUploadField from '@/components/image-upload-field/main.vue';
import ShipLedger from './components/ship-ledger.vue';

const emptyForm = () => ({
  id: '',
  organizationName: '',
  shipName: '',
  shipIdentifierNo: '',
  keelLayingDate: '',
  buildCompletionDate: '',
  totalLength: undefined,
  shipWidth: undefined,
  moldedDepth: undefined,
  maxShipHeight: undefined,
  lightDraft: undefined,
  fullLoadDraft: undefined,
  navigationArea: 'A级',
  ownershipRegistrationNo: '',
  initialRegistrationNo: '',
  shipOwner: '',
  ownershipAcquisitionDate: '',
  shipInspectionNo: '',
  shipType: '',
  grossTonnage: undefined,
  netTonnage: undefined,
  nationalityCertStartDate: '',
  nationalityCertEndDate: '',
  nationalityCertLongTerm: 0,
  nationalityCertImage: '',
  ownershipCertImage: '',
  safetyCertImage: '',
  safeManningCertStartDate: '',
  safeManningCertEndDate: '',
  safeManningCertLongTerm: 0,
  safeManningCertImage: '',
  leaseStartDate: '',
  shipLessee: '',
  businessTransportCertEndDate: '',
  businessTransportCertLongTerm: 0,
  businessTransportCertImage: '',
  businessTransportCertNo: '',
  businessTransportCertIssueDate: '',
  shipOperator: '',
  leaseEndDate: '',
  leaseLongTerm: 0,
  leaseContractImage: '',
  remark: '',
  status: 1,
});

export default {
  components: { ImageUploadField, InfoFilled, ShipLedger },
  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,
      shipLedgerBox: false,
      ledgerShip: {},
      readonly: false,
      shipForm: emptyForm(),
      uploadHeaders: getUploadHeaders(),
      organizationOptions: [],
      formRules: {
        organizationName: [{ required: true, message: '请选择船舶所属组织', trigger: 'change' }],
        shipName: [
          { required: true, message: '请输入船名', trigger: 'blur' },
          { max: 20, message: '船名不能超过20个字符', trigger: 'blur' },
        ],
        keelLayingDate: [{ validator: this.validateKeelCompletionDate, trigger: 'change' }],
        shipIdentifierNo: [{ required: true, message: '请输入船舶识别号', trigger: 'blur' }],
        totalLength: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        shipWidth: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        moldedDepth: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        maxShipHeight: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        lightDraft: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        fullLoadDraft: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
        navigationArea: [{ required: true, message: '请选择航区', trigger: 'change' }],
        ownershipRegistrationNo: [{ required: true, message: '请输入登记号码', trigger: 'blur' }],
        initialRegistrationNo: [{ required: true, message: '请输入初次登记号码', trigger: 'blur' }],
        shipOwner: [{ max: 50, message: '船舶所有人不能超过50字', trigger: 'blur' }],
        grossTonnage: [{ required: true, message: '请输入总吨', trigger: 'change' }],
        netTonnage: [{ required: true, message: '请输入净吨', trigger: 'change' }],
        shipInspectionNo: [{ required: true, message: '请输入船检登记号', trigger: 'blur' }],
        shipType: [{ required: true, message: '请选择船舶类型', trigger: 'change' }],
        nationalityCertStartDate: [
          { validator: this.validateNationalityCertDate, trigger: 'change' },
        ],
        safeManningCertStartDate: [
          { validator: this.validateSafeManningCertDate, trigger: 'change' },
        ],
        leaseStartDate: [{ validator: this.validateLeaseDate, trigger: 'change' }],
        businessTransportCertNo: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
        businessTransportCertIssueDate: [
          { required: true, message: '请选择发证日期', trigger: 'change' },
          { validator: this.validateBusinessTransportCertDate, trigger: 'change' },
        ],
        businessTransportCertEndDate: [
          { required: true, message: '请选择有效期至', trigger: 'change' },
          { validator: this.validateBusinessTransportCertDate, trigger: 'change' },
        ],
        shipLessee: [{ max: 50, message: '船舶承租人不能超过50字', trigger: 'blur' }],
        shipOperator: [{ max: 50, message: '船舶经营人不能超过50字', trigger: 'blur' }],
        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 ? '修改船舶' : '新增船舶';
    },
    expiryTagOptions() {
      return [
        { label: '全部', value: '', statKey: 'total' },
        { label: '30天内到期', value: 'within30', statKey: 'within30' },
        { label: '已到期', value: 'expired', statKey: 'expired' },
      ];
    },
  },
  created() {
    this.initDeptTree();
  },
  methods: {
    hasPermission(code) {
      return this.isAdmin || this.permission?.[code] === true;
    },
    initDeptTree() {
      getDeptTree(this.userInfo.tenantId).then(res => {
        this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
        const column = this.findColumn(this.option.column, 'organizationName');
        column.dicData = this.organizationOptions;
        if (this.shipBox && !this.shipForm.id && !this.shipForm.organizationName) {
          this.shipForm.organizationName = this.getCurrentOrganizationName();
        }
      });
    },
    flattenDeptOptions(tree = [], level = 0) {
      const result = [];
      tree.forEach(item => {
        const rawLabel = item.title || item.deptName || item.name;
        result.push({
          label: `${'　'.repeat(level)}${rawLabel}`,
          value: rawLabel,
          rawLabel,
          id: item.id || item.value,
        });
        if (item.children && item.children.length) {
          result.push(...this.flattenDeptOptions(item.children, level + 1));
        }
      });
      return result;
    },
    getCurrentOrganizationName() {
      const currentDeptId = this.userInfo.deptId || this.userInfo.dept_id;
      const currentDept = this.organizationOptions.find(
        item => String(item.id) === String(currentDeptId)
      );
      return currentDept?.rawLabel || this.userInfo.deptName || this.userInfo.dept_name || '';
    },
    validateField(prop) {
      this.$refs.shipForm?.validateField(prop);
    },
    normalizeNonNegativeDecimal(prop) {
      const value = String(this.shipForm[prop] ?? '').replace(/[^\d.]/g, '');
      const [integerPart = '', ...decimalParts] = value.split('.');
      const decimalPart = decimalParts.join('').slice(0, 2);
      this.shipForm[prop] = decimalParts.length ? `${integerPart}.${decimalPart}` : integerPart;
    },
    validateNonNegativeField(rule, value, callback) {
      if (value !== undefined && value !== null && value < 0) {
        callback(new Error('数值不能小于0'));
        return;
      }
      callback();
    },
    validateKeelCompletionDate(rule, value, callback) {
      if (
        this.shipForm.keelLayingDate &&
        this.shipForm.buildCompletionDate &&
        this.$dayjs(this.shipForm.buildCompletionDate).isBefore(this.shipForm.keelLayingDate, 'day')
      ) {
        callback(new Error('建造完工日期不能早于安放龙骨日期'));
        return;
      }
      callback();
    },
    validateNationalityCertDate(rule, value, callback) {
      this.validateDateRangeByProp(
        'nationalityCertStartDate',
        'nationalityCertEndDate',
        'nationalityCertLongTerm',
        '请选择船舶国籍证书有效期',
        callback
      );
    },
    validateSafeManningCertDate(rule, value, callback) {
      this.validateDateRangeByProp(
        'safeManningCertStartDate',
        'safeManningCertEndDate',
        'safeManningCertLongTerm',
        '请选择最低安全配员证书有效期',
        callback
      );
    },
    validateLeaseDate(rule, value, callback) {
      this.validateOptionalDateRange(
        'leaseStartDate',
        'leaseEndDate',
        '终止日期不能早于起租日期',
        callback
      );
    },
    validateBusinessTransportCertDate(rule, value, callback) {
      this.validateOptionalDateRange(
        'businessTransportCertIssueDate',
        'businessTransportCertEndDate',
        '有效期至不能早于发证日期',
        callback
      );
    },
    validateDateRangeByProp(startProp, endProp, longTermProp, emptyMessage, callback) {
      if (
        this.shipForm[longTermProp] === 1 &&
        !this.shipForm[startProp] &&
        !this.shipForm[endProp]
      ) {
        callback();
        return;
      }
      if (!this.shipForm[startProp] || !this.shipForm[endProp]) {
        callback(new Error(emptyMessage));
        return;
      }
      this.validateOptionalDateRange(startProp, endProp, '结束日期不能早于开始日期', callback);
    },
    validateOptionalDateRange(startProp, endProp, message, callback) {
      if (
        this.shipForm[startProp] &&
        this.shipForm[endProp] &&
        this.$dayjs(this.shipForm[endProp]).isBefore(this.shipForm[startProp], 'day')
      ) {
        callback(new Error(message));
        return;
      }
      callback();
    },
    openShip(row, readonly = false) {
      this.readonly = readonly;
      if (!row?.id) {
        this.shipForm = emptyForm();
        this.shipForm.organizationName = this.getCurrentOrganizationName();
        this.shipBox = true;
        return;
      }
      getDetail(row.id).then(res => {
        this.shipForm = { ...emptyForm(), ...(res.data.data || {}) };
        this.shipBox = true;
      });
    },
    openShipLedger(row) {
      this.ledgerShip = { ...row };
      this.shipLedgerBox = 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(expireStatus) {
      this.query.expireStatus = expireStatus;
      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(),
          { feedback: true }
        )
          .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 '';
    },
    getCertificateExpiryClass(row, dateProp, longTermProp) {
      if (row[longTermProp] === 1 || !row[dateProp]) return '';
      const endDate = this.$dayjs(row[dateProp]);
      return endDate.isValid() && endDate.diff(this.$dayjs(), 'day') <= 30 ? 'date-danger' : '';
    },
  },
};
</script>

<style lang="scss" scoped>
.transport-ship-page {
  &__expiry-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    width: 100%;

    :deep(.el-check-tag) {
      margin: 0;
      white-space: nowrap;
    }
  }

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

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

.date-range-inline {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.date-range-inline :deep(.el-date-editor) {
  flex: 1;
  min-width: 0;
}

.navigation-area-field {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.navigation-area-field :deep(.el-select) {
  flex: 1;
  min-width: 0;
}

.navigation-info-icon {
  color: #909399;
  font-size: 18px;
  cursor: help;
  flex-shrink: 0;
}

.cert-block {
  padding: 16px 0 8px;
  border-top: 1px solid #e5e6eb;
}

.cert-block__title {
  margin-bottom: 12px;
  color: #303133;
  font-weight: 600;
  line-height: 20px;
}

.cert-upload-grid {
  padding-top: 8px;
}

.cert-upload-spacer {
  height: 1px;
}

.ship-upload-item {
  margin-bottom: 14px;
}

.ocr-tip {
  min-height: 114px;
  padding: 18px 20px;
  background: #ffd84d;
  color: #333;
  font-size: 16px;
  line-height: 1.45;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

// 大尺寸证件照：按身份证 1.586:1 比例缩放（约真实尺寸 75%，240×151），左对齐显示
:deep(.ship-uploader) {
  display: block;
}

:deep(.ship-uploader .el-upload),
:deep(.ship-uploader.el-upload) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 170px;
  border: 1px dashed #c0c4cc;
  background: #fafafa;
  overflow: hidden;
}

:deep(.ship-uploader--large .el-upload),
:deep(.ship-uploader--large.el-upload) {
  width: 100%;
  height: 151px;
}

:deep(.ship-uploader--large) {
  display: block;
  width: 240px;
  margin: 0;
}

: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;
}

:deep(.ship-navigation-tooltip) {
  padding: 8px 10px;
}

.navigation-cargo-table {
  border-collapse: collapse;
  font-size: 12px;
}

.navigation-cargo-table th,
.navigation-cargo-table td {
  border: 1px solid #909399;
  padding: 6px 10px;
  text-align: center;
  white-space: nowrap;
}

.navigation-cargo-table th {
  font-weight: 600;
}

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

.date-danger {
  color: #d40000;
  font-weight: 600;
}
</style>
