<template>
  <view>
    <picker mode="selector" :range="displayRange" :disabled="disableChange" @change="onPick">
      <common-cell :name="name" :required="required">
        <view class="form-content__wrapper">
          <view class="flex-main-content truncate" :class="selectLabel ? '' : 'form__placeholder'">
            {{ selectLabel || placeholder }}
          </view>
          <uni-icons class="form-arrow" type="arrowright"></uni-icons>
        </view>
      </common-cell>
    </picker>

    <view v-if="showOther" class="other-row">
      <input
        :disabled="disableChange"
        :value="otherValue"
        class="other-input"
        placeholder="请输入补充内容"
        placeholder-class="form__placeholder"
        maxlength="50"
        @input="onOtherInput"
      />
    </view>
  </view>
</template>

<script setup>
import { computed } from 'vue';
import commonCell from '../common-cell.vue';

const emits = defineEmits(['change']);
const props = defineProps({
  form: { type: Object, default: () => ({}) },
  name: { default: '' },
  required: { type: Boolean, default: false },
  title: { default: '' },
  disableChange: { type: Boolean, default: false },
  range: { type: Array, default: () => [] },
  otherFiled: { type: String, default: '其他' },
});

function normalizeOptions(options) {
  if (!Array.isArray(options)) return [];
  if (!options.length) return [];
  if (typeof options[0] === 'string') return options.filter(Boolean).map((i) => ({ label: String(i), value: String(i) }));
  return options
    .map((i) => {
      const label = i?.label ?? i?.name ?? i?.text ?? i?.title ?? '';
      const value = i?.value ?? i?.id ?? i?.key ?? label;
      if (!label && (value === undefined || value === null || value === '')) return null;
      return { label: String(label || value), value: String(value) };
    })
    .filter(Boolean);
}

const options = computed(() => normalizeOptions(props.range));
const displayRange = computed(() => options.value.map((i) => i.label));
const placeholder = computed(() => `请选择${props.name || ''}`);

const rawValue = computed(() => {
  const v = props.form?.[props.title];
  return v === undefined || v === null ? '' : String(v);
});

const isOther = computed(() => {
  const v = String(rawValue.value || '');
  if (!v) return false;
  const known = new Set(options.value.map((i) => String(i.value)));
  return !known.has(v);
});

const showOther = computed(() => {
  const selected = selectLabel.value;
  return selected === props.otherFiled || isOther.value;
});

const selectLabel = computed(() => {
  const v = String(rawValue.value || '');
  if (!v) return '';
  const found = options.value.find((i) => String(i.value) === v);
  if (found) return found.label;
  return props.otherFiled;
});

const otherValue = computed(() => (isOther.value ? String(rawValue.value || '') : ''));

function onPick(e) {
  const idx = Number(e?.detail?.value || 0);
  const picked = options.value[idx];
  if (!picked) return;
  if (picked.label === props.otherFiled || String(picked.value) === String(props.otherFiled)) {
    emits('change', { title: props.title, value: '' });
    return;
  }
  emits('change', { title: props.title, value: picked.value });
}

function onOtherInput(e) {
  emits('change', { title: props.title, value: String(e?.detail?.value || '') });
}
</script>

<style lang="scss" scoped>
@import '../cell-style.css';

.other-row {
  padding: 0 30rpx 24rpx;
  border-bottom: 1px solid #eee;
  background: #fff;
}

.other-input {
  width: 100%;
  font-size: 30rpx;
  padding: 18rpx 20rpx;
  border: 1px solid #eee;
  border-radius: 8rpx;
  box-sizing: border-box;
}
</style>
