<script lang="ts" setup>
/**
 * 消息场景宿主：自定义弹层 + 按 type_code 挂载专属视图（彻底不走 VbenModal）
 */
import { computed, ref, watch } from 'vue';

import { getNoticeDetailApi } from '#/views/notice/api';
import { resolveNoticeView } from '#/views/notice/views/registry';

import { resolveNoticeSceneMeta } from './meta';
import NoticeSceneShell from './NoticeSceneShell.vue';

const props = defineProps<{
  notice: null | Record<string, any>;
  onOpenBizAudit?: (payload: { bizId: number; typeCode: string; }) => void;
  onWithdrawAudit?: (payload: { bizId: number; modalType: number }) => void;
}>();

const emit = defineEmits<{
  close: [];
}>();

const open = defineModel<boolean>('open', { default: false });

const loading = ref(false);
const detail = ref<Record<string, any>>({});

const merged = computed(() => ({
  ...(props.notice || {}),
  ...detail.value,
}));

/**
 * 有效类型编码：决定用哪套场景 meta 与视图
 * 特殊处理：人工群发的个人日报/周报是富文本，但旧 type=2 被后端映射成
 * period_report；只有自动运营总结才带 action_payload.metrics，
 * 没有 metrics 的一律降级按富文本（system）渲染，避免显示一堆 0 的「运营总结」
 */
const effectiveTypeCode = computed(() => {
  const code = String(merged.value?.type_code || '');
  if (code === 'period_report' && !merged.value?.action_payload?.metrics) {
    return 'system';
  }
  return code;
});

const meta = computed(() => resolveNoticeSceneMeta(effectiveTypeCode.value));

const sceneTitle = computed(() => {
  const t = meta.value.title;
  const noticeTitle = String(merged.value?.title || '');
  // VIP / 富文本用消息标题更贴切
  const code = effectiveTypeCode.value;
  if (code === 'system' || code === 'broadcast' || code === 'vip') {
    return noticeTitle || t;
  }
  return t;
});

const ViewComp = computed(() => resolveNoticeView(effectiveTypeCode.value));

watch(
  () => [open.value, props.notice?.id] as const,
  async ([isOpen, id]) => {
    if (!isOpen) {
      detail.value = {};
      loading.value = false;
      return;
    }
    detail.value = {};
    const nid = Number(id || 0);
    if (nid <= 0) return;
    loading.value = true;
    try {
      const res = await getNoticeDetailApi(nid);
      detail.value = res || {};
    } catch {
      detail.value = {};
    } finally {
      loading.value = false;
    }
  },
);

function close() {
  open.value = false;
  emit('close');
}

function onViewAudit(modalType?: number) {
  const typeCode = String(merged.value?.type_code || '');
  const bizId = Number(merged.value?.action_payload?.biz_id || 0);
  if (typeCode === 'withdraw_audit') {
    props.onWithdrawAudit?.({
      bizId,
      modalType: typeof modalType === 'number' ? modalType : 0,
    });
    close();
    return;
  }
  props.onOpenBizAudit?.({ typeCode, bizId });
  close();
}

function onViewDone() {
  close();
}
</script>

<template>
  <NoticeSceneShell
    v-model:open="open"
    :title="sceneTitle"
    :kicker="meta.kicker"
    :tone="meta.tone"
    :size="meta.size"
    :bare-header="!!meta.bareHeader"
    @close="emit('close')"
  >
    <div v-if="loading" class="loading">加载消息内容…</div>
    <component
      :is="ViewComp"
      v-else-if="merged.id || merged.title"
      :notice="merged"
      @audit="onViewAudit"
      @done="onViewDone"
    />
  </NoticeSceneShell>
</template>

<style scoped>
.loading {
  padding: 48px 0;
  text-align: center;
  color: hsl(var(--muted-foreground));
  font-size: 14px;
}
</style>
