<template>
  <basic-container class="transport-vehicle-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_vehicle_add')"
          @click="openVehicle()"
          >新增
        </el-button>
        <el-button
          type="primary"
          icon="el-icon-download"
          plain
          v-if="hasPermission('transport_vehicle_export')"
          @click="handleExport"
          >导出
        </el-button>
        <el-button
          type="danger"
          icon="el-icon-delete"
          plain
          v-if="hasPermission('transport_vehicle_delete')"
          @click="handleDelete"
          >批量删除
        </el-button>
      </template>
      <template #expireStatus-search>
        <div class="transport-vehicle-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 #plateNo="{ row }">
        <el-button type="primary" link @click="openVehicle(row, true)">
          {{ row.plateNo }}
        </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 #boundDriver>
        <span>-</span>
      </template>
      <template #certificationStatus="{ row }">
        <el-tag :type="getCertificationStatus(row).type">
          {{ getCertificationStatus(row).label }}
        </el-tag>
      </template>
      <template #drivingLicenseEndDate="{ row }">
        <span :class="getDateClass(row, 'drivingLicenseEndDate', 'drivingLicenseLongTerm')">
          {{ formatEndDate(row.drivingLicenseEndDate, row.drivingLicenseLongTerm) }}
        </span>
      </template>
      <template #roadTransportCertEndDate="{ row }">
        <span :class="getDateClass(row, 'roadTransportCertEndDate', 'roadTransportCertLongTerm')">
          {{ formatEndDate(row.roadTransportCertEndDate, row.roadTransportCertLongTerm) }}
        </span>
      </template>
      <template #annualReviewEndDate="{ row }">
        <span :class="getDateClass(row, 'annualReviewEndDate', 'annualReviewLongTerm')">
          {{ formatEndDate(row.annualReviewEndDate, row.annualReviewLongTerm) }}
        </span>
      </template>
      <template #menu="{ row }">
        <el-link
          type="primary"
          v-if="hasPermission('transport_vehicle_view')"
          @click="openVehicle(row, true)"
        >
          查看
        </el-link>
        <el-link
          type="primary"
          v-if="hasPermission('transport_vehicle_edit')"
          @click="openVehicle(row)"
        >
          修改
        </el-link>
        <el-link type="primary" @click="openVehicleLedger(row)">综合台账</el-link>
        <el-link type="primary" v-if="row.certificationStatus === 0" @click="openCertificationAudit(row)">
          审核
        </el-link>
        <el-link
          type="primary"
          v-if="hasPermission('transport_vehicle_status')"
          @click="handleStatus(row)"
        >
          {{ row.status === 1 ? '停用' : '启用' }}
        </el-link>
      </template>
    </avue-crud>

    <vehicle-ledger v-model="vehicleLedgerBox" :vehicle="ledgerVehicle" />

    <el-dialog v-model="certificationAuditBox" title="车辆认证审核" width="92%" top="4vh">
      <el-descriptions :column="3" border>
        <el-descriptions-item v-for="item in auditDetailItems" :key="item.label" :label="item.label">
          {{ formatAuditValue(item) }}
        </el-descriptions-item>
      </el-descriptions>
      <el-form v-if="showRejectReason" class="certification-audit__reason" label-position="right" label-width="auto">
        <el-form-item label="驳回原因" required>
          <el-input v-model="certificationRejectReason" type="textarea" maxlength="200" show-word-limit />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="certificationAuditBox = false">取消</el-button>
        <el-button type="danger" @click="handleCertificationReject">认证驳回</el-button>
        <el-button type="primary" @click="handleCertificationApprove">认证通过</el-button>
      </template>
    </el-dialog>

    <el-dialog
      :title="dialogTitle"
      append-to-body
      v-model="vehicleBox"
      width="92%"
      top="4vh"
      class="vehicle-dialog"
      @closed="resetVehicle"
    >
      <el-form
        ref="vehicleForm"
        :model="vehicleForm"
        :rules="formRules"
        label-position="right"
        :disabled="readonly"
        class="vehicle-form"
      >
        <section-card title="基础车辆信息">
          <el-row :gutter="18">
            <el-col :span="24">
              <el-form-item label="所有组织" prop="organizationName">
                <el-select
                  v-model="vehicleForm.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-row>
          <el-row :gutter="18">
            <el-col :span="10">
              <el-form-item label="车牌号" prop="plateNo">
                <div class="plate-group">
                  <el-select
                    v-model="vehicleForm.plateProvince"
                    placeholder="请选择"
                    filterable
                    @change="syncPlateNo(false)"
                  >
                    <el-option
                      v-for="item in plateProvinceOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                  <el-input
                    v-model="vehicleForm.plateNoBody"
                    maxlength="7"
                    show-word-limit
                    @input="handlePlateBodyInput"
                  />
                  <el-select
                    v-model="vehicleForm.plateColor"
                    placeholder="请选择"
                    @change="syncPlateNo(false)"
                  >
                    <el-option
                      v-for="item in plateColorOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="车辆类型" prop="vehicleType">
                <el-select
                  v-model="vehicleForm.vehicleType"
                  filterable
                  allow-create
                  default-first-option
                >
                  <el-option
                    v-for="item in vehicleTypeOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="外廓尺寸(毫米)">
                <div class="dimension-group">
                  <div class="dimension-group__item">
                    <span class="dimension-group__label">长</span>
                    <el-input
                      v-model="vehicleForm.outerLength"
                      inputmode="numeric"
                      @input="vehicleForm.outerLength = digitsOnly($event)"
                    />
                  </div>
                  <div class="dimension-group__item">
                    <span class="dimension-group__label">宽</span>
                    <el-input
                      v-model="vehicleForm.outerWidth"
                      inputmode="numeric"
                      @input="vehicleForm.outerWidth = digitsOnly($event)"
                    />
                  </div>
                  <div class="dimension-group__item">
                    <span class="dimension-group__label">高</span>
                    <el-input
                      v-model="vehicleForm.outerHeight"
                      inputmode="numeric"
                      @input="vehicleForm.outerHeight = digitsOnly($event)"
                    />
                  </div>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="核定载质量(KG)" prop="approvedLoadKg">
                <el-input
                  v-model="vehicleForm.approvedLoadKg"
                  inputmode="numeric"
                  @input="vehicleForm.approvedLoadKg = digitsOnly($event)"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="准牵引总质量(KG)" prop="tractionMassKg">
                <el-input
                  v-model="vehicleForm.tractionMassKg"
                  inputmode="numeric"
                  @input="vehicleForm.tractionMassKg = digitsOnly($event)"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="业务关系" prop="businessRelation">
                <el-select v-model="vehicleForm.businessRelation">
                  <el-option
                    v-for="item in businessRelationOptions"
                    :key="item"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="能源类型" prop="energyType">
                <el-select
                  v-model="vehicleForm.energyType"
                  filterable
                  allow-create
                  default-first-option
                >
                  <el-option
                    v-for="item in energyTypeOptions"
                    :key="item"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="强制报废日期" prop="compulsoryScrapDate">
                <div class="date-with-flag">
                  <el-date-picker
                    v-model="vehicleForm.compulsoryScrapDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    :disabled="vehicleForm.compulsoryScrapLongTerm === 1"
                  />
                  <el-checkbox
                    v-model="vehicleForm.compulsoryScrapLongTerm"
                    :true-label="1"
                    :false-label="0"
                  >
                    长期有效
                  </el-checkbox>
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="海关备案号" prop="customsRecordNo">
                <el-input v-model="vehicleForm.customsRecordNo" maxlength="50" />
              </el-form-item>
            </el-col>
          </el-row>
        </section-card>

        <section-card title="车辆资质图片">
          <el-row :gutter="18">
            <el-col :span="6">
              <el-form-item label="行驶证档案编号" prop="drivingLicenseNo">
                <el-input v-model="vehicleForm.drivingLicenseNo" maxlength="50" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="行驶证有效期" prop="drivingLicenseEndDate">
                <div class="date-with-flag">
                  <el-date-picker
                    v-model="vehicleForm.drivingLicenseEndDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                  <el-checkbox
                    v-model="vehicleForm.drivingLicenseLongTerm"
                    :true-label="1"
                    :false-label="0"
                  >
                    长期有效
                  </el-checkbox>
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="10">
              <el-form-item label="道路运输证号" prop="roadTransportCertNo">
                <el-input v-model="vehicleForm.roadTransportCertNo" maxlength="50" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="道路运输证有效期" prop="roadTransportCertEndDate">
                <div class="date-with-flag">
                  <el-date-picker
                    v-model="vehicleForm.roadTransportCertEndDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                  />
                  <el-checkbox
                    v-model="vehicleForm.roadTransportCertLongTerm"
                    :true-label="1"
                    :false-label="0"
                  >
                    长期有效
                  </el-checkbox>
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="道路运输年审有效期" prop="annualReviewEndDate">
                <div class="date-with-flag">
                  <el-date-picker
                    v-model="vehicleForm.annualReviewEndDate"
                    type="date"
                    value-format="YYYY-MM-DD"
                    :disabled="vehicleForm.annualReviewLongTerm === 1"
                  />
                  <el-checkbox
                    v-model="vehicleForm.annualReviewLongTerm"
                    :true-label="1"
                    :false-label="0"
                  >
                    长期有效
                  </el-checkbox>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <el-form-item label="机动车登记编号" prop="registrationNo">
                <el-input v-model="vehicleForm.registrationNo" maxlength="50" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="机动车登记日期" prop="registrationDate">
                <el-date-picker
                  v-model="vehicleForm.registrationDate"
                  type="date"
                  value-format="YYYY-MM-DD"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <image-upload-field
                label="行驶证主页正面"
                prop="drivingLicenseImage"
                :value="vehicleForm.drivingLicenseImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="
                  (url, file) =>
                    handleVehicleCertificateUploadSuccess('drivingLicenseImage', url, file)
                "
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="行驶证主页反面"
                prop="drivingLicenseMainBack"
                :value="vehicleForm.drivingLicenseMainBack"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="
                  (url, file) =>
                    handleVehicleCertificateUploadSuccess('drivingLicenseMainBack', url, file)
                "
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="行驶证副页正面"
                prop="drivingLicenseViceFront"
                :value="vehicleForm.drivingLicenseViceFront"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="
                  (url, file) =>
                    handleVehicleCertificateUploadSuccess('drivingLicenseViceFront', url, file)
                "
              />
            </el-col>
          </el-row>
          <el-row :gutter="18">
            <el-col :span="8">
              <image-upload-field
                label="行驶证副页反面"
                prop="drivingLicenseViceBack"
                :value="vehicleForm.drivingLicenseViceBack"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="
                  (url, file) =>
                    handleVehicleCertificateUploadSuccess('drivingLicenseViceBack', url, file)
                "
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="道路运输证图片"
                prop="roadTransportCertImage"
                :value="vehicleForm.roadTransportCertImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="url => setImage('roadTransportCertImage', url)"
              />
            </el-col>
            <el-col :span="8">
              <image-upload-field
                label="机动车登记本"
                prop="registrationImage"
                :value="vehicleForm.registrationImage"
                :readonly="readonly"
                :headers="uploadHeaders"
                large
                class-prefix="vehicle"
                @success="
                  (url, file) =>
                    handleVehicleCertificateUploadSuccess('registrationImage', url, file)
                "
              />
            </el-col>
          </el-row>
        </section-card>
      </el-form>
      <template #footer>
        <el-button @click="vehicleBox = 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 { ElLoading } from 'element-plus';
import { option } from '@/option/transportCapacity/transport-vehicle';
import {
  getList,
  getDetail,
  submit,
  remove,
  changeStatus,
  auditCertification,
  getExpiryStat,
  recognitionTransportCertificates,
} from '@/api/transportCapacity/transport-vehicle';
import { getDeptTree } from '@/api/system/dept';
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 VehicleLedger from './components/vehicle-ledger.vue';

const emptyForm = () => ({
  id: '',
  organizationName: '',
  plateProvince: '',
  plateNoBody: '',
  plateNo: '',
  plateColor: '',
  vehicleType: '',
  outerLength: undefined,
  outerWidth: undefined,
  outerHeight: undefined,
  approvedLoadKg: undefined,
  tractionMassKg: undefined,
  businessRelation: '自有',
  energyType: '',
  compulsoryScrapDate: '',
  compulsoryScrapLongTerm: 0,
  customsRecordNo: '',
  drivingLicenseNo: '',
  drivingLicenseStartDate: '',
  drivingLicenseEndDate: '',
  drivingLicenseLongTerm: 0,
  drivingLicenseImage: '',
  drivingLicenseMainBack: '',
  drivingLicenseViceFront: '',
  drivingLicenseViceBack: '',
  roadTransportCertNo: '',
  roadTransportCertStartDate: '',
  roadTransportCertEndDate: '',
  roadTransportCertLongTerm: 0,
  roadTransportCertImage: '',
  annualReviewEndDate: '',
  annualReviewLongTerm: 0,
  registrationNo: '',
  registrationDate: '',
  registrationImage: '',
  status: 1,
});

const plateProvinceOptions = [
  '京',
  '津',
  '沪',
  '渝',
  '冀',
  '豫',
  '云',
  '辽',
  '黑',
  '湘',
  '皖',
  '鲁',
  '新',
  '苏',
  '浙',
  '赣',
  '鄂',
  '桂',
  '甘',
  '晋',
  '蒙',
  '陕',
  '吉',
  '闽',
  '贵',
  '粤',
  '青',
  '藏',
  '川',
  '宁',
  '琼',
  '港',
  '澳',
].map(item => ({ label: item, value: item }));

const plateColorOptions = ['黄牌', '蓝牌', '绿牌'].map(item => ({ label: item, value: item }));

export default {
  components: {
    ImageUploadField,
    VehicleLedger,
  },
  data() {
    return {
      option,
      form: {},
      query: {
        expireStatus: '',
      },
      searchForm: {
        businessRelation: '',
      },
      loading: true,
      submitLoading: false,
      data: [],
      ids: '',
      selectionList: [],
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0,
      },
      expiryStat: {
        total: 0,
        within30: 0,
        expired: 0,
      },
      vehicleBox: false,
      vehicleLedgerBox: false,
      ledgerVehicle: {},
      certificationAuditBox: false,
      certificationAuditForm: {},
      certificationRejectReason: '',
      showRejectReason: false,
      readonly: false,
      vehicleForm: emptyForm(),
      vehicleCertificateUploads: {},
      uploadHeaders: getUploadHeaders(),
      organizationOptions: [],
      plateProvinceOptions,
      plateColorOptions,
      vehicleTypeOptions: [
        { label: '高栏车', value: '高栏' },
        { label: '低栏车', value: '低栏' },
        { label: '平板车', value: '平板' },
        { label: '厢式车', value: '厢式' },
        { label: '拖挂车', value: '拖挂' },
        { label: '半挂车', value: '半挂' },
      ],
      businessRelationOptions: ['自有', '管理挂靠', '业务合作'],
      energyTypeOptions: ['柴油', '汽油', '新能源', '天然气'],
      formRules: {
        organizationName: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
        plateNo: [
          { required: true, message: '请输入车牌号', trigger: 'change' },
          { validator: this.validatePlateNo, trigger: 'change' },
        ],
        vehicleType: [{ required: true, message: '请选择车辆类型', trigger: 'change' }],
        approvedLoadKg: [{ required: true, message: '请输入核定载质量', trigger: 'blur' }],
        businessRelation: [{ required: true, message: '请选择业务关系', trigger: 'change' }],
        energyType: [{ required: true, message: '请选择能源类型', trigger: 'change' }],
        drivingLicenseNo: [{ required: true, message: '请输入行驶证档案编号', trigger: 'blur' }],
        drivingLicenseEndDate: [
          { required: true, message: '请选择行驶证有效期', trigger: 'change' },
        ],
        roadTransportCertNo: [{ required: true, message: '请输入道路运输证号', trigger: 'blur' }],
        roadTransportCertEndDate: [
          { required: true, message: '请选择道路运输证有效期', trigger: 'change' },
        ],
        annualReviewEndDate: [{ validator: this.validateAnnualReviewEndDate, trigger: 'change' }],
        registrationNo: [{ required: true, message: '请输入机动车登记编号', trigger: 'blur' }],
      },
    };
  },
  computed: {
    ...mapGetters(['permission', 'userInfo']),
    isAdmin() {
      const authority = this.userInfo.authority || '';
      return authority.includes('admin');
    },
    permissionList() {
      return {
        addBtn: this.hasPermission('transport_vehicle_add'),
        viewBtn: this.hasPermission('transport_vehicle_view'),
        delBtn: this.hasPermission('transport_vehicle_delete'),
        editBtn: this.hasPermission('transport_vehicle_edit'),
      };
    },
    dialogTitle() {
      if (this.readonly) {
        return '查看车辆';
      }
      return this.vehicleForm.id ? '修改车辆' : '新增车辆';
    },
    auditDetailItems() {
      return [
        ['所属组织', 'organizationName'], ['车牌号', 'plateNo'], ['车牌颜色', 'plateColor'],
        ['车辆类型', 'vehicleType'], ['外廓长度(mm)', 'outerLength'], ['外廓宽度(mm)', 'outerWidth'],
        ['外廓高度(mm)', 'outerHeight'], ['核定载质量(KG)', 'approvedLoadKg'], ['准牵引总质量(KG)', 'tractionMassKg'],
        ['业务关系', 'businessRelation'], ['能源类型', 'energyType'], ['强制报废日期', 'compulsoryScrapDate'],
        ['海关备案号', 'customsRecordNo'], ['行驶证档案编号', 'drivingLicenseNo'], ['行驶证有效期起', 'drivingLicenseStartDate'],
        ['行驶证有效期止', 'drivingLicenseEndDate'], ['道路运输证号', 'roadTransportCertNo'], ['道路运输证有效期起', 'roadTransportCertStartDate'],
        ['道路运输证有效期止', 'roadTransportCertEndDate'], ['道路运输年审有效期', 'annualReviewEndDate'],
        ['机动车登记编号', 'registrationNo'], ['机动车登记日期', 'registrationDate'], ['备注', 'remark'],
      ].map(([label, prop]) => ({ label, prop }));
    },
    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.vehicleBox && !this.vehicleForm.id && !this.vehicleForm.organizationName) {
          this.vehicleForm.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 || '';
    },
    digitsOnly(value = '') {
      return String(value).replace(/\D/g, '');
    },
    validatePlateNo(rule, value, callback) {
      const plateProvince = String(this.vehicleForm.plateProvince || '').trim();
      const plateNoBody = String(this.vehicleForm.plateNoBody || '')
        .trim()
        .toUpperCase();
      const plateColor = String(this.vehicleForm.plateColor || '').trim();
      if (!plateProvince || !plateNoBody || !plateColor) {
        callback(new Error('请完整填写车牌号'));
        return;
      }
      if (!/^[A-Z][A-Z0-9挂学警港澳]{5,6}$/.test(plateNoBody)) {
        callback(new Error('请输入标准车牌号'));
        return;
      }
      callback();
    },
    validateAnnualReviewEndDate(rule, value, callback) {
      if (this.vehicleForm.annualReviewLongTerm !== 1 && !value) {
        callback(new Error('请选择道路运输年审有效期'));
        return;
      }
      callback();
    },
    openVehicle(row, readonly = false) {
      this.readonly = readonly;
      if (!row?.id) {
        this.vehicleForm = emptyForm();
        this.vehicleForm.organizationName = this.getCurrentOrganizationName();
        this.syncPlateNo(false);
        this.vehicleBox = true;
        return;
      }
      getDetail(row.id).then(res => {
        this.vehicleForm = {
          ...emptyForm(),
          ...(res.data.data || {}),
        };
        this.splitPlateNo();
        this.syncPlateNo(false);
        this.vehicleBox = true;
      });
    },
    openVehicleLedger(row) {
      this.ledgerVehicle = { ...row };
      this.vehicleLedgerBox = true;
    },
    openCertificationAudit(row) {
      getDetail(row.id).then(res => {
        this.certificationAuditForm = { ...(res.data.data || {}) };
        this.certificationRejectReason = '';
        this.showRejectReason = false;
        this.certificationAuditBox = true;
      });
    },
    formatAuditValue(item) {
      const value = this.certificationAuditForm[item.prop];
      return value === undefined || value === null || value === '' ? '-' : value;
    },
    handleCertificationApprove() {
      auditCertification(this.certificationAuditForm.id, 1).then(() => {
        this.$message.success('认证已通过');
        this.certificationAuditBox = false;
        this.onLoad(this.page);
      });
    },
    handleCertificationReject() {
      if (!this.showRejectReason) { this.showRejectReason = true; return; }
      if (!this.certificationRejectReason.trim()) { this.$message.warning('请输入认证驳回原因'); return; }
      auditCertification(this.certificationAuditForm.id, 2, this.certificationRejectReason).then(() => {
        this.$message.success('认证已驳回');
        this.certificationAuditBox = false;
        this.onLoad(this.page);
      });
    },
    resetVehicle() {
      this.vehicleForm = emptyForm();
      this.vehicleCertificateUploads = {};
      this.readonly = false;
      this.submitLoading = false;
      this.$refs.vehicleForm?.clearValidate();
    },
    setImage(prop, url) {
      this.vehicleForm[prop] = url;
      this.$refs.vehicleForm?.validateField(prop);
    },
    handleVehicleCertificateUploadSuccess(prop, url) {
      this.setImage(prop, url);
      this.vehicleCertificateUploads[prop] = url;
      this.recognizeVehicleCertificates();
    },
    recognizeVehicleCertificates() {
      const objectKeys = [
        this.vehicleCertificateUploads.drivingLicenseImage || this.vehicleForm.drivingLicenseImage,
        this.vehicleCertificateUploads.drivingLicenseMainBack ||
          this.vehicleForm.drivingLicenseMainBack,
        this.vehicleCertificateUploads.drivingLicenseViceFront ||
          this.vehicleForm.drivingLicenseViceFront,
        this.vehicleCertificateUploads.drivingLicenseViceBack ||
          this.vehicleForm.drivingLicenseViceBack,
        this.vehicleCertificateUploads.registrationImage || this.vehicleForm.registrationImage,
      ].filter(Boolean);
      if (!objectKeys.length) {
        this.$message.warning('车辆资质图片上传成功，未获取到图片地址，无法自动识别');
        return;
      }
      const loading = ElLoading.service({
        lock: true,
        text: '车辆资质识别中',
        background: 'rgba(255, 255, 255, 0.7)',
      });
      recognitionTransportCertificates(objectKeys)
        .then(res => {
          this.applyVehicleCertificateRecognition(res.data.data || {});
          this.$message.success('车辆资质识别完成');
        })
        .catch(() => {
          this.$message.warning('车辆资质图片上传成功，自动识别失败，请手动填写车辆资质信息');
        })
        .finally(() => {
          loading.close();
        });
    },
    applyVehicleCertificateRecognition(data = {}) {
      const plateNo = data.drivingPlateNo || data.vehicleLicensePlateNo || '';
      const vehicleType = data.vehicleLicenseVehicleType || data.vehicleType || '';
      const drivingLicenseNo =
        data.vehicleLicenseFileNo || data.drivingLicenseNo || data.fileNo || '';
      const drivingLicenseEndDate =
        data.vehicleLicenseInspectionValidDate ||
        data.drivingLicenseEndDate ||
        data.vehicleLicenseValidDateEnd ||
        '';
      const registrationDate =
        data.vehicleLicenseRegisterDate || data.registrationDate || data.dateRegister || '';
      const registrationNo = data.registrationNo || data.vehicleLicenseNo || '';
      if (plateNo) {
        this.vehicleForm.plateNo = plateNo;
        this.splitPlateNo();
        this.syncPlateNo(false);
      }
      if (vehicleType) {
        this.vehicleForm.vehicleType = this.normalizeVehicleType(vehicleType);
      }
      if (drivingLicenseNo) {
        this.vehicleForm.drivingLicenseNo = drivingLicenseNo;
      }
      if (drivingLicenseEndDate) {
        this.vehicleForm.drivingLicenseEndDate = this.normalizeDate(drivingLicenseEndDate);
        this.vehicleForm.drivingLicenseLongTerm = 0;
      }
      if (registrationDate) {
        this.vehicleForm.registrationDate = this.normalizeDate(registrationDate);
      }
      if (registrationNo) {
        this.vehicleForm.registrationNo = registrationNo;
      }
      this.$nextTick(() => {
        [
          'plateNo',
          'vehicleType',
          'drivingLicenseNo',
          'drivingLicenseEndDate',
          'registrationNo',
        ].forEach(prop => {
          this.$refs.vehicleForm?.validateField(prop);
        });
      });
    },
    normalizeDate(value = '') {
      const dateValue = String(value || '').trim();
      const match = dateValue.match(/^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?$/);
      if (!match) return dateValue;
      const [, year, month, day] = match;
      return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
    },
    normalizeVehicleType(value = '') {
      const vehicleType = String(value || '').trim();
      const option = this.vehicleTypeOptions.find(
        item => item.value === vehicleType || item.label === vehicleType
      );
      return option ? option.value : vehicleType;
    },
    handlePlateBodyInput(value) {
      this.vehicleForm.plateNoBody = String(value || '').toUpperCase();
      this.syncPlateNo();
    },
    syncPlateNo(validate = true) {
      const plateProvince = String(this.vehicleForm.plateProvince || '').trim();
      const plateNoBody = String(this.vehicleForm.plateNoBody || '')
        .trim()
        .toUpperCase();
      const plateColor = String(this.vehicleForm.plateColor || '').trim();
      this.vehicleForm.plateNoBody = plateNoBody;
      this.vehicleForm.plateNo =
        plateProvince && plateNoBody ? `${plateProvince}${plateNoBody}` : '';
      this.vehicleForm.plateColor = plateColor;
      if (validate) {
        this.$refs.vehicleForm?.validateField('plateNo');
      }
    },
    splitPlateNo() {
      const plateNo = String(this.vehicleForm.plateNo || '').trim();
      if (!plateNo) {
        this.vehicleForm.plateProvince = '';
        this.vehicleForm.plateNoBody = '';
        return;
      }
      this.vehicleForm.plateProvince = plateNo.slice(0, 1);
      this.vehicleForm.plateNoBody = plateNo.slice(1).toUpperCase();
    },
    handleSubmit() {
      this.syncPlateNo();
      this.$refs.vehicleForm.validate(valid => {
        if (!valid) {
          return;
        }
        this.submitLoading = true;
        submit(this.vehicleForm)
          .then(() => {
            this.$message.success('操作成功');
            this.vehicleBox = 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 = {
        businessRelation: '',
      };
      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-vehicle/export-transport-vehicle',
          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 '';
    },
    getCertificationStatus(row) {
      if (row.certificationStatus === 0) return { label: '认证中', type: 'warning' };
      if (row.certificationStatus === 1) return { label: '已认证', type: 'success' };
      if (row.certificationStatus === 2) return { label: '已驳回', type: 'danger' };
      const today = this.$dayjs().startOf('day');
      const certificateDates = [
        [row.drivingLicenseEndDate, row.drivingLicenseLongTerm],
        [row.roadTransportCertEndDate, row.roadTransportCertLongTerm],
      ];
      if (certificateDates.some(([date, longTerm]) => longTerm !== 1 && !date)) {
        return { label: '未认证', type: 'info' };
      }
      if (
        certificateDates.some(
          ([date, longTerm]) => longTerm !== 1 && this.$dayjs(date).isBefore(today, 'day')
        )
      ) {
        return { label: '已过期', type: 'danger' };
      }
      return { label: '已认证', type: 'success' };
    },
  },
};
</script>

<style lang="scss" scoped>
.transport-vehicle-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;
  }
}

.vehicle-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%;
  }

  .plate-group {
    display: grid;
    grid-template-columns: 112px minmax(0, 1fr) 112px;
    gap: 8px;
    align-items: center;
  }

  .dimension-group {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    align-items: center;
  }

  .dimension-group__item {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
  }

  .dimension-group__label {
    flex-shrink: 0;
    color: #303133;
    font-weight: 500;
  }

  .date-with-flag {
    display: flex;
    align-items: center;
    gap: 8px;
  }

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

  .date-with-flag :deep(.el-checkbox) {
    flex-shrink: 0;
    margin-right: 0;
  }

  .date-with-flag :deep(.el-checkbox__label) {
    padding-left: 4px;
  }

  .date-range {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 8px;
  }

  :deep(.el-form-item__label) {
    white-space: nowrap;
  }
}

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

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

// 大尺寸模式：缩成 1.586:1 比例，左对齐（不再 100% 占栏）
:deep(.vehicle-uploader--large) {
  display: block;
  width: 240px;
  margin: 0;
}

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

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

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

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

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