<script lang="ts" setup>
/**
 * 企微应用 API 场景投递目标面板
 * 个人目标：从已同步的企微组织架构（xk_oa_ww_user）选成员，存 userid
 * 群目标：多选群 + 客户群确认发送人 + 每群 @
 */
import { computed, onMounted, ref, watch } from 'vue';

import {
  Button,
  Collapse,
  CollapsePanel,
  Select,
  Tag,
  message,
} from 'ant-design-vue';

import UserTagSelect from '#/components/form/components/user-tag-select.vue';
import { getOaChatListByPlatform } from '#/views/system/oa-chat/api';
import { getOaWwUserList } from '#/views/system/oa-chat/api/org';

export interface SceneTargetItem {
  target_type: 1 | 2;
  platform_code: string;
  /** 个人目标：企微 userid（优先） */
  userid?: string;
  /** 兼容旧数据 / 匹配到系统员工时回填 */
  admin_id?: number;
  chat_id?: number;
  at_admin_ids?: number[];
  at_userids?: string[];
  /** 客户群群发确认人 userid */
  sender_userid?: string;
}

const props = defineProps<{
  modelValue: SceneTargetItem[];
  /** 系统员工列表（群 @ 手机号用） */
  adminList: Array<{ id: number; name: string; avatar?: string }>;
  platformCode?: string;
}>();

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

const platformCode = computed(() => props.platformCode || 'work_wechat_app');

/** 该平台下的群聊选项 */
const chatOptions = ref<
  Array<{
    id: number;
    name: string;
    chat_kind: number;
    external_id: string;
  }>
>([]);

/** 企微组织架构成员：选项 + userid→matched_admin_id */
const wwUserOptions = ref<{ label: string; value: string }[]>([]);
const wwUserAdminMap = ref<Record<string, number>>({});
const wwUsersLoaded = ref(false);

/**
 * 个人目标选中的 userid 列表（与 modelValue 双向同步）
 */
const personUserids = computed({
  get() {
    return props.modelValue
      .filter((t) => t.target_type === 1)
      .map((t) => String(t.userid || '').trim())
      .filter((u) => u !== '');
  },
  set(ids: string[]) {
    rebuild(ids, groupChatIds.value);
  },
});

const groupChatIds = computed({
  get() {
    return props.modelValue
      .filter((t) => t.target_type === 2 && (t.chat_id || 0) > 0)
      .map((t) => Number(t.chat_id));
  },
  set(ids: number[]) {
    rebuild(personUserids.value, ids);
  },
});

/** 旧数据仅有 admin_id、无 userid 时的提示标记 */
const orphanPersonAdminIds = computed(() =>
  props.modelValue
    .filter(
      (t) =>
        t.target_type === 1 &&
        !String(t.userid || '').trim() &&
        (t.admin_id || 0) > 0,
    )
    .map((t) => Number(t.admin_id)),
);

/** 按 chat_id 取群目标行（含 @ / 确认人配置） */
function groupTargetOf(chatId: number): SceneTargetItem {
  return (
    props.modelValue.find(
      (t) => t.target_type === 2 && Number(t.chat_id) === chatId,
    ) || {
      target_type: 2,
      platform_code: platformCode.value,
      chat_id: chatId,
      at_admin_ids: [],
      at_userids: [],
      sender_userid: '',
    }
  );
}

function chatMeta(chatId: number) {
  return chatOptions.value.find((c) => c.id === chatId);
}

/**
 * 重建 targets：个人按 userid；保留已有群的 @ / sender
 */
function rebuild(userids: string[], chatIds: number[]) {
  const next: SceneTargetItem[] = [];
  const uniq = [...new Set(userids.map((u) => String(u).trim()).filter(Boolean))];
  for (const userid of uniq) {
    const matchedAdminId = wwUserAdminMap.value[userid] || 0;
    // 保留详情回显时已有的 admin_id（若组织列表尚未匹配到）
    const prev = props.modelValue.find(
      (t) => t.target_type === 1 && String(t.userid || '') === userid,
    );
    next.push({
      target_type: 1,
      platform_code: platformCode.value,
      userid,
      admin_id: matchedAdminId || prev?.admin_id || 0,
    });
  }
  for (const chatId of chatIds) {
    const prev = groupTargetOf(chatId);
    next.push({
      target_type: 2,
      platform_code: platformCode.value,
      chat_id: chatId,
      at_admin_ids: [...(prev.at_admin_ids || [])],
      at_userids: [...(prev.at_userids || [])],
      sender_userid: prev.sender_userid || '',
    });
  }
  emit('update:modelValue', next);
}

function updateGroupAt(
  chatId: number,
  patch: {
    at_admin_ids?: number[];
    at_userids?: string[];
    sender_userid?: string;
  },
) {
  const next = props.modelValue.map((t) => {
    if (t.target_type !== 2 || Number(t.chat_id) !== chatId) return t;
    return {
      ...t,
      at_admin_ids: patch.at_admin_ids ?? t.at_admin_ids ?? [],
      at_userids: patch.at_userids ?? t.at_userids ?? [],
      sender_userid:
        patch.sender_userid !== undefined
          ? patch.sender_userid
          : t.sender_userid || '',
    };
  });
  emit('update:modelValue', next);
}

/**
 * 保存前校验：任一客户群缺确认发送员工则拦截
 * @returns 错误文案，通过返回空串
 */
function validateBeforeSubmit(): string {
  for (const chatId of groupChatIds.value) {
    const meta = chatMeta(chatId);
    if (Number(meta?.chat_kind) !== 2) continue;
    const sender = String(groupTargetOf(chatId).sender_userid || '').trim();
    if (!sender) {
      return `客户群「${meta?.name || chatId}」请选择确认发送员工`;
    }
  }
  return '';
}

defineExpose({ validateBeforeSubmit });

async function loadChats() {
  try {
    const res = await getOaChatListByPlatform();
    const grouped = res?.data ?? res ?? {};
    const list = grouped[platformCode.value] || [];
    chatOptions.value = (Array.isArray(list) ? list : []).map((c: any) => ({
      id: Number(c.id),
      name: String(c.name || ''),
      chat_kind: Number(c.chat_kind ?? 2),
      external_id: String(c.external_id || ''),
    }));
  } catch (e) {
    console.error(e);
    message.error('加载群聊列表失败');
  }
}

async function loadWwUsers() {
  try {
    const userRes = await getOaWwUserList({
      platform_code: platformCode.value,
      page: 1,
      pageSize: 500,
    });
    const userData = userRes?.data ?? userRes ?? {};
    const items = Array.isArray(userData.items) ? userData.items : [];
    const adminMap: Record<string, number> = {};
    wwUserOptions.value = items.map((u: any) => {
      const userid = String(u.userid || '');
      const matched = Number(u.matched_admin_id || 0);
      if (userid && matched > 0) {
        adminMap[userid] = matched;
      }
      return {
        label: u.name ? `${u.name}（${userid}）` : userid,
        value: userid,
      };
    });
    wwUserAdminMap.value = adminMap;
    wwUsersLoaded.value = true;
  } catch (e) {
    console.error(e);
    wwUserOptions.value = [];
    wwUserAdminMap.value = {};
    wwUsersLoaded.value = true;
  }
}

onMounted(() => {
  loadChats();
  loadWwUsers();
});
watch(platformCode, () => {
  loadChats();
  loadWwUsers();
});

/** 系统员工 → UserTagSelect 选项（群 @ 手机号） */
const adminTagOptions = computed(() =>
  props.adminList.map((a) => ({
    value: a.id,
    label: a.name,
    avatar: a.avatar || '',
  })),
);

/** 群聊 → UserTagSelect 选项 */
const chatTagOptions = computed(() =>
  chatOptions.value.map((c) => ({
    value: c.id,
    label: `${c.name}${c.chat_kind === 2 ? '（客户群·需确认）' : '（应用群）'}`,
    avatar: '',
  })),
);
</script>

<template>
  <div class="scene-targets-panel">
    <div class="mb-3 text-xs text-gray-500">
      同一场景可同时选人、多群；客户群发送为群发任务，需指定确认员工并在企微客户端确认（非实时）
    </div>

    <!-- 发送给个人：企微组织架构成员（userid） -->
    <div class="mb-4">
      <div class="section-title">发送给个人</div>
      <Select
        mode="multiple"
        show-search
        allow-clear
        class="w-full"
        placeholder="从企微组织架构选择成员（可多选）"
        :value="personUserids"
        :options="wwUserOptions"
        :filter-option="
          (input: string, option: any) =>
            String(option?.label || '')
              .toLowerCase()
              .includes(input.toLowerCase())
        "
        :max-tag-count="6"
        @change="(v: string[]) => (personUserids = v || [])"
      />
      <div
        v-if="wwUsersLoaded && wwUserOptions.length === 0"
        class="mt-1 text-xs text-orange-500"
      >
        请先在 OA 群聊 → 员工 Tab 同步组织架构
      </div>
      <div
        v-if="orphanPersonAdminIds.length > 0"
        class="mt-1 text-xs text-orange-500"
      >
        存在仅绑定系统员工、未选企微成员的旧目标（admin_id:
        {{ orphanPersonAdminIds.join('、') }}），请重新从组织架构选择成员
      </div>
    </div>

    <!-- 发送给群：UserTagSelect 多选 -->
    <div class="mb-2">
      <div class="section-title">发送给群</div>
      <UserTagSelect
        v-model="groupChatIds"
        :options="chatTagOptions"
        :max-count="99"
        placeholder="选择群聊（可多选）"
      />
    </div>

    <Collapse v-if="groupChatIds.length > 0" ghost>
      <CollapsePanel
        v-for="chatId in groupChatIds"
        :key="chatId"
        :header="chatMeta(chatId)?.name || `群#${chatId}`"
      >
        <template #extra>
          <Tag
            :color="chatMeta(chatId)?.chat_kind === 1 ? 'blue' : 'orange'"
            @click.stop
          >
            {{
              chatMeta(chatId)?.chat_kind === 1
                ? '应用群·实时'
                : '客户群·需确认'
            }}
          </Tag>
        </template>

        <!-- 仅客户群：确认发送员工必填 -->
        <div
          v-if="chatMeta(chatId)?.chat_kind === 2"
          class="mb-3"
        >
          <div class="mb-1 text-xs">
            确认发送员工 <span class="text-red-500">*</span>
          </div>
          <Select
            show-search
            allow-clear
            class="w-full"
            placeholder="选择在企微客户端确认群发的员工 userid"
            :value="groupTargetOf(chatId).sender_userid || undefined"
            :options="wwUserOptions"
            :filter-option="
              (input: string, option: any) =>
                String(option?.label || '')
                  .toLowerCase()
                  .includes(input.toLowerCase())
            "
            @change="
              (v: string) => updateGroupAt(chatId, { sender_userid: v || '' })
            "
          />
          <div class="mt-1 text-xs text-gray-400">
            对应企微 add_msg_template.sender，该员工需在客户端点确认后消息才会发出
          </div>
        </div>

        <div class="mb-2 text-xs text-gray-500">本群 @ 配置</div>
        <div class="mb-2">
          <div class="mb-1 text-xs">@ 系统员工（手机号）</div>
          <UserTagSelect
            :model-value="groupTargetOf(chatId).at_admin_ids || []"
            :options="adminTagOptions"
            placeholder="选择要 @ 的员工"
            @update:model-value="
              (v: (string | number)[]) =>
                updateGroupAt(chatId, {
                  at_admin_ids: v.map((n) => Number(n)).filter((n) => n > 0),
                })
            "
          />
        </div>
        <div>
          <div class="mb-1 text-xs">@ 群成员 userid</div>
          <Select
            mode="multiple"
            show-search
            class="w-full"
            placeholder="从组织架构选择或输入 userid"
            :options="wwUserOptions"
            :filter-option="
              (input: string, option: any) =>
                String(option?.label || '')
                  .toLowerCase()
                  .includes(input.toLowerCase())
            "
            :value="groupTargetOf(chatId).at_userids || []"
            @change="
              (v: string[]) => updateGroupAt(chatId, { at_userids: v || [] })
            "
          />
        </div>
      </CollapsePanel>
    </Collapse>

    <Button
      v-if="chatOptions.length === 0"
      type="link"
      size="small"
      class="px-0"
      @click="loadChats"
    >
      刷新群聊列表
    </Button>
  </div>
</template>

<style scoped>
.section-title {
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ant-color-text, #1d2129);
}
</style>
