<template>
    <div class="auto-promo-container" v-loading="loading" :element-loading-text="$t('autoPromotion.loading')">
        <div class="page-header">
            <el-breadcrumb separator="/">
                <el-breadcrumb-item>
                    <i class="el-icon-s-promotion"></i> {{ $t('autoPromotion.title') }}
                    <el-button
                        type="text"
                        icon="el-icon-refresh"
                        class="auto-promo-refresh-btn"
                        :disabled="loading"
                        :title="$t('autoPromotion.refresh')"
                        @click="refreshAll"
                    />
                </el-breadcrumb-item>
            </el-breadcrumb>
            <div class="page-header-actions">
                <el-button
                    type="primary"
                    size="small"
                    @click="openFactoryTaskDialogForJournal(null)"
                >
                    {{ $t('autoPromotion.factoryCreateBtn') }}
                </el-button>
            </div>
        </div>

        <div class="journal-list-wrapper">
            <div v-for="journal in allJournals" :key="journal.journal_id" class="journal-group-section">
                <div class="journal-main-header">
                    <div class="journal-brand">
                        <div class="brand-icon">
                            <i class="el-icon-notebook-2"></i>
                        </div>
                        <h2 class="journal-title-text">{{ journal.title }}</h2>
                    </div>
                </div>

                <div v-if="getJournalDisplayTasks(journal).length" class="cards-grid">
                    <div
                        v-for="taskCard in getJournalDisplayTasks(journal)"
                        :key="taskCard.cardKey"
                        :class="['stat-card', taskCard.enabled ? 'is-active' : 'is-stopped']"
                    >
                        <div class="card-inner-header">
                            <div class="card-label-area">
                                <div class="card-main-title">
                                    {{ taskCard.typeLabel }}
                                    <!-- <span v-if="taskCard.showCount" class="scene-task-count">
                                        ({{ taskCard.totalCount }})
                                    </span> -->
                                    <el-button
                                        v-if="taskCard.initialized"
                                        type="text"
                                        size="mini"
                                        icon="el-icon-edit"
                                        class="config-inline-btn"
                                        @click="openFactoryTaskDialogForTask(journal, taskCard)"
                                    >
                                        {{ $t('autoPromotion.editConfig') }}
                                    </el-button>
                                </div>
                                <div class="status-tag">
                                    <span class="dot"></span>
                                    {{ taskCard.enabled ? $t('autoPromotion.running') : $t('autoPromotion.stopped') }}
                                </div>
                            </div>
                            <el-switch
                                :value="taskCard.enabled"
                                size="small"
                                active-color="#3DBB6A"
                                :disabled="!taskCard.taskId || !!taskCard.switchLoading"
                                @change="onFactoryTaskSwitchChange(journal, taskCard, $event)"
                            />
                        </div>

                        <div class="card-content">
                            <div class="template-preview-box">
                                <div class="meta-row">
                                    <i class="el-icon-message"
                                    ><span style="font-size: 11px; margin-left: 3px; margin-right: 3px">Template&nbsp;:</span></i
                                >
                                <span class="tpl-name tpl-name-single-line">{{ taskCard.templateName || 'No Template Configured' }}</span>
                                </div>
                                <div class="meta-row">
                                    <i class="el-icon-user"
                                    ><span style="font-size: 11px; margin-left: 3px; margin-right: 3px">Type&nbsp;:</span></i
                                >
                                <span class="tpl-name">{{ taskCard.expertTypeLabel || '-' }}</span>
                                </div>
                                
                                <!-- <div class="meta-row">
                                    <i class="el-icon-collection-tag"
                                    ><span style="font-size: 11px; margin-left: 3px; margin-right: 3px">Promotion Fields&nbsp;:</span></i
                                >
                                <span class="tpl-name">{{ taskCard.fieldCountText }}</span>
                                </div> -->
                               
                                <div class="meta-row" v-if="String(taskCard.expertType || '') === '5'">
                                    <i class="el-icon-location-outline"
                                    ><span style="font-size: 11px; margin-left: 3px; margin-right: 3px">Country&nbsp;:</span></i
                                >
                                <span class="tpl-name">{{ taskCard.countryScopeLabel || '-' }}</span>
                                </div>
                               
                            </div>

                            <!-- <div class="stats-container">
                                <div class="stat-box">
                                    <span class="stat-label">SENT</span>
                                    <span class="stat-value"><i class="el-icon-circle-check"></i> 1,240</span>
                                </div>
                                <div class="stat-box">
                                    <span class="stat-label">PENDING</span>
                                    <span class="stat-value warning"><i class="el-icon-time"></i> 150</span>
                                </div>
                            </div> -->
                        </div>

                        <div class="card-actions">
                           
                            <button class="action-main-btn" @click="handleFactoryTaskAction(journal, taskCard)">
                                <span
                                    v-if="
                                        promotionUpdating &&
                                        String(promotionUpdatingJournalId) === String(journal.journal_id) &&
                                        String(promotionUpdatingTaskId) === String(taskCard.taskId || '')
                                    "
                                >
                                    <i class="el-icon-loading"></i>
                                </span>
                                <span v-else>{{ getFactoryTaskActionText(taskCard) }}</span>
                            </button>
                            <div class="task-card-footer-row">
                                <button
                                    v-if="!taskCard.enabled && taskCard.taskId"
                                    type="button"
                                    class="promo-history-link"
                                    @click.stop="openDetail(journal, taskCard)"
                                >
                                    <span>{{ $t('autoPromotion.logs') }}</span>
                                    <i class="el-icon-document"></i>
                                </button>
                                <span v-else class="promo-history-spacer"></span>
                                <div v-if="taskCard.createdAtText" class="task-create-time">
                                    {{ $t('autoPromotion.createdAt') }}: {{ taskCard.createdAtText }}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div v-else class="no-task-tip">
                    <span>{{ $t('autoPromotion.noFactoryTask') }}</span>
                    <el-button type="text" size="mini" class="no-task-create-btn" @click="openFactoryTaskDialogForJournal(journal)">
                        <i class="el-icon-plus"></i>
                        {{ $t('autoPromotion.factoryCreateNow') }}
                    </el-button>
                </div>
            </div>
        </div>

        <journal-detail-dialog v-if="detailVisible" :visible.sync="detailVisible" :journal="currentJournal" />

        <auto-promotion-wizard
            mode="dialog"
            :visible.sync="showWizardDialog"
            :config="wizardConfig"
            :wizardStartDate.sync="wizardStartDate"
            :selectedFieldIds.sync="selectedFieldIds"
            :selectedCountryIds.sync="selectedCountryIds"
            :availableFields="availableFields"
            :availableCountries="availableCountries"
            :fieldsLoading="fieldsLoading"
            :fieldsSaving="fieldsSaving"
            :currentJournalName="wizardJournal ? wizardJournal.title : ''"
            :selectedTemplateThumbHtml="selectedTemplateThumbHtml"
            :selectedTemplateName="selectedTemplateName"
            :selectedStyleName="selectedStyleName"
            :saving="saving"
            :title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
            @open-template-selector="openTemplateSelector"
            @confirm-fields="savePromotionFieldsNow"
            @confirm-countries="savePromotionCountriesNow"
            @cancel="showWizardDialog = false"
            @confirm="saveWizardConfig"
        />

        <template-selector-dialog
            v-if="showTemplateDialog"
            :visible.sync="showTemplateDialog"
            :journalId="wizardJournal ? wizardJournal.journal_id : ''"
            :journalLabel="wizardJournal ? wizardJournal.title : ''"
            :initial-style-id="templateDialogInitialStyleId"
            :initial-template-id="templateDialogInitialTemplateId"
            :return-source="'autoPromotion'"
            @confirm="handleTemplateApply"
            @close-all-dialogs="closeAllDialogs"
        />

        <promotion-factory-task-dialog
            :visible.sync="showFactoryTaskDialog"
            :initial-journal-id="factoryDialogInitialJournalId"
            :initial-task="factoryDialogInitialTask"
            :journal-options="allJournals"
            @success="refreshAll"
        />
    </div>
</template>

<script>
import JournalDetailDialog from './components/autoPromotion/JournalDetailDialog.vue';
import AutoPromotionWizard from './components/autoPromotion/AutoPromotionWizard.vue';
import PromotionFactoryTaskDialog from './components/autoPromotion/PromotionFactoryTaskDialog.vue';
import TemplateSelectorDialog from '@/components/page/components/email/TemplateSelectorDialog.vue';

export default {
    components: { JournalDetailDialog, AutoPromotionWizard, PromotionFactoryTaskDialog, TemplateSelectorDialog },
    data() {
        return {
            loading: true,
            detailVisible: false,
            currentJournal: null,
            showWizardDialog: false,
            showTemplateDialog: false,
            saving: false,
            promotionUpdating: false,
            promotionUpdatingJournalId: '',
            promotionUpdatingTaskId: '',
            wizardJournal: null,
            wizardStartDate: '',
            wizardConfig: {
                defaultTemplateId: '',
                defaultStyleId: '',
                enabled: false
            },
            selectedTemplateThumbHtml: '',
            selectedTemplateName: '',
            selectedStyleName: '',
            selectedFieldIds: [],
            selectedCountryIds: [],
            availableFields: [],
            availableCountries: [],
            fieldsLoading: false,
            fieldsSaving: false,
            templateDialogInitialStyleId: '',
            templateDialogInitialTemplateId: '',
            templateNameMap: {},
            factoryTemplateNameMap: {},
            allJournals: [],
            showFactoryTaskDialog: false,
            factoryDialogInitialJournalId: '',
            factoryDialogInitialTask: null
        };
    },
    created() {
        this.fetchPromotionJournals();
    },
    methods: {
        savePromotionCountriesNow(){

        },
        // --- 逻辑部分完全保留你原有的实现 ---
        openTemplateSelector() {
            this.templateDialogInitialStyleId =
                this.wizardConfig && this.wizardConfig.defaultStyleId ? String(this.wizardConfig.defaultStyleId) : '';
            this.templateDialogInitialTemplateId =
                this.wizardConfig && this.wizardConfig.defaultTemplateId ? String(this.wizardConfig.defaultTemplateId) : '';
            this.showTemplateDialog = true;
        },
        closeAllDialogs() {
            this.showWizardDialog = false;
            this.showTemplateDialog = false;
            this.detailVisible = false;
        },
        openFactoryTaskDialogForTask(journal, taskCard) {
            this.factoryDialogInitialJournalId = journal && journal.journal_id != null ? String(journal.journal_id) : '';
            this.factoryDialogInitialTask = taskCard && taskCard.rawTask ? { ...taskCard.rawTask } : null;
            this.showFactoryTaskDialog = true;
        },
        openFactoryTaskDialogForJournal(journal) {
            this.factoryDialogInitialJournalId = journal && journal.journal_id != null ? String(journal.journal_id) : '';
            this.factoryDialogInitialTask = null;
            this.showFactoryTaskDialog = true;
        },
        async onFactoryTaskSwitchChange(journal, taskCard, nextEnabled) {
            const taskId =
                taskCard && taskCard.taskId
                    ? String(taskCard.taskId)
                    : taskCard && taskCard.rawTask && taskCard.rawTask.promotion_factory_id != null
                    ? String(taskCard.rawTask.promotion_factory_id)
                    : '';
            if (!taskId) return;
            this.$set(taskCard, 'switchLoading', true);
            try {
                const res = await this.$api.post('api/promotion_factory/changePromotionAct', {
                    promotion_factory_id: taskId,
                    start_promotion: nextEnabled ? '1' : '0'
                });
                if (res && Number(res.code) === 0) {
                    this.$set(taskCard, 'enabled', !!nextEnabled);
                    if (taskCard.rawTask) {
                        this.$set(taskCard.rawTask, 'state', nextEnabled ? '1' : '0');
                        this.$set(taskCard.rawTask, 'start_promotion', nextEnabled ? '1' : '0');
                    }
                    return;
                }
                this.$message.error((res && res.msg) || this.$t('autoPromotion.saveFailed'));
                await this.loadFactoryTaskSummaryByJournal(journal, localStorage.getItem('U_id') || '');
            } catch (e) {
                this.$message.error(this.$t('autoPromotion.saveFailed'));
                await this.loadFactoryTaskSummaryByJournal(journal, localStorage.getItem('U_id') || '');
            } finally {
                this.$set(taskCard, 'switchLoading', false);
            }
        },
        getFactoryTaskActionText(taskCard) {
            return taskCard && taskCard.enabled ? this.$t('autoPromotion.goManagePlan') : this.$t('autoPromotion.startPlan');
        },
        async handleFactoryTaskAction(journal, taskCard) {
            if (!journal || !taskCard) return;
            const taskId = taskCard.taskId != null ? String(taskCard.taskId) : '';
            this.promotionUpdating = true;
            this.promotionUpdatingJournalId = journal.journal_id;
            this.promotionUpdatingTaskId = taskId;
            try {
                if (!taskCard.enabled && taskId) {
                    const res = await this.$api.post('api/promotion_factory/changePromotionAct', {
                        promotion_factory_id: taskId,
                        start_promotion: '1'
                    });
                    if (!res || Number(res.code) !== 0) {
                        this.$message.error((res && res.msg) || this.$t('autoPromotion.saveFailed'));
                        return;
                    }
                    this.$set(taskCard, 'enabled', true);
                    if (taskCard.rawTask) {
                        this.$set(taskCard.rawTask, 'state', '1');
                        this.$set(taskCard.rawTask, 'start_promotion', '1');
                    }
                }
                this.openDetail(journal, taskCard);
            } finally {
                this.promotionUpdating = false;
                this.promotionUpdatingJournalId = '';
                this.promotionUpdatingTaskId = '';
            }
        },
        _parseJournalDetail(data) {
            const journalInfo = data.journal || data || {};
            const tpl = journalInfo.template || data.template || {};
            const style = journalInfo.style || data.style || {};
            const tplId = String(journalInfo.default_template_id || '0');
            const styleId = String(journalInfo.default_style_id || '0');
            return {
                title: journalInfo.title || journalInfo.journal_title || '',
                templateId: tplId,
                styleId: styleId,
                templateName: tpl.name || tpl.title || journalInfo.default_template_name || (tplId !== '0' ? `模板#${tplId}` : ''),
                styleName: style.name || style.title || journalInfo.default_style_name || (styleId !== '0' ? `风格#${styleId}` : ''),
                html: `${style.header_html || ''}${tpl.body_html || ''}${style.footer_html || ''}`,
                enabled: String(journalInfo.start_promotion || '0') === '1',
                initialized: tplId !== '0' && styleId !== '0'
            };
        },
        async fetchPromotionJournals() {
            this.loading = true;
            try {
                const username = localStorage.getItem('U_name') || '';
                const userId = localStorage.getItem('U_id') || '';
                const res = await this.$api.post('api/Article/getJournal', { username: username });
                let raw = [];
                if (res && Number(res.code) === 0 && res.data) {
                    if (Array.isArray(res.data.journals)) {
                        raw = res.data.journals;
                    } else if (Array.isArray(res.data)) {
                        raw = res.data;
                    }
                } else if (Array.isArray(res)) {
                    raw = res;
                }
                if (!Array.isArray(raw) || !raw.length) {
                    this.allJournals = [];
                    return;
                }
                const journalIdsForTpl = raw
                    .map((item) => item.journal_id || item.id)
                    .filter((id) => id != null && String(id).trim() !== '');
                await this.prefetchFactoryTemplateNameMapsOnce(journalIdsForTpl);
                this.allJournals = await Promise.all(
                    raw.map(async (item) => {
                        const journalId = item.journal_id || item.id;
                        let journalObj = {
                            journal_id: journalId,
                            abbr: item.abbr || '',
                            journal_icon: item.journal_icon || '',
                            title: item.title || item.journal_title || item.name || `Journal ${journalId}`,
                            solicit: {
                                enabled: false,
                                initialized: false,
                                templateId: '0',
                                styleId: '0',
                                templateName: '',
                                styleName: '',
                                html: ''
                            },
                            
                            country_scope_label:'',
                            factoryTask: {
                                count: 0,
                                type: '',
                                typeLabel: this.$t('autoPromotion.autoSolicit')
                            },
                            factoryTasks: []
                        };
                        await Promise.all([
                            // this.refreshJournalByDetail(journalObj),
                            this.loadFactoryTaskSummaryByJournal(journalObj, userId)
                        ]);
                        return journalObj;
                    })
                );
            } catch (e) {
                this.$message.error(this.$t('autoPromotion.loadListFailed'));
            } finally {
                this.loading = false;
            }
        },
        async loadFactoryTaskSummaryByJournal(journal, userId) {
            if (!journal || !journal.journal_id) return;
            try {
                const res = await this.$api.post('api/promotion_factory/getList', {
                    journal_id: String(journal.journal_id),
                    user_id: String(userId || ''),
                    state: '-1'
                });
                const payload = (res && res.data) || {};
                const list = this.findArray(payload) || this.findArray(res) || [];
                const totalRaw = payload.total != null ? payload.total : res && res.total != null ? res.total : list.length;
                const total = Number(totalRaw) || 0;
                let latest = null;
                if (Array.isArray(list) && list.length) {
                    latest = list
                        .slice()
                        .sort((a, b) => Number(b.ctime || b.create_time || b.time || 0) - Number(a.ctime || a.create_time || a.time || 0))[0];
                }
          
                const normalizedTasks = (Array.isArray(list) ? list : []).map((task, idx) => {
                    const type = task && task.type != null ? String(task.type) : '';
                    const fieldCount = this.getFactoryTaskFieldCount(task);
                    const startPromotion =
                        task && task.start_promotion != null && String(task.start_promotion).trim() !== ''
                            ? String(task.start_promotion)
                            : null;
                    const state = task && task.state != null && String(task.state).trim() !== '' ? String(task.state) : null;
                    const enabled = String(startPromotion != null ? startPromotion : state != null ? state : '0') === '1';
                    return {
                        cardKey: `${journal.journal_id}_${task.promotion_factory_id || idx}`,
                        taskId: task.promotion_factory_id || '',
                        type: type,
                        typeLabel: this.mapFactoryTaskTypeLabel(type),
                        expertType: task && task.expert_type != null ? String(task.expert_type) : '',
                        expertTypeLabel: this.mapFactoryExpertTypeLabel(task && task.expert_type != null ? String(task.expert_type) : ''),
                        enabled: enabled,
                        switchLoading: false,
                        initialized: true,
                        templateName: this.getFactoryTemplateName(task, journal.journal_id),
                        fieldCount: fieldCount,
                        fieldCountText: String(fieldCount),
                        countryScopeLabel: task.country_scope_label || '-',
                        createdAtText: this.formatTaskCreateTime(task),
                        totalCount: total,
                        showCount: idx === 0 && total > 0,
                        rawTask: task
                    };
                });
                const firstTask = normalizedTasks.length ? normalizedTasks[0] : null;
                this.$set(journal, 'factoryTasks', normalizedTasks);
                this.$set(journal, 'factoryTask', {
                    count: total,
                    type: firstTask ? firstTask.type : '',
                    typeLabel: firstTask ? firstTask.typeLabel : this.$t('autoPromotion.autoSolicit'),
                    fieldCount: firstTask ? firstTask.fieldCount : 0
                });
            } catch (e) {
                this.$set(journal, 'factoryTasks', []);
                this.$set(journal, 'factoryTask', {
                    count: 0,
                    type: '',
                    typeLabel: this.$t('autoPromotion.autoSolicit'),
                    fieldCount: 0
                });
            }
        },
        /**
         * 全页只请求一次 listTemplatesAll，再按期刊写入 factoryTemplateNameMap。
         * 若列表项带 journal_id 则按期刊拆分；否则用同一份 id->name 映射到当前页各期刊（与原先「每刊各请求一次」相比只发 1 次 HTTP）。
         */
        async prefetchFactoryTemplateNameMapsOnce(journalIds) {
            const ids = [...new Set((journalIds || []).map((id) => String(id).trim()).filter(Boolean))];
            if (!ids.length) return;
            try {
                const res = await this.$api.post('api/mail_template/listTemplatesAll', { journal_id: ids[0] });
                const payload = (res && res.data) || {};
                const list = this.findArray(payload) || this.findArray(res) || [];
                const flat = {};
                const byJournal = {};
                (Array.isArray(list) ? list : []).forEach((item) => {
                    const id = item && (item.template_id != null ? item.template_id : item.id);
                    if (id == null) return;
                    const name = String(item.title || item.name || '').trim();
                    if (!name) return;
                    const tid = String(id);
                    flat[tid] = name;
                    const jid =
                        item.journal_id != null
                            ? String(item.journal_id).trim()
                            : item.journalId != null
                              ? String(item.journalId).trim()
                              : item.j_id != null
                                ? String(item.j_id).trim()
                                : '';
                    if (jid) {
                        if (!byJournal[jid]) byJournal[jid] = {};
                        byJournal[jid][tid] = name;
                    }
                });
                const perItemJournal = Object.keys(byJournal).length > 0;
                ids.forEach((jid) => {
                    const m = perItemJournal ? byJournal[jid] || {} : { ...flat };
                    this.$set(this.factoryTemplateNameMap, jid, m);
                });
            } catch (e) {
                console.error(e);
            }
        },
        getFactoryTemplateName(task, journalId) {
            const tplId = task && task.template_id != null ? String(task.template_id) : '';
            const journalMap = this.factoryTemplateNameMap[String(journalId || '')] || {};
            if (tplId && journalMap[tplId]) return journalMap[tplId];
            if (task && task.template_name) return task.template_name;
            return tplId ? `Template #${tplId}` : 'No Template Configured';
        },
        getFactoryTaskFieldCount(task) {
            if (!task) return 0;
            if (task.fetch_fields && typeof task.fetch_fields === 'object') {
                const keys = Object.keys(task.fetch_fields).filter(Boolean);
                if (keys.length) return keys.length;
            }
            const fetchIds = String(task.fetch_ids || '')
                .split(',')
                .map((s) => String(s).trim())
                .filter(Boolean);
            return fetchIds.length;
        },
        formatTaskCreateTime(task) {
            if (!task || typeof task !== 'object') return '';
            const raw = task.ctime || task.create_time || task.created_at || task.time || '';
            if (raw == null || String(raw).trim() === '') return '';
            const n = Number(raw);
            let dt = null;
            if (!isNaN(n) && n > 0) {
                dt = new Date(n > 1e12 ? n : n * 1000);
            } else {
                dt = new Date(String(raw));
            }
            if (!dt || isNaN(dt.getTime())) return String(raw);
            const pad = (v) => String(v).padStart(2, '0');
            return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())} ${pad(dt.getHours())}:${pad(
                dt.getMinutes()
            )}:${pad(dt.getSeconds())}`;
        },
        mapFactoryTaskTypeLabel(type) {
            const t = String(type || '');
            if (t === '1') return this.$t('autoPromotion.factoryScenarioSolicit');
            if (t === '2') return this.$t('autoPromotion.factoryScenarioPromoteCitation');
            if (t === '3') return this.$t('autoPromotion.factoryScenarioGeneralThanks');
            if (t === '4') return this.$t('autoPromotion.autoSolicit');
            return this.$t('autoPromotion.autoSolicit');
        },
        mapFactoryExpertTypeLabel(expertType) {
            const t = String(expertType || '').trim();
            if (t === '1') return this.$t('autoPromotion.factoryExpertChief');
            if (t === '2') return this.$t('autoPromotion.factoryExpertBoard');
            if (t === '3') return this.$t('autoPromotion.factoryExpertYoungBoard');
            if (t === '4') return this.$t('autoPromotion.factoryExpertAuthor');
            if (t === '5') return this.$t('autoPromotion.factoryExpertDb');
            return '-';
        },
        getJournalDisplayTasks(journal) {
            const list = journal && Array.isArray(journal.factoryTasks) ? journal.factoryTasks : [];
            return list;
        },
        getFactoryTaskTypeLabel(journal) {
            if (journal && journal.factoryTask && journal.factoryTask.typeLabel) {
                return journal.factoryTask.typeLabel;
            }
            return this.$t('autoPromotion.autoSolicit');
        },
        async refreshAll() {
            this.templateNameMap = {};
            this.factoryTemplateNameMap = {};
            this.allJournals = [];
            await this.fetchPromotionJournals();
        },
        async refreshJournalByDetail(journal) {
            if (!journal || !journal.journal_id) return;
            try {
                const res = await this.$api.post('api/email_client/getPromotionJournalDetail', { journal_id: String(journal.journal_id) });
                const detail = this._parseJournalDetail(res.data);
                this.$set(this.templateNameMap, 'j_' + journal.journal_id, detail);
                this.$set(journal, 'title', detail.title || journal.title);
                this.$set(journal, 'solicit', { ...(journal.solicit || {}), ...detail });
            } catch (e) {
                console.error(e);
            }
        },
        isSolicitConfigured(journal) {
            const s = journal && journal.solicit ? journal.solicit : {};
            return !!(s.initialized && s.templateId !== '0' && s.styleId !== '0');
        },
        getSolicitActionText(journal) {
            if (!this.isSolicitConfigured(journal)) return this.$t('autoPromotion.goConfig');
            return journal.solicit.enabled ? this.$t('autoPromotion.goManagePlan') : this.$t('autoPromotion.startPlan');
        },
        findArray(obj) {
            if (Array.isArray(obj)) return obj;
            const keys = ['list', 'fields', 'rows', 'items', 'data', 'result'];
            for (const k of keys) {
                if (obj && Array.isArray(obj[k])) return obj[k];
            }
            return null;
        },
        async loadPromotionFields(journalId) {
            this.fieldsLoading = true;
            try {
                const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
                let availableArr = this.findArray(availableRes.data || availableRes) || [];
                this.availableFields = availableArr.map((item, idx) => ({
                    id: String(item.expert_fetch_id || item.fetch_id || item.id || idx),
                    label: item.field || item.title || item.name || 'Field'
                }));
                this.availableCountries = [...this.availableFields];
                const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) });
                const selectedPayload = selectedRes.data || selectedRes || {};
                let selectedArr = this.findArray(selectedPayload);
                if (selectedArr) {
                    this.selectedFieldIds = selectedArr.map((it) => String(it.expert_fetch_id || it.fetch_id || it.id || it));
                }
                if (selectedPayload.country_fetch_ids) {
                    this.selectedCountryIds = selectedPayload.country_fetch_ids.split(',').filter(Boolean);
                }
            } catch (e) {
                console.error(e);
            }
            this.fieldsLoading = false;
        },
        async savePromotionFieldsNow() {
            await this.$api.post(
                'api/email_client/setJournalPromotionFields',
                this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
            );
            this.$message.success(this.$t('autoPromotion.fieldsSaved'));
        },
        journalPromotionFieldsPayload(journalId) {
            return {
                journal_id: String(journalId),
                fetch_ids: (this.selectedFieldIds || []).join(','),
                country_fetch_ids: (this.selectedCountryIds || []).join(',')
            };
        },
      
        openWizardForJournal(journal) {
            this.wizardJournal = journal;
            const s = journal.solicit || {};
            this.wizardConfig = { defaultTemplateId: s.templateId, defaultStyleId: s.styleId, enabled: !!s.enabled };
            this.selectedTemplateName = s.templateName;
            this.selectedStyleName = s.styleName;
            this.selectedTemplateThumbHtml = `<div style="zoom:0.18;">${s.html || ''}</div>`;
            this.loadPromotionFields(journal.journal_id);
            this.showWizardDialog = true;
        },
        handleTemplateApply(payload) {
            this.wizardConfig.defaultTemplateId = String(payload.template_id);
            this.wizardConfig.defaultStyleId = String(payload.style_id);
            this.selectedTemplateName = payload.template.name;
            this.selectedTemplateThumbHtml = `<div style="zoom:0.18;">${payload.html || ''}</div>`;
            this.showTemplateDialog = false;
        },
        async saveWizardConfig() {
            this.saving = true;
            try {
                await this.$api.post('api/email_client/setDefaultPromotion', {
                    journal_id: String(this.wizardJournal.journal_id),
                    default_template_id: this.wizardConfig.defaultTemplateId,
                    default_style_id: this.wizardConfig.defaultStyleId,
                    start_promotion: this.wizardConfig.enabled ? '1' : '0',
                    user_id: localStorage.getItem('U_id')
                });
                await this.refreshJournalByDetail(this.wizardJournal);
                this.showWizardDialog = false;
            } catch (e) {
                this.$message.error('Save failed');
            } finally {
                this.saving = false;
            }
        },
        openDetail(journal,taskCard) {
            const taskId = taskCard && taskCard.taskId != null ? String(taskCard.taskId) : '';
            this.$router.push({
                path: '/autoPromotionLogs',
                query: {
                    journal_id: String(journal.journal_id),
                    promotion_factory_id: taskId
                }
            });
        },
        async handleSwitch(journal, type, nextVal) {
            if (!this.isSolicitConfigured(journal)) {
                this.$set(journal.solicit, 'enabled', false);
                return;
            }
            this.promotionUpdating = true;
            try {
                await this.$api.post('api/email_client/setDefaultPromotion', {
                    journal_id: String(journal.journal_id),
                    default_template_id: String(journal.solicit.templateId),
                    default_style_id: String(journal.solicit.styleId),
                    start_promotion: nextVal ? '1' : '0',
                    user_id: localStorage.getItem('U_id')
                });
            } catch (e) {
                this.$set(journal.solicit, 'enabled', !nextVal);
            } finally {
                this.promotionUpdating = false;
            }
        }
    }
};
</script>

<style scoped>
/* 容器 */
.auto-promo-container {
    padding: 0 10px 6px;
    min-height: 100vh;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.journal-list-wrapper {
    max-width: 1600px;
    margin: 0 auto;
}

/* 顶部 */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
}

/* 期刊分组区间 */
.journal-group-section {
    margin-bottom: 20px;
}

.journal-main-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    padding-left: 2px;
}

.brand-icon {
    width: 22px;
    height: 22px;
    background: #3a579a;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    font-size: 15px;
}

.journal-title-text {
    font-size: 15px;
    font-weight: 700;
    color: #1a1a1a;
    margin: 0;
    margin-left: 6px;
}

.active-badge {
    font-size: 12px;
    font-weight: 800;
    color: #6a737d;
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.pulse-dot {
    width: 8px;
    height: 8px;
    background-color: #409eff;
    border-radius: 50%;
    box-shadow: 0 0 0 rgba(64, 158, 255, 0.4);
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(64, 158, 255, 0.7);
    }
    70% {
        transform: scale(1);
        box-shadow: 0 0 0 6px rgba(64, 158, 255, 0);
    }
    100% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(64, 158, 255, 0);
    }
}
.journal-brand {
    display: flex;
    align-items: center;
}
/* 卡片网格布局 */
.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: 12px;
}

.no-task-tip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 12px;
    border: 1px dashed #dcdfe6;
    border-radius: 8px;
    color: #909399;
    font-size: 13px;
    background: #fafafa;
}

.no-task-create-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}

/* 统计卡片基础样式 */
.stat-card {
    background: #ffffff;
    border-radius: 8px;
    border: 1px solid #e1e4e8;
    padding: 10px;
    transition: all 0.2s ease;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.06);
}

.stat-card.is-active {
    border-top: 3px solid #67c23a;
}

.stat-card.is-stopped {
    border-top: 3px solid #909399;
}

.stat-card.is-disabled-style {
    opacity: 0.8;
    background: #fafbfc;
}

/* 卡片内部头部 */
.card-inner-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 8px;
    width: 100%;
    box-sizing: border-box;
    gap: 8px;
}

.card-label-area {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.card-main-title {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 700;
    color: #1a1a1a;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
}

.config-inline-btn {
    flex-shrink: 0;
    white-space: nowrap;
}

.scene-task-count {
    font-size: 12px;
    color: #909399;
    font-weight: 600;
}

.status-tag {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    margin-top: 0px;
    margin-left: 0;
    flex-shrink: 0;
    white-space: nowrap;
}

.is-active .status-tag {
    color: #52c41a;
}
.is-stopped .status-tag {
    color: #909399;
}

.status-tag .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    margin-right: 6px;
}

/* 内容区：与底部按钮同宽对齐 */
.card-content {
    flex: 1;
    width: 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    box-sizing: border-box;
}

.template-preview-box {
    background: #f1f4f9;
    border: 1px solid #e1e4e8;
    border-radius: 6px;
    padding: 3px 8px;
    /* display: flex;
    align-items: center; */
    gap: 0px;
    margin-bottom: 8px;
    color: #409eff;
    width: 100%;
    box-sizing: border-box;
}

.meta-row {
    display: flex;
    align-items: center;
    min-width: 0;
}

.template-preview-box.is-empty {
    color: #909399;
    font-style: italic;
}

.tpl-name {
    font-size: 12px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tpl-name-single-line {
    flex: 1;
    min-width: 0;
}

/* 统计项 */
.stats-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-bottom: 8px;
}

.stat-box {
    background: #f8f9fa;
    padding: 6px 8px;
    border-radius: 4px;
    border: 1px solid #f0f1f2;
}

.stat-label {
    display: block;
    font-size: 10px;
    font-weight: 800;
    color: #6a737d;
    margin-bottom: 4px;
    letter-spacing: 0.4px;
}

.stat-value {
    font-size: 13px;
    font-weight: 700;
    color: #24292e;
    display: flex;
    align-items: center;
    gap: 4px;
}

.stat-value i {
    font-size: 15px;
    color: #52c41a;
}
.stat-value.warning i {
    color: #e6a23c;
}

/* 底部按钮区 */
.card-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.task-card-footer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 16px;
}

.promo-history-spacer {
    flex: 0 0 auto;
    min-width: 0;
}

.promo-history-link {
    flex: 0 1 auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    padding: 0;
    border: none;
    background: transparent;
    font-size: 11px;
    font-weight: 600;
    color: #409eff;
    cursor: pointer;
    line-height: 1.3;
    text-align: left;
}

.promo-history-link i {
    font-size: 12px;
}

.promo-history-link:hover {
    color: #66b1ff;
    text-decoration: underline;
}

.task-create-time {
    flex-shrink: 0;
    font-size: 11px;
    color: #909399;
    text-align: right;
}

.action-main-btn {
    flex: 1;
    height: 24px;
    background: #eaf3ff;
    color: #409eff;
    border: 1px solid #d7e7ff;
    border-radius: 4px;
    font-weight: 600;
    font-size: 12px;
    line-height: 22px;
    cursor: pointer;
    transition: all 0.2s;
}

.action-main-btn:hover {
    background: #dcecff;
    border-color: #c4ddff;
    color: #2f89ea;
}

.is-active .action-main-btn {
    background: #3dbb6a;
    color: #ffffff;
    border-color: #3dbb6a;
}

.is-active .action-main-btn:hover {
    background: #31a85b;
    border-color: #31a85b;
    color: #ffffff;
}

.action-main-btn.secondary {
    background: transparent;
    border: 2px solid #1a1a1a;
    color: #1a1a1a;
}

.action-edit-btn {
    width: 30px;
    height: 30px;
    background: white;
    border: 1px solid #e1e4e8;
    border-radius: 6px;
    font-size: 14px;
    cursor: pointer;
    color: #6a737d;
    display: flex;
    align-items: center;
    justify-content: center;
}

.action-edit-btn:hover {
    background: #f6f8fa;
    color: #409eff;
    border-color: #409eff;
}

/* 响应式 */
@media (max-width: 1200px) {
    .cards-grid {
        grid-template-columns: 1fr;
    }
}
</style>
