﻿<template>
  <view class="ppm-overlay" v-if="visible" @tap="handleCancel">
    <view class="ppm-dialog" @tap.stop>
      <!-- 头部 -->
      <view class="ppm-header">
        <text class="ppm-header__icon">&#128274;</text>
        <text class="ppm-header__title">{{ title }}</text>
        <text v-if="subtitle" class="ppm-header__subtitle">{{ subtitle }}</text>
      </view>

      <!-- 金额展示 -->
      <view v-if="amount != null" class="ppm-amount">
        <text class="ppm-amount__label">{{ amountLabel }}</text>
        <text class="ppm-amount__value">¥{{ formatAmount(amount) }}</text>
      </view>

      <!-- 退款提示（免费次数） -->
      <view v-if="cancelNotice && cancelNotice.length" class="ppm-notice">
        <text>{{ cancelNotice }}</text>
      </view>

      <!-- 密码输入 -->
      <view class="ppm-input-wrap">
        <view class="ppm-code-box">
          <view
            v-for="i in 6"
            :key="i"
            class="ppm-code-item"
            :class="{
              'ppm-code-item--focus': focusIndex === i - 1 && password.length < 6,
              'ppm-code-item--filled': password.length >= i
            }"
          >
            <text v-if="password.length >= i" class="ppm-code-dot"></text>
            <view v-if="focusIndex === i - 1 && password.length === i - 1" class="ppm-code-cursor"></view>
          </view>
        </view>
      </view>

      <!-- 隐藏输入框 -->
      <input
        class="ppm-hidden-input"
        type="number"
        :maxlength="6"
        :focus="inputFocus"
        :value="password"
        @input="onInput"
        @focus="onFocus"
        @blur="onBlur"
      />

      <!-- 提示 -->
      <view class="ppm-tips">
        <text>请输入6位支付密码</text>
      </view>

      <!-- 底部按钮 -->
      <view class="ppm-buttons">
        <view class="ppm-btn ppm-btn--cancel" @tap="handleCancel">
          <text>取消</text>
        </view>
        <view
          class="ppm-btn ppm-btn--confirm"
          :class="{ 'ppm-btn--disabled': password.length < 6 || loading }"
          @tap="handleConfirm"
        >
          <text>{{ loading ? '验证中...' : '确认' }}</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, watch, nextTick } from 'vue'

const props = defineProps({
  visible: { type: Boolean, default: false },
  title: { type: String, default: '支付验证' },
  subtitle: { type: String, default: '' },
  amount: { type: [Number, String], default: null },
  amountLabel: { type: String, default: '支付金额' },
  cancelNotice: { type: String, default: '' },
  errorMsg: { type: String, default: '' },
  loading: { type: Boolean, default: false }
})

const emit = defineEmits(['confirm', 'cancel'])

const password = ref('')
const inputFocus = ref(false)
const focusIndex = ref(0)

watch(() => props.visible, (val) => {
  if (val) {
    password.value = ''
    focusIndex.value = 0
    nextTick(() => {
      setTimeout(() => {
        inputFocus.value = true
      }, 300)
    })
  }
})

function formatAmount(val) {
  return Number(val).toFixed(2)
}

function onInput(e) {
  let val = String(e.detail.value || '').replace(/\D/g, '').slice(0, 6)
  password.value = val
  focusIndex.value = val.length
}

function onFocus() {
  inputFocus.value = true
  focusIndex.value = password.value.length
}

function onBlur() {
  // Keep focusIndex, just mark input as not focused
}

function handleConfirm() {
  if (password.value.length < 6 || props.loading) return
  emit('confirm', password.value)
}

function handleCancel() {
  emit('cancel')
}

function clear() {
  password.value = ''
  focusIndex.value = 0
}

defineExpose({ clear })
</script>

<style lang="scss" scoped>
.ppm-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  animation: ppm-fade-in 0.25s ease;
}

@keyframes ppm-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.ppm-dialog {
  width: 600rpx;
  background: #FFFFFF;
  border-radius: 32rpx;
  padding: 48rpx 40rpx 36rpx;
  box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.15);
  animation: ppm-scale-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  display: flex;
  flex-direction: column;
  align-items: center;
}

@keyframes ppm-scale-in {
  from { opacity: 0; transform: scale(0.85); }
  to { opacity: 1; transform: scale(1); }
}

.ppm-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 28rpx;
}

.ppm-header__icon {
  font-size: 48rpx;
  margin-bottom: 12rpx;
}

.ppm-header__title {
  font-size: 34rpx;
  font-weight: 700;
  color: #1A202C;
}

.ppm-header__subtitle {
  font-size: 24rpx;
  color: #8A99B4;
  margin-top: 6rpx;
}

.ppm-amount {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx 40rpx;
  background: linear-gradient(135deg, #FFF5F0 0%, #FFF8F5 100%);
  border-radius: 16rpx;
  margin-bottom: 24rpx;
  width: 100%;
  box-sizing: border-box;
}

.ppm-amount__label {
  font-size: 22rpx;
  color: #8A99B4;
  margin-bottom: 4rpx;
}

.ppm-amount__value {
  font-size: 48rpx;
  font-weight: 800;
  color: #FF6B35;
  font-family: 'DIN', 'Helvetica Neue', sans-serif;
}

.ppm-notice {
  width: 100%;
  padding: 12rpx 24rpx;
  margin-bottom: 20rpx;
  background: #FFF7ED;
  border-radius: 12rpx;
  border: 1rpx solid #FFEDD5;
  box-sizing: border-box;
}

.ppm-notice text {
  font-size: 22rpx;
  color: #C2410C;
  line-height: 1.5;
}

.ppm-input-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
  margin-bottom: 16rpx;
}

.ppm-code-box {
  display: flex;
  justify-content: center;
  gap: 8px;
}

.ppm-code-item {
  width: 36px;
  height: 40px;
  background: #FFFFFF;
  border: 1px solid #E2E8F0;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.ppm-code-item--focus {
  border-color: #FF6B35;
}

.ppm-code-item--filled {
  border-color: #1A202C;
}

.ppm-code-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #1A202C;
}

.ppm-code-cursor {
  width: 2px;
  height: 20px;
  background: #FF6B35;
  animation: ppm-blink 1s infinite;
}

@keyframes ppm-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

.ppm-hidden-input {
  position: fixed;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  z-index: -1;
}

.ppm-tips {
  margin-bottom: 32rpx;
}

.ppm-tips text {
  font-size: 22rpx;
  color: #8A99B4;
}

.ppm-buttons {
  display: flex;
  gap: 20rpx;
  width: 100%;
}

.ppm-btn {
  flex: 1;
  height: 80rpx;
  border-radius: 40rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28rpx;
  font-weight: 600;
  transition: all 0.2s ease;
}

.ppm-btn:active {
  transform: scale(0.96);
}

.ppm-btn--cancel {
  background: #F3F4F6;
  color: #6B7280;
}

.ppm-btn--confirm {
  background: linear-gradient(135deg, #FF6B35 0%, #FF8C5A 100%);
  color: #FFFFFF;
  box-shadow: 0 8rpx 20rpx rgba(255, 107, 53, 0.25);
}

.ppm-btn--disabled {
  opacity: 0.5;
}
</style>
