<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { ComponentSubmission } from '../types/resumeAgent'
import {
  booleanValue,
  initialValue,
  optionList,
  stringValue,
} from '../utils/componentData'
import FormCard from './shared/FormCard.vue'

const props = withDefaults(
  defineProps<{
    data: Record<string, unknown>
    value?: unknown
    readOnly?: boolean
    pending?: boolean
    inputOnly?: boolean
  }>(),
  { value: undefined, readOnly: false, pending: false, inputOnly: false },
)

const emit = defineEmits<{ submit: [submission: ComponentSubmission] }>()
const accountOptions = computed(() => {
  if (props.inputOnly) return []
  const explicit = optionList(props.data.options ?? props.data.phones ?? props.data.choices)
  if (explicit.length) return explicit
  return [
    ...(booleanValue(props.data.has_account_phone)
      ? [{
          value: 'account',
          label: stringValue(props.data.masked_phone, '使用登录手机号'),
          description: '将登录手机号作为简历联系电话',
        }]
      : []),
    { value: 'manual', label: '输入其他手机号', description: '仅校验格式，不发送验证码' },
  ]
})
const sourceValue = computed(() =>
  typeof props.value === 'string' ? props.value : initialValue(props.data),
)
const selected = ref(sourceValue.value)
const manualPhone = ref(props.inputOnly ? sourceValue.value : '')
const validationError = ref('')

watch(sourceValue, (next) => {
  selected.value = next
  if (props.inputOnly) manualPhone.value = next
})

const resolvedValue = computed(() => (props.inputOnly ? manualPhone.value.trim() : selected.value))
const resolvedLabel = computed(
  () => accountOptions.value.find((option) => option.value === sourceValue.value)?.label || sourceValue.value,
)

function selectPhone(value: string) {
  selected.value = value
  validationError.value = ''
}

function submit() {
  if (!props.inputOnly) {
    if (!selected.value) {
      validationError.value = '请选择手机号来源。'
      return
    }
    const source = ['manual', 'other'].includes(selected.value) ? 'manual' : 'account'
    emit('submit', {
      event: 'select',
      payload: { value: source, source },
    })
    return
  }

  const phone = resolvedValue.value.trim()
  if (!/^1[3-9]\d{9}$/.test(phone)) {
    validationError.value = '手机号格式不正确，请检查后重试。'
    return
  }
  emit('submit', {
    event: 'submit',
    payload: { value: phone, phone },
  })
}
</script>

<template>
  <FormCard
    eyebrow="简历定位"
    :title="stringValue(data.title, inputOnly ? '输入其他简历手机号' : '选择简历联系电话')"
    :description="stringValue(data.description, '可以使用登录手机号，也可以填写其他中国大陆手机号。')"
    :read-only="readOnly"
    :pending="pending"
  >
    <div v-if="readOnly" class="read-only-value">{{ resolvedLabel || '手机号已记录' }}</div>
    <form v-else novalidate @submit.prevent="submit">
      <ul v-if="!inputOnly" class="phone-list">
        <li v-for="phone in accountOptions" :key="phone.value">
          <button
            class="phone-option"
            :class="{ 'phone-option--selected': selected === phone.value }"
            type="button"
            :disabled="pending || phone.disabled"
            :aria-pressed="selected === phone.value"
            @click="selectPhone(phone.value)"
          >
            <span class="phone-option__avatar" aria-hidden="true">{{ phone.label.slice(-2) }}</span>
            <span>
              <strong>{{ phone.label }}</strong>
              <small>{{ phone.description || '已有简历记录' }}</small>
            </span>
          </button>
        </li>
      </ul>

      <div v-if="inputOnly" class="field-group">
        <label class="field-label" for="resume-phone">手机号</label>
        <input
          id="resume-phone"
          v-model="manualPhone"
          class="text-input"
          type="tel"
          inputmode="tel"
          autocomplete="tel"
          :placeholder="stringValue(data.placeholder, '例如：13800138000')"
          :disabled="pending"
          :aria-invalid="Boolean(validationError)"
          aria-describedby="resume-phone-help resume-phone-error"
          @input="validationError = ''"
        />
        <p id="resume-phone-help" class="field-hint">仅校验 11 位中国大陆手机号格式，不发送验证码。</p>
        <p v-if="validationError" id="resume-phone-error" class="validation-error" role="alert">
          {{ validationError }}
        </p>
      </div>

      <div class="component-actions">
        <button class="primary-button" type="submit" :disabled="!resolvedValue || pending">
          继续
        </button>
      </div>
    </form>
  </FormCard>
</template>

<style scoped>
.phone-list {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.phone-option {
  display: flex;
  width: 100%;
  min-height: 70px;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: 16px;
  color: var(--ink);
  background: #f9fcfb;
  text-align: left;
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}

.phone-option:hover:not(:disabled) {
  transform: translateY(-1px);
  border-color: #91cbc7;
}

.phone-option--selected {
  border-color: var(--brand);
  background: var(--brand-soft);
}

.phone-option__avatar {
  display: grid;
  width: 42px;
  height: 42px;
  flex: none;
  place-items: center;
  border-radius: 13px;
  color: var(--brand-dark);
  background: #fff;
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  font-size: 11px;
  font-weight: 800;
}

.phone-option strong,
.phone-option small {
  display: block;
}

.phone-option strong {
  font-size: 14px;
}

.phone-option small {
  margin-top: 3px;
  color: var(--ink-faint);
  font-size: 11px;
}

.validation-error {
  margin: 0;
  color: var(--danger);
  font-size: 12px;
}
</style>
