<template>
  <div>
    <!-- 二次验证对话框 -->
    <el-dialog v-model="visibleProxy" :title="title" width="500px" append-to-body :close-on-click-modal="false" @closed="resetForm">
      <el-form ref="verifyFormRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="验证方式" prop="verifyType">
          <el-radio-group v-model="form.verifyType">
            <el-radio :value="3">密码验证</el-radio>
            <el-radio v-if="currentUser.phonenumber" :value="1">短信验证</el-radio>
            <el-radio v-if="currentUser.email" :value="2">邮件验证</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 密码验证 -->
        <template v-if="form.verifyType === 3">
          <el-form-item label="用户名">
            <el-input v-model="currentUser.userName" disabled />
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input
              v-model="form.password"
              type="password"
              placeholder="请输入密码"
              show-password
              autocomplete="new-password"
              :name="'pwd_' + randomStr"
              ref="passwordInputRef"
            />
          </el-form-item>
        </template>

        <!-- 短信验证 -->
        <template v-if="form.verifyType === 1">
          <el-form-item label="手机号码">
            <el-input v-model="maskedPhone" disabled />
          </el-form-item>
          <el-form-item label="验证码" prop="smsCode">
            <div class="verify-code-container">
              <el-input v-model="form.smsCode" placeholder="请输入验证码" maxlength="6" />
              <el-button :disabled="smsTimer > 0" @click="sendSmsCode">
                {{ smsTimer > 0 ? `重新获取(${smsTimer}s)` : '获取验证码' }}
              </el-button>
            </div>
          </el-form-item>
        </template>

        <!-- 邮件验证 -->
        <template v-if="form.verifyType === 2">
          <el-form-item label="邮箱">
            <el-input v-model="maskedEmail" disabled />
          </el-form-item>
          <el-form-item label="验证码" prop="emailCode">
            <div class="verify-code-container">
              <el-input v-model="form.emailCode" placeholder="请输入验证码" maxlength="6" />
              <el-button :disabled="emailTimer > 0" @click="sendEmailCode">
                {{ emailTimer > 0 ? `重新获取(${emailTimer}s)` : '获取验证码' }}
              </el-button>
            </div>
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { UserVO, VerifyResult } from '@/api/system/user/types';
import { ElMessage } from 'element-plus';
import { sendAuthCode, verifyAuthCode, verifyPassword } from '@/api/system/security';
import api from '@/api/system/user';
import { nextTick } from 'vue';
import { secureRandom } from '@/utils/ruoyi';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '二次验证'
  },
  operationType: {
    type: String,
    default: 'default' // 可以是 'edit', 'delete', 'sensitive' 等
  }
});

const emit = defineEmits(['update:visible', 'verify-success', 'verify-cancel']);

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

// 表单实例
const verifyFormRef = ref<ElFormInstance>();

// 当前登录用户信息
const currentUser = reactive<Partial<UserVO>>({});

// 随机字符串，用于防止密码自动填充
const randomStr = ref(secureRandom().toString(36).substring(2, 10));

// 密码输入框引用
const passwordInputRef = ref();

// 验证表单数据
const form = reactive({
  verifyType: 3, // 默认密码验证
  smsCode: '',
  emailCode: '',
  password: ''
});

// 验证倒计时
const smsTimer = ref(0);
const emailTimer = ref(0);
const buttonLoading = ref(false);

// 手机号码掩码处理
const maskedPhone = computed(() => {
  const phone = currentUser.phonenumber || '';
  if (phone.length >= 11) {
    return phone.substring(0, 3) + '****' + phone.substring(7);
  }
  return phone;
});

// 邮箱掩码处理
const maskedEmail = computed(() => {
  const email = currentUser.email || '';
  if (email.includes('@')) {
    const [username, domain] = email.split('@');
    if (username.length > 2) {
      return username.substring(0, 2) + '****@' + domain;
    }
    return username + '****@' + domain;
  }
  return email;
});

// 可见性的双向绑定
const visibleProxy = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
});

// 表单验证规则
const rules = reactive({
  verifyType: [{ required: true, message: '请选择验证方式', trigger: 'change' }],
  smsCode: [
    { required: true, message: '请输入短信验证码', trigger: 'blur' },
    { pattern: /^\d{6}$/, message: '验证码必须是6位数字', trigger: 'blur' }
  ],
  emailCode: [
    { required: true, message: '请输入邮箱验证码', trigger: 'blur' },
    { pattern: /^\d{6}$/, message: '验证码必须是6位数字', trigger: 'blur' }
  ],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
});

// 获取当前用户信息
const loadCurrentUser = async () => {
  try {
    const res = await api.getUserProfile();
    if (res.code === 200 && res.data) {
      Object.assign(currentUser, res.data.user);
      // 默认使用密码验证，不再根据用户信息自动选择验证方式
    } else {
      ElMessage.error('获取用户信息失败');
    }
  } catch (error) {
    ElMessage.error('获取用户信息失败，请刷新页面重试');
  }
};

// 发送短信验证码
const sendSmsCode = async () => {
  try {
    await sendAuthCode(1); // 1 表示短信验证码
    ElMessage.success('验证码发送成功，请注意查收');
    smsTimer.value = 60;
    const interval = setInterval(() => {
      smsTimer.value--;
      if (smsTimer.value <= 0) {
        clearInterval(interval);
      }
    }, 1000);
  } catch (error) {
    ElMessage.error('验证码发送失败，请稍后重试');
  }
};

// 发送邮件验证码
const sendEmailCode = async () => {
  try {
    await sendAuthCode(2); // 2 表示邮件验证码
    ElMessage.success('验证码发送成功，请注意查收');
    emailTimer.value = 60;
    const interval = setInterval(() => {
      emailTimer.value--;
      if (emailTimer.value <= 0) {
        clearInterval(interval);
      }
    }, 1000);
  } catch (error) {
    ElMessage.error('验证码发送失败，请稍后重试');
  }
};

// 提交验证
const submitForm = () => {
  verifyFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;

      try {
        let verifyResult;

        if (form.verifyType === 1) {
          // 短信验证
          await verifyAuthCode({
            authCodeType: 1,
            authCode: form.smsCode,
            safeType: props.operationType,
            timeout: 180
          });
        } else if (form.verifyType === 2) {
          // 邮件验证
          await verifyAuthCode({
            authCodeType: 2,
            authCode: form.emailCode,
            safeType: props.operationType,
            timeout: 180
          });
        } else if (form.verifyType === 3) {
          // 密码验证
          await verifyPassword({
            authCodeType: 3,
            password: form.password,
            safeType: props.operationType,
            timeout: 180
          });
        }

        ElMessage.success('验证成功');

        const result: VerifyResult = {
          operationType: props.operationType,
          verifyType: form.verifyType,
          success: true
        };

        emit('verify-success', result);
        visibleProxy.value = false;
      } catch (error) {
        ElMessage.error('验证失败，请检查输入并重试');
      } finally {
        buttonLoading.value = false;
      }
    }
  });
};

// 取消按钮
const cancel = () => {
  emit('verify-cancel');
  visibleProxy.value = false;
};

// 重置表单
const resetForm = () => {
  form.smsCode = '';
  form.emailCode = '';
  form.password = '';
  verifyFormRef.value?.resetFields();

  // 生成新的随机字符串，防止密码自动填充
  randomStr.value = secureRandom().toString(36).substring(2, 10);
};

// 组件挂载时加载当前用户信息
onMounted(() => {
  loadCurrentUser();
});

// 监听对话框显示状态
watch(
  () => props.visible,
  (newVal) => {
    if (newVal) {
      if (Object.keys(currentUser).length === 0) {
        loadCurrentUser();
      }

      // 每次打开对话框都重置密码字段并生成新的随机字符串
      form.password = '';
      randomStr.value = secureRandom().toString(36).substring(2, 10);

      // 使用nextTick确保DOM更新后再清空密码输入框
      nextTick(() => {
        if (passwordInputRef.value && passwordInputRef.value.$el) {
          const inputEl = passwordInputRef.value.$el.querySelector('input');
          if (inputEl) {
            inputEl.value = '';
          }
        }
      });
    }
  }
);
</script>

<style scoped>
.verify-code-container {
  display: flex;
  align-items: center;
  gap: 10px;
}

.verify-code-container .el-input {
  flex-grow: 1;
}

.verify-code-container .el-button {
  flex-shrink: 0;
  width: 110px;
}
</style>
