<script lang="ts" setup>
/**
 * OA 定时任务「消息配置」弹窗
 * 平台 Tab → 消息类型 Radio → 复用场景 PayloadSchemaForm（含 GalleryPickLink acceptTypes）
 * 保存 active_types + 各平台当前类型的 preset_payloads，物化到场景
 */
import { computed, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import { Alert, Radio, RadioGroup, Tabs, message } from 'ant-design-vue';

import {
  getOaCronTaskInfo,
  updateOaCronTask,
} from '#/views/system/oa-cron-task/api';
import { getOaPlatformList } from '#/views/system/oa-platform/api';
import { getOaMessageTypes } from '#/views/system/oa-scene/api';
import MsgPreview from '#/views/system/oa-scene/components/msg-preview.vue';
import PayloadSchemaForm, {
  type PayloadFieldSchema,
} from '#/views/system/oa-scene/components/payload-schema-form.vue';

interface MessageTypeOption {
  message_type: string;
  name: string;
  icon?: string;
  need_media?: number;
  payload_schema: string | null;
}

const gridApi = ref();
const loading = ref(false);
const detail = ref<Record<string, any>>({});
/** 各平台当前激活的消息类型 */
const activeTypes = ref<Record<string, string>>({});
/** presets[platform][type] = { payload, field_bindings } */
const presets = ref<Record<string, Record<string, any>>>({});
/** 本会话编辑中的 payload（按平台，对应当前 active 类型） */
const payloadByPlatform = ref<Record<string, Record<string, any>>>({});
const platforms = ref<
  Array<{ platform_code: string; name: string; icon?: string }>
>([]);
const activePlatform = ref('');
/** message-types 接口：platform → 类型列表（含 schema） */
const messageTypesMap = ref<Record<string, MessageTypeOption[]>>({});

/**
 * 当前平台可选消息类型：presets 已有类型 ∩ 接口返回类型
 */
function typeOptionsOf(platformCode: string) {
  const presetKeys = Object.keys(presets.value?.[platformCode] || {});
  const apiTypes = messageTypesMap.value[platformCode] || [];
  const nameMap = Object.fromEntries(
    apiTypes.map((t) => [t.message_type, t.name]),
  );
  return presetKeys.map((t) => ({
    label: nameMap[t] || t,
    value: t,
  }));
}

/**
 * 解析当前平台当前类型的 payload_schema
 */
function currentPayloadSchema(platformCode: string): PayloadFieldSchema[] {
  const messageType = activeTypes.value[platformCode];
  if (!messageType) return [];
  const types = messageTypesMap.value[platformCode] || [];
  const typeInfo = types.find((t) => t.message_type === messageType);
  if (!typeInfo?.payload_schema) return [];
  try {
    const parsed = JSON.parse(typeInfo.payload_schema);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

/** 当前类型 field_bindings 只读提示 */
const currentBindings = computed(() => {
  const p = activePlatform.value;
  const t = activeTypes.value[p] || '';
  const raw = presets.value?.[p]?.[t]?.field_bindings || {};
  return Object.entries(raw).map(([path, key]) => ({
    path: String(path),
    key: String(key),
  }));
});

/**
 * 切换消息类型：只改 active_types，并把编辑区切到该类型已有 payload（不丢其它类型 presets）
 */
function handleTypeChange(platformCode: string, messageType: string) {
  if (!platformCode || !messageType) return;
  // 先把当前编辑区写回 presets，避免切换丢改
  flushPayloadToPresets(platformCode);
  activeTypes.value = {
    ...activeTypes.value,
    [platformCode]: messageType,
  };
  const existing =
    presets.value?.[platformCode]?.[messageType]?.payload || {};
  payloadByPlatform.value = {
    ...payloadByPlatform.value,
    [platformCode]: { ...existing },
  };
}

/**
 * 把某平台编辑中的 payload 写回 presets[platform][activeType]
 */
function flushPayloadToPresets(platformCode: string) {
  const type = activeTypes.value[platformCode];
  if (!platformCode || !type) return;
  const payload = payloadByPlatform.value[platformCode] || {};
  const platformPresets = { ...(presets.value[platformCode] || {}) };
  const prev = { ...(platformPresets[type] || {}) };
  platformPresets[type] = {
    ...prev,
    payload: { ...payload },
  };
  presets.value = {
    ...presets.value,
    [platformCode]: platformPresets,
  };
}

/**
 * 打开时加载详情、平台、场景 message-types（含 payload_schema）
 */
async function loadAll(id: number) {
  loading.value = true;
  try {
    const [info, platformList, typesRes] = await Promise.all([
      getOaCronTaskInfo(id),
      getOaPlatformList(),
      getOaMessageTypes(),
    ]);
    detail.value = info || {};
    activeTypes.value = { ...(info?.active_types || {}) };
    presets.value = { ...(info?.presets || {}) };

    const typeMap =
      typesRes && typeof typesRes === 'object' && !Array.isArray(typesRes)
        ? typesRes
        : typesRes?.data || {};
    messageTypesMap.value = typeMap as Record<string, MessageTypeOption[]>;

    const rows = Array.isArray(platformList)
      ? platformList
      : platformList?.data || [];
    platforms.value = (Array.isArray(rows) ? rows : [])
      .filter((p: any) => info?.presets?.[p.platform_code])
      .map((p: any) => ({
        platform_code: p.platform_code,
        name: p.name,
        icon: p.icon,
      }));
    activePlatform.value = platforms.value[0]?.platform_code || '';

    // 初始化各平台编辑区为当前 active 类型的 payload
    const payloads: Record<string, Record<string, any>> = {};
    for (const p of platforms.value) {
      const code = p.platform_code;
      let type = activeTypes.value[code] || '';
      const presetKeys = Object.keys(presets.value[code] || {});
      if (!type || !presetKeys.includes(type)) {
        type = presetKeys[0] || '';
        if (type) {
          activeTypes.value = { ...activeTypes.value, [code]: type };
        }
      }
      payloads[code] = {
        ...(presets.value?.[code]?.[type]?.payload || {}),
      };
    }
    payloadByPlatform.value = payloads;
  } finally {
    loading.value = false;
  }
}

/**
 * 预览用 payload（template_card 需展开）
 */
function previewPayloadOf(platformCode: string): Record<string, any> {
  const messageType = activeTypes.value[platformCode];
  const payload = { ...(payloadByPlatform.value[platformCode] || {}) };
  if (messageType === 'template_card' && payload.template_card) {
    return payload.template_card;
  }
  return payload;
}

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  class: 'w-[920px]',
  onCancel() {
    modalApi.close();
  },
  onConfirm: async () => {
    const id = detail.value?.id;
    if (!id) return;
    // 提交前把当前 Tab 编辑区写回
    for (const p of platforms.value) {
      flushPayloadToPresets(p.platform_code);
    }
    const presetPayloads: Record<
      string,
      { message_type: string; payload: Record<string, any> }
    > = {};
    for (const p of platforms.value) {
      const code = p.platform_code;
      const type = activeTypes.value[code];
      if (!type) continue;
      presetPayloads[code] = {
        message_type: type,
        payload: {
          ...(presets.value?.[code]?.[type]?.payload ||
            payloadByPlatform.value[code] ||
            {}),
        },
      };
    }
    modalApi.setState({ loading: true, confirmLoading: true });
    try {
      await updateOaCronTask({
        id,
        active_types: activeTypes.value,
        preset_payloads: presetPayloads,
      });
      message.success('消息配置已保存');
      gridApi.value?.query?.();
      modalApi.close();
    } finally {
      modalApi.setState({ loading: false, confirmLoading: false });
    }
  },
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) return;
    const data = modalApi.getData<{ id?: number; gridApi?: any }>();
    gridApi.value = data?.gridApi;
    if (data?.id) {
      await loadAll(data.id);
    }
  },
});
</script>

<template>
  <Modal :title="`消息配置：${detail.name || ''}`">
    <div v-if="loading" class="py-8 text-center text-gray-400">加载中…</div>
    <div v-else class="cron-msg-config space-y-4">
      <Alert
        type="info"
        show-icon
        message="按平台选择消息类型并编辑发送内容（与 OA 场景同一套 payload_schema）。定时命令仍用 field_bindings 与 {var} 填充动态字段。"
      />

      <Tabs v-if="platforms.length" v-model:active-key="activePlatform" type="card">
        <Tabs.TabPane
          v-for="p in platforms"
          :key="p.platform_code"
          :tab="p.name"
        >
          <div class="mb-3">
            <div class="mb-2 text-sm text-gray-500">消息类型</div>
            <RadioGroup
              :value="activeTypes[p.platform_code]"
              button-style="solid"
              @update:value="(v) => handleTypeChange(p.platform_code, String(v))"
            >
              <Radio.Button
                v-for="opt in typeOptionsOf(p.platform_code)"
                :key="opt.value"
                :value="opt.value"
              >
                {{ opt.label }}
              </Radio.Button>
            </RadioGroup>
          </div>

          <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
            <div>
              <div class="mb-2 font-medium">发送内容</div>
              <PayloadSchemaForm
                :schema="currentPayloadSchema(p.platform_code)"
                :model-value="payloadByPlatform[p.platform_code] || {}"
                @update:model-value="
                  (v) => {
                    payloadByPlatform = {
                      ...payloadByPlatform,
                      [p.platform_code]: v || {},
                    };
                  }
                "
              />
            </div>
            <div>
              <div class="mb-2 font-medium">预览</div>
              <MsgPreview
                :platform-code="p.platform_code"
                :message-type="activeTypes[p.platform_code] || ''"
                :payload="previewPayloadOf(p.platform_code)"
              />
              <div class="mt-3">
                <div class="mb-1 text-sm font-medium">
                  可替换变量（field_bindings）
                </div>
                <div
                  v-if="
                    p.platform_code === activePlatform &&
                    currentBindings.length === 0
                  "
                  class="text-xs text-gray-400"
                >
                  当前类型无字段绑定
                </div>
                <ul
                  v-else-if="p.platform_code === activePlatform"
                  class="m-0 list-disc pl-4 text-xs text-gray-600"
                >
                  <li v-for="b in currentBindings" :key="b.path">
                    <code>{{ b.key }}</code>
                    ← {{ b.path.replace(/^.*\.payload\./, 'payload.') }}
                  </li>
                </ul>
                <div class="mt-1 text-xs text-gray-400">
                  payload 字符串中也可写
                  <code>{{ '{count}' }}</code>
                  /
                  <code>{{ '{content}' }}</code>
                  等模板，定时任务传对应 vars 即可替换
                </div>
              </div>
            </div>
          </div>
        </Tabs.TabPane>
      </Tabs>
      <div v-else class="py-6 text-center text-gray-400">
        当前任务暂无平台 presets，请先确认种子数据已写入
      </div>
    </div>
  </Modal>
</template>
