<template>
  <div class="accident-create-container">
    <el-form ref="formRef" :model="formData" :rules="rules" class="form-wrap">
      <div class="personnel-section">
        <div v-for="(person, index) in personnelList" :key="index" class="personnel-item">
          <el-row :gutter="40">
            <el-col :span="6">
              <el-form-item :prop="`accidentPersonnelInfoList.${index}.carNum`" :rules="carNumRules" label="车牌号：">
                <el-input
                  v-model="person.carNum"
                  placeholder="请输入违规车辆车牌号码"
                  maxlength="8"
                  show-word-limit
                  clearable
                />
              </el-form-item>
            </el-col>
            <el-col :span="10">
              <el-form-item
                :prop="`accidentPersonnelInfoList.${index}.accidentPersonnel`"
                :rules="personRules"
                label="事故人员："
              >
                <el-input
                  v-model="person.accidentPersonnel"
                  placeholder="请输入事故人员姓名"
                  maxlength="20"
                  show-word-limit
                  clearable
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item
                :prop="`accidentPersonnelInfoList.${index}.phoneNum`"
                :rules="phoneRules"
                label="联系方式："
              >
                <el-input
                  v-model="person.phoneNum"
                  placeholder="请输入联系方式"
                  maxlength="11"
                  show-word-limit
                  clearable
                />
              </el-form-item>
            </el-col>
            <el-col :span="2" class="delete-col">
              <el-button
                type="danger"
                link
                :icon="Delete"
                :disabled="personnelList.length === 1"
                @click="removePersonnel(index)"
                >删除</el-button
              >
            </el-col>
          </el-row>
        </div>
        <el-button type="primary" :icon="Plus" :disabled="personnelList.length >= 10" @click="addPersonnel">
          新增
        </el-button>
      </div>

      <el-row :gutter="40" class="basic-info">
        <el-col :span="12">
          <el-form-item label="事故地点：" prop="trafficAccidentRecord.accidentLocation">
            <el-input
              v-model="formData.trafficAccidentRecord.accidentLocation"
              placeholder="请输入事故发生地点"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="事故时间：" prop="trafficAccidentRecord.accidentTime">
            <el-date-picker
              v-model="formData.trafficAccidentRecord.accidentTime"
              type="datetime"
              value-format="YYYY-MM-DD HH:mm:ss"
              placeholder="请选择事故发生时间"
              style="width: 100%"
              :disabled-date="disabledDate"
              :disabled-time="disabledTime"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="事故描述：" prop="trafficAccidentRecord.accidentDescription">
        <el-input
          v-model="formData.trafficAccidentRecord.accidentDescription"
          type="textarea"
          :rows="4"
          placeholder="请输入事故描述"
          clearable
        />
      </el-form-item>
      <el-form-item label="事故图片：" label-width="92.54px">
        <UploadImages
          ref="uploadImagesRef"
          :maxCount="5"
          :image-list="recordImageList"
          @upload-success="handleUploadChange"
        />
      </el-form-item>
      <el-form-item label="备注：" label-width="92.54px">
        <el-input v-model="formData.trafficAccidentRecord.remark" placeholder="请输入备注" clearable />
      </el-form-item>
      <el-form-item label="创建人：" label-width="92.54px">
        <el-input v-model="formData.trafficAccidentRecord.createdByName" placeholder="创建人" disabled />
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, onMounted, computed } from 'vue';
  import { useRoute, onBeforeRouteLeave } from 'vue-router';
  import { ElForm } from 'element-plus';
  import { Delete, Plus } from '@element-plus/icons-vue';
  import UploadImages from '@/views/disaster/disaster-control/src/components/UploadImages.vue';
  import { useUserInfoHook } from '@/views/disaster/hooks';
  import { ImageItem } from '@/types/disaster-control';
  import { UPLOAD_BIZ_TYPE, uploadFileApi } from '@/api/minio';
  import { AccidentPersonnelInfoStruct, AddAccidentInfoStruct, getAccidentInfoDetail } from '@/api/traffic-accident';
  import { msgConfirm } from '@/utils/element-plus/messageBox';

  const { realname } = useUserInfoHook();

  const route = useRoute();
  const operate = route.query.operate;
  const id = route.query.id;

  const formRef = ref<InstanceType<typeof ElForm>>();

  const formData = ref<AddAccidentInfoStruct>({
    trafficAccidentRecord: {
      accidentImages: '',
      accidentLocation: '',
      accidentTime: '',
      accidentDescription: '',
      remark: '',
      createdByName: '',
    },
    accidentPersonnelInfoList: [{ carNum: '', accidentPersonnel: '', phoneNum: '' }],
  });

  const personnelList = ref<AccidentPersonnelInfoStruct[]>([]);

  // 保存初始表单数据用于比较
  const initialFormData = ref<AddAccidentInfoStruct>({
    trafficAccidentRecord: {
      accidentImages: '',
      accidentLocation: '',
      accidentTime: '',
      accidentDescription: '',
      remark: '',
      createdByName: '',
    },
    accidentPersonnelInfoList: [],
  });
  const initialPersonnelList = ref<AccidentPersonnelInfoStruct[]>([]);
  const initialImagesString = ref<string>('');

  const rules = reactive({
    'trafficAccidentRecord.accidentLocation': [{ required: true, message: '请输入事故地点', trigger: 'blur' }],
    'trafficAccidentRecord.accidentTime': [{ required: true, message: '请选择事故时间', trigger: 'change' }],
    'trafficAccidentRecord.accidentDescription': [{ required: true, message: '请输入事故描述', trigger: 'blur' }],
  });

  const carNumRules = [
    {
      validator: (_: unknown, value: string, callback: (err?: Error) => void) => {
        if (!value) return callback();
        if (!/^.{0,8}$/.test(value)) return callback(new Error('车牌号格式错误'));
        callback();
      },
      trigger: ['blur', 'change'],
    },
  ];
  const personRules = [
    { required: true, message: '请输入事故人员姓名', trigger: 'blur' },
    { min: 1, max: 20, message: '最多20个字符', trigger: 'blur' },
  ];
  const phoneRules = [
    {
      validator: (_: unknown, value: string, callback: (err?: Error) => void) => {
        if (!value) return callback();
        if (!/^1\d{10}$/.test(value)) return callback(new Error('联系方式非11位数字'));
        callback();
      },
      trigger: ['blur', 'change'],
    },
  ];

  // 新增
  const addPersonnel = () => {
    if (personnelList.value.length >= 10) return;
    personnelList.value.push({ carNum: '', accidentPersonnel: '', phoneNum: '' });
  };

  // 删除
  const removePersonnel = (index: number) => {
    if (personnelList.value.length === 1) return;
    personnelList.value.splice(index, 1);
  };

  // 禁用未来日期
  const disabledDate = (time: Date) => {
    return time.getTime() > Date.now();
  };

  // 禁用未来时间
  const disabledTime = (date: Date) => {
    const now = new Date();
    if (date.toDateString() === now.toDateString()) {
      return {
        disabledHours: () => {
          const hours: number[] = [];
          for (let i = now.getHours() + 1; i < 24; i++) {
            hours.push(i);
          }
          return hours;
        },
        disabledMinutes: (hour: number) => {
          if (hour === now.getHours()) {
            const minutes: number[] = [];
            for (let i = now.getMinutes() + 1; i < 60; i++) {
              minutes.push(i);
            }
            return minutes;
          }
          return [];
        },
        disabledSeconds: (hour: number, minute: number) => {
          if (hour === now.getHours() && minute === now.getMinutes()) {
            const seconds: number[] = [];
            for (let i = now.getSeconds() + 1; i < 60; i++) {
              seconds.push(i);
            }
            return seconds;
          }
          return [];
        },
      };
    }
    return {};
  };

  // 事故图片
  const uploadImagesRef = ref<InstanceType<typeof UploadImages>>();
  const uploadImages = ref<ImageItem[]>([]);
  const imagesString = ref<string>('');

  const recordImageList = computed(() => {
    if (!formData.value.trafficAccidentRecord.accidentImages) return [];
    return JSON.parse(formData.value.trafficAccidentRecord.accidentImages);
  });

  // 格式化事故图片
  const formatImageList = async (file: File) => {
    if (!file) return file;
    const fileName = file.name;
    const res = await uploadFileApi({ bizType: UPLOAD_BIZ_TYPE.ATTACHMENT, fileName, file });
    return '"' + res.url + '"';
  };

  const handleUploadChange = async () => {
    uploadImages.value = uploadImagesRef.value!.getUploadedImages();
    const images = await Promise.all(
      (uploadImages.value || []).map((item) => {
        if (!item.file && item.url) {
          return '"' + item.url + '"';
        } else {
          return formatImageList(item.file!);
        }
      }),
    );
    imagesString.value = '[' + images.toString() + ']';
  };

  // 检测表单是否有修改
  const hasFormChanged = () => {
    // 比较事故记录数据
    const currentRecord = formData.value.trafficAccidentRecord;
    const initialRecord = initialFormData.value.trafficAccidentRecord;

    if (
      currentRecord.accidentLocation !== initialRecord.accidentLocation ||
      currentRecord.accidentTime !== initialRecord.accidentTime ||
      currentRecord.accidentDescription !== initialRecord.accidentDescription ||
      currentRecord.remark !== initialRecord.remark ||
      imagesString.value !== initialImagesString.value
    ) {
      return true;
    }

    // 比较人员信息数据
    if (personnelList.value.length !== initialPersonnelList.value.length) {
      return true;
    }

    for (let i = 0; i < personnelList.value.length; i++) {
      const current = personnelList.value[i];
      const initial = initialPersonnelList.value[i];
      if (
        current.carNum !== initial.carNum ||
        current.accidentPersonnel !== initial.accidentPersonnel ||
        current.phoneNum !== initial.phoneNum
      ) {
        return true;
      }
    }

    return false;
  };

  // 保存初始数据
  const saveInitialData = () => {
    initialFormData.value = JSON.parse(JSON.stringify(formData.value));
    initialPersonnelList.value = JSON.parse(JSON.stringify(personnelList.value));
    initialImagesString.value = imagesString.value;
  };

  // 重置表单状态（提交成功后调用）
  const resetFormState = () => {
    saveInitialData();
  };

  const handleValidate = async () => {
    const form = formRef.value;
    if (!form) return false;
    try {
      await form.validate();
      return true;
    } catch (_) {
      return false;
    }
  };

  const getFormData = (): AddAccidentInfoStruct => {
    formData.value.trafficAccidentRecord.accidentImages = imagesString.value;
    const payload: AddAccidentInfoStruct = {
      trafficAccidentRecord: formData.value.trafficAccidentRecord,
      accidentPersonnelInfoList: personnelList.value.map(({ carNum, accidentPersonnel, phoneNum }) => ({
        carNum,
        accidentPersonnel,
        phoneNum,
      })),
    } as unknown as AddAccidentInfoStruct;
    return payload;
  };

  // 路由守卫 - 离开页面前的确认
  onBeforeRouteLeave((to, from, next) => {
    const hasChange = hasFormChanged();
    if (!hasChange) {
      next();
      return;
    }

    setTimeout(() => {
      msgConfirm('当前页面存在修改，是否确认离开当前页面？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        customClass: 'customMessageBox--warning',
      })
        .then(() => {
          next();
        })
        .catch(() => {
          next(false);
        });
    }, 200);
  });

  defineExpose({ handleValidate, getFormData, resetFormState });

  onMounted(() => {
    formData.value.trafficAccidentRecord.createdByName = realname;
    personnelList.value = formData.value.accidentPersonnelInfoList;

    if (operate === 'edit') {
      getAccidentInfoDetail({ accidentRecordId: Number(id) }).then((res) => {
        formData.value = res;
        personnelList.value = res.accidentPersonnelInfoList;
        imagesString.value = res.trafficAccidentRecord.accidentImages;

        // 数据加载完成后保存初始数据
        setTimeout(() => {
          saveInitialData();
        }, 100);
      });
    } else {
      // 创建模式，立即保存初始数据
      setTimeout(() => {
        saveInitialData();
      }, 100);
    }
  });
</script>

<style scoped lang="scss">
  .accident-create-container {
    .personnel-section {
      background: #f5f9ff;
      border-radius: 4px;
      padding: 20px 34px;
      margin-bottom: 30px;

      .personnel-item {
        margin-bottom: 20px;

        :deep(.el-form-item) {
          margin-bottom: 0;
        }

        .el-row {
          align-items: center;
        }
      }

      .delete-col {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: flex-end;
      }
    }
  }
</style>
