<template>
  <el-dialog v-model="visible" :title="dialogTitle" width="640px" destroy-on-close>
    <div class="dialog-form">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="150px" label-suffix="：">
        <el-form-item label="律所名称" prop="firmName">
          <el-input v-model="form.firmName" placeholder="请输入律所名称" clearable />
        </el-form-item>
        <el-form-item label="负责人姓名" prop="directorName">
          <el-input v-model="form.directorName" placeholder="请输入负责人姓名" clearable />
        </el-form-item>
        <el-form-item label="律所位置" prop="address">
          <el-input v-model="form.address" placeholder="请输入律所位置" clearable />
        </el-form-item>
        <el-form-item label="社会统一信用代码" prop="creditCode">
          <el-input v-model="form.creditCode" placeholder="请输入社会统一信用代码" clearable />
        </el-form-item>
        <el-form-item label="电话号码" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入电话号码" clearable maxlength="11" />
        </el-form-item>
        <el-form-item label="收款账号" prop="paymentAccount">
          <div class="bank-card-input">
            <el-input v-model="bankCardDisplay" placeholder="请输入银行卡号" maxlength="23" clearable :disabled="isEditMode" />
          </div>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <el-button @click="visible = false"> 取消 </el-button>
      <el-button type="primary" :loading="loading" @click="handleSubmit"> 确定 </el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, nextTick } from "vue";
import { ElMessage, type FormInstance } from "element-plus";

interface DialogOptions {
  title: string;
  row?: Record<string, any>;
  onSubmit: (params: Record<string, any>) => Promise<any>;
}

const visible = ref(false);
const loading = ref(false);
const formRef = ref<FormInstance>();
const options = ref<DialogOptions>({
  title: "",
  row: {},
  onSubmit: async () => Promise.resolve()
});
const form = reactive({
  id: "",
  firmName: "",
  directorName: "",
  address: "",
  creditCode: "",
  paymentAccount: "",
  phone: ""
});
const bankCardInput = ref("");
const bankCardReg = /^([1-9]\d{15}|\d{17}|\d{18}|\d{19})$/;

const validatePhoneNumber = (_rule: any, value: string, callback: (err?: Error) => void) => {
  if (!value || value.trim() === "") {
    callback(new Error("请输入电话号码"));
    return;
  }
  const phoneReg = /^1[3-9]\d{9}$/;
  if (!phoneReg.test(value)) {
    callback(new Error("请输入正确的手机号码"));
    return;
  }
  callback();
};

const rules = reactive({
  firmName: [{ required: true, message: "请输入律所名称", trigger: "blur" }],
  directorName: [{ required: true, message: "请输入负责人姓名", trigger: "blur" }],
  address: [{ required: true, message: "请输入律所位置", trigger: "blur" }],
  creditCode: [{ required: true, message: "请输入社会统一信用代码", trigger: "blur" }],
  paymentAccount: [
    { required: true, message: "请输入收款账号", trigger: "blur" },
    {
      validator: (_rule, _value, callback) => {
        const card = bankCardInput.value.trim();
        if (!card) {
          callback(new Error("请输入收款账号"));
        } else if (!bankCardReg.test(card)) {
          callback(new Error("请输入正确的银行卡号"));
        } else {
          callback();
        }
      },
      trigger: "change"
    }
  ],
  phone: [
    { required: true, message: "请输入电话号码", trigger: "blur" },
    { validator: validatePhoneNumber, trigger: "blur" }
  ]
});

const dialogTitle = computed(() => options.value.title);

const resetForm = () => {
  form.id = "";
  form.firmName = "";
  form.directorName = "";
  form.address = "";
  form.creditCode = "";
  form.paymentAccount = "";
  form.phone = "";
  bankCardInput.value = "";
};

const open = (payload: DialogOptions) => {
  resetForm();
  options.value = payload;
  if (payload.row) {
    Object.assign(form, payload.row);
    bankCardInput.value = (form.paymentAccount || "").replace(/\s+/g, "");
    form.phone = payload.row.phone || "";
    form.creditCode = payload.row.creditCode || "";
  } else {
    form.phone = "";
    form.creditCode = "";
    bankCardInput.value = "";
    form.paymentAccount = "";
  }
  visible.value = true;
  nextTick(() => formRef.value?.clearValidate());
};

const emits = defineEmits<{
  success: [];
}>();

const isEditMode = computed(() => !!form.id);

const bankCardDisplay = computed({
  get: () => formatCard(bankCardInput.value),
  set: val => {
    bankCardInput.value = val.replace(/\s+/g, "");
    form.paymentAccount = bankCardInput.value;
    formRef.value?.validateField("paymentAccount").catch(() => {});
  }
});

const formatCard = (card: string) => {
  return card
    .replace(/\s+/g, "")
    .replace(/(.{4})/g, "$1 ")
    .trim();
};

const handleSubmit = () => {
  form.paymentAccount = bankCardInput.value;
  formRef.value?.validate(async valid => {
    if (!valid) return;
    loading.value = true;
    try {
      await options.value.onSubmit({ ...form });
      emits("success");
      visible.value = false;
    } finally {
      loading.value = false;
    }
  });
};

defineExpose({
  open
});
</script>

<style scoped lang="scss">
.dialog-form {
  max-width: 560px;
  margin: 0 auto;
}
.bank-card-input {
  display: flex;
  gap: 12px;
  align-items: stretch;
  margin-bottom: 8px;
}
.bank-card-input .el-input {
  flex: 1;
}
.bank-card-tags {
  display: flex;
  flex-wrap: wrap;
}
.bank-card-tip {
  display: flex;
  padding-bottom: 0;
  margin-left: 4px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
.form-tip {
  margin-left: 12px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
</style>
