<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"
          plain
          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 #menu-right>
        <el-radio-group
          v-model="query.expireStatus"
          class="vehicle-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>
      </template>
      <template #plateNo="{ row }">
        <el-button type="primary" link @click="openVehicle(row, true)">
          {{ row.plateNo }}
        </el-button>
      </template>
      <template #status="{ row }">
        <el-tag :type="row.status === 1 ? 'primary' : 'info'">
          {{ row.status === 1 ? '启用' : '停用' }}
        </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"
          v-if="hasPermission('transport_vehicle_status')"
          @click="handleStatus(row)"
        >
          {{ row.status === 1 ? '停用' : '启用' }}
        </el-link>
      </template>
    </avue-crud>

    <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"
      >
        <div class="section-title">基础车辆信息</div>
        <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-number
                    v-model="vehicleForm.outerLength"
                    :min="0"
                    :precision="0"
                    controls-position="right"
                  />
                </div>
                <div class="dimension-group__item">
                  <span class="dimension-group__label">宽</span>
                  <el-input-number
                    v-model="vehicleForm.outerWidth"
                    :min="0"
                    :precision="0"
                    controls-position="right"
                  />
                </div>
                <div class="dimension-group__item">
                  <span class="dimension-group__label">高</span>
                  <el-input-number
                    v-model="vehicleForm.outerHeight"
                    :min="0"
                    :precision="0"
                    controls-position="right"
                  />
                </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-number
                v-model="vehicleForm.approvedLoadKg"
                :min="0"
                :precision="0"
                controls-position="right"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="准牵引总质量(KG)" prop="tractionMassKg">
              <el-input-number
                v-model="vehicleForm.tractionMassKg"
                :min="0"
                :precision="0"
                controls-position="right"
              />
            </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>

        <div class="section-title">车辆资质图片</div>
        <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>
      </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,
  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';

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,
  },
  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,
      },
      vehicleBox: 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: [{ 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 ? '修改车辆' : '新增车辆';
    },
  },
  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;
      });
    },
    flattenDeptOptions(tree = [], level = 0) {
      const result = [];
      tree.forEach(item => {
        const label = item.title || item.deptName || item.name;
        result.push({
          label: `${'　'.repeat(level)}${label}`,
          value: label,
        });
        if (item.children && item.children.length) {
          result.push(...this.flattenDeptOptions(item.children, level + 1));
        }
      });
      return result;
    },
    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.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;
      });
    },
    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, file = {}) {
      this.setImage(prop, url);
      this.vehicleCertificateUploads[prop] = this.getUploadRecognitionKey(file, 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);
        });
      });
    },
    getUploadRecognitionKey(file = {}, url = '') {
      return (
        file.objectKey ||
        file.key ||
        file.fileName ||
        file.name ||
        file.link ||
        file.url ||
        file.domain ||
        url ||
        ''
      );
    },
    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() {
      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-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 '';
    },
  },
};
</script>

<style lang="scss" scoped>
.transport-vehicle-page {
  .vehicle-stat {
    flex-shrink: 0;
  }

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

.vehicle-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),
  :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;
  }
}

:deep(.vehicle-uploader) {
  display: block;
  width: 100%;
}

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

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

: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: #f56c6c;
  font-weight: 600;
}

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