<script lang="ts" setup>
/**
 * OA 测试发送手机号输入 + 记忆选择器（任务 5）
 *
 * 用途：场景测试发送（Step 3）每个平台一行需要输入 @ 手机号列表，
 *       本组件把"输入 + 常用快速选择 + 后端记忆"三件事打包成一个独立组件。
 *
 * 特性：
 * - 顶部 Input tags 模式，回车 / 逗号 / 空格都能添加手机号
 * - 输入框下方展示常用手机号快速选择标签（最多 8 个）
 *   - 前 3 个使用_count 最高的标为常用色（蓝），其余灰色
 *   - 点击标签立即添加到选中列表（去重），并后台 record 一次（提升常用度）
 * - 选中手机号后自动调用 record API 记忆，下次常用排序更靠前
 * - 当 platform_code 切换时自动重新拉取记忆列表
 * - 删除单条记忆：标签上 hover 出现 ×（用户主动清除）
 *
 * Props：
 * - platformCode：必填，平台编码（按平台维度隔离记忆库）
 * - modelValue：string[]，当前选中的手机号列表（双向绑定）
 *
 * 复用：
 * - 任务 3 form-page.vue Step 3 每个启用平台一行用本组件
 * - 后续机器人管理页测试发送也可复用
 */

import { computed, onMounted, ref, watch } from 'vue';

import { CloseOutlined } from '@ant-design/icons-vue';
import { Input, Spin, Tag, message } from 'ant-design-vue';

import {
  deleteOaTestPhone,
  getOaTestPhones,
  recordOaTestPhone,
  type OaTestPhoneItem,
} from '#/views/system/oa-scene/api';

interface Props {
  /** 平台编码（按平台维度隔离记忆库） */
  platformCode: string;
  /** 当前选中的手机号列表 */
  modelValue?: string[];
  /** 占位符 */
  placeholder?: string;
  /** 是否禁用（例如飞书 webhook 不支持手机号 @，外层可禁用） */
  disabled?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  placeholder: '输入手机号回车添加，可多选',
  disabled: false,
});

const emit = defineEmits<{
  (e: 'update:modelValue', v: string[]): void;
  (e: 'recorded', phone: string): void;
}>();

/* ----------------- 内部状态 ----------------- */

/** 后端拉取的记忆库列表（按 use_count DESC 已排序） */
const memoryList = ref<OaTestPhoneItem[]>([]);

/** 加载状态 */
const loading = ref(false);

/** Input tags 模式的当前值（受控） */
const inputValue = computed<string[]>({
  get: () => props.modelValue,
  set: (v) => emit('update:modelValue', v),
});

/* ----------------- 数据加载 ----------------- */

async function loadMemory() {
  if (!props.platformCode) {
    memoryList.value = [];
    return;
  }
  loading.value = true;
  try {
    const res: any = await getOaTestPhones(props.platformCode);
    const list = res?.data ?? res ?? [];
    memoryList.value = Array.isArray(list) ? list : [];
  } catch (e) {
    console.error('phone-memory-picker loadMemory error', e);
    memoryList.value = [];
  } finally {
    loading.value = false;
  }
}

onMounted(loadMemory);
watch(() => props.platformCode, loadMemory);

/* ----------------- 标签快捷选择 ----------------- */

/** 展示前 8 个常用手机号（去除当前已选） */
const quickList = computed(() => {
  const selected = new Set(props.modelValue.map((p) => p.trim()));
  return memoryList.value
    .filter((item) => item.phone && !selected.has(item.phone))
    .slice(0, 8);
});

/** 前 3 个标为常用色 */
function isTopItem(index: number): boolean {
  return index < 3;
}

/** 点击快捷标签 → 加入 modelValue，并后台 record */
async function pickFromMemory(item: OaTestPhoneItem) {
  if (props.disabled) return;
  const phone = item.phone.trim();
  if (!phone) return;
  // 去重
  if (props.modelValue.includes(phone)) return;
  emit('update:modelValue', [...props.modelValue, phone]);
  // 后台 record，不阻塞 UI（失败也不影响主流程）
  try {
    await recordOaTestPhone({
      platform_code: props.platformCode,
      phone,
      name: item.name || '',
    });
    emit('recorded', phone);
    // 静默刷新（更新排序）
    loadMemory();
  } catch (e) {
    console.warn('recordOaTestPhone failed', e);
  }
}

/* ----------------- Input tags 添加手机号 ----------------- */

/** 输入新值时的处理（tags 模式 antd Input 不支持，用回车手动添加） */
function handleInputConfirm(e: Event) {
  const target = e.target as HTMLInputElement;
  const raw = target.value || '';
  // 支持一次粘贴多个：逗号 / 空格 / 换行分隔
  const phones = raw
    .split(/[\s,，]+/)
    .map((s) => s.trim())
    .filter((s) => s !== '');
  if (phones.length === 0) return;
  // 简单校验：11 位数字；非法的提示但不阻塞合法的
  const validPhones: string[] = [];
  for (const p of phones) {
    if (!/^1\d{10}$/.test(p)) {
      message.warning(`「${p}」不是有效手机号，已忽略`);
      continue;
    }
    if (!props.modelValue.includes(p)) {
      validPhones.push(p);
    }
  }
  if (validPhones.length > 0) {
    emit('update:modelValue', [...props.modelValue, ...validPhones]);
    // 后台批量记忆
    validPhones.forEach((phone) => {
      recordOaTestPhone({ platform_code: props.platformCode, phone }).catch(
        console.warn,
      );
    });
    setTimeout(loadMemory, 200);
  }
  // 清空输入框
  target.value = '';
}

/* ----------------- 移除选中的手机号 ----------------- */

function removePhone(phone: string) {
  emit(
    'update:modelValue',
    props.modelValue.filter((p) => p !== phone),
  );
}

/* ----------------- 删除单条记忆（用户主动清除历史） ----------------- */

async function removeMemory(item: OaTestPhoneItem, e: Event) {
  e.stopPropagation();
  try {
    await deleteOaTestPhone(item.id);
    message.success('已删除');
    memoryList.value = memoryList.value.filter((m) => m.id !== item.id);
  } catch (e) {
    console.error(e);
    message.error('删除失败');
  }
}
</script>

<template>
  <div class="phone-memory-picker">
    <!-- 已选手机号标签展示（带 × 关闭） -->
    <div v-if="modelValue.length" class="picked-tags">
      <Tag
        v-for="phone in modelValue"
        :key="phone"
        closable
        :disabled="disabled"
        @close="removePhone(phone)"
      >
        {{ phone }}
      </Tag>
    </div>

    <!-- 输入框（回车确认 / 粘贴多个） -->
    <Input
      :placeholder="placeholder"
      :disabled="disabled"
      allow-clear
      class="phone-input"
      @keydown.enter="handleInputConfirm"
      @blur="handleInputConfirm"
    />

    <!-- 常用快速选择标签 -->
    <Spin :spinning="loading" size="small">
      <div v-if="quickList.length" class="quick-tags">
        <span class="quick-title">常用：</span>
        <Tag
          v-for="(item, i) in quickList"
          :key="item.id"
          :color="isTopItem(i) ? 'blue' : 'default'"
          class="quick-tag"
          @click="pickFromMemory(item)"
        >
          <span>{{ item.name ? `${item.name}（${item.phone}）` : item.phone }}</span>
          <span class="count">·{{ item.use_count }}</span>
          <CloseOutlined
            v-if="!disabled"
            class="del-icon"
            @click="removeMemory(item, $event)"
          />
        </Tag>
      </div>
      <div v-else-if="!loading && !modelValue.length" class="empty-tip">
        输入手机号后会自动记忆，下次快速选择
      </div>
    </Spin>
  </div>
</template>

<style scoped lang="scss">
.phone-memory-picker {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.picked-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.phone-input {
  width: 100%;
}

.quick-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}

.quick-title {
  font-size: 12px;
  color: var(--ant-color-text-tertiary, #86909c);
  margin-right: 4px;
}

.quick-tag {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: transform 0.1s;

  &:hover {
    transform: translateY(-1px);
  }

  .count {
    color: var(--ant-color-text-tertiary, #86909c);
    font-size: 11px;
  }

  .del-icon {
    font-size: 10px;
    color: var(--ant-color-text-tertiary, #86909c);
    margin-left: 2px;

    &:hover {
      color: var(--ant-color-error, #f5222d);
    }
  }
}

.empty-tip {
  font-size: 12px;
  color: var(--ant-color-text-tertiary, #86909c);
  font-style: italic;
}
</style>
