<script setup lang="ts">
import { ref } from 'vue'

const props = defineProps<{
  modelValue?: string
  type?: string
  placeholder?: string
  label?: string
  error?: string
  disabled?: boolean
  /** 右侧插槽宽度（用于验证码按钮） */
  suffix?: boolean
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const showPassword = ref(false)

const inputType = () => {
  if (props.type === 'password') return showPassword.value ? 'text' : 'password'
  return props.type ?? 'text'
}
</script>

<template>
  <div class="app-input" :class="{ 'has-error': error, 'has-suffix': suffix || type === 'password' }">
    <label v-if="label" class="app-input__label">{{ label }}</label>

    <div class="app-input__wrapper">
      <input
        class="app-input__field"
        :type="inputType()"
        :value="modelValue"
        :placeholder="placeholder"
        :disabled="disabled"
        @input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
      />

      <!-- 密码显示/隐藏 -->
      <button
        v-if="type === 'password'"
        type="button"
        class="app-input__eye"
        @click="showPassword = !showPassword"
      >
        <svg v-if="showPassword" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
          <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
          <circle cx="12" cy="12" r="3"/>
        </svg>
        <svg v-else width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
          <path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/>
          <line x1="1" y1="1" x2="23" y2="23"/>
        </svg>
      </button>

      <!-- 右侧插槽（如验证码按钮） -->
      <div v-else-if="suffix" class="app-input__suffix">
        <slot name="suffix" />
      </div>
    </div>

    <p v-if="error" class="app-input__error">{{ error }}</p>
  </div>
</template>

<style scoped>
.app-input { display: flex; flex-direction: column; gap: var(--space-2); }

.app-input__label {
  font-size: var(--text-small);
  color: var(--color-text-secondary);
}

.app-input__wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.app-input__field {
  width: 100%;
  height: 52px;
  padding: 0 var(--space-4);
  background: var(--color-bg-input);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text-primary);
  font-size: var(--text-body);
  transition: border-color var(--transition);
}
.app-input__field::placeholder { color: var(--color-text-muted); }
.app-input__field:focus { border-color: var(--color-border-focus); }
.app-input__field:disabled { opacity: 0.5; cursor: not-allowed; }

.has-suffix .app-input__field,
.app-input:has(.app-input__eye) .app-input__field {
  padding-right: 48px;
}

.app-input__eye {
  position: absolute;
  right: var(--space-4);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  transition: color var(--transition);
}
.app-input__eye:hover { color: var(--color-text-secondary); }

.app-input__suffix {
  position: absolute;
  right: 0;
  height: 100%;
  display: flex;
  align-items: center;
  padding-right: var(--space-2);
}

.has-error .app-input__field { border-color: var(--color-down); }
.app-input__error {
  font-size: var(--text-caption);
  color: var(--color-down);
}
</style>
