<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-breadcrumb-item>
      </el-breadcrumb>
      <el-button
        type="text"
        icon="el-icon-refresh"
        class="auto-promo-refresh-btn"
        :disabled="loading"
        :title="$t('autoPromotion.refresh')"
        @click="refreshAll"
      />
    </div>

    <div class="journal-grid">
      <div v-for="journal in allJournals" :key="journal.journal_id" class="journal-item">
        
        <div class="item-header">
          <div class="journal-info">
            <div class="icon-box">
              <i class="el-icon-notebook-2"></i>
            </div>
            <span class="journal-name">{{ journal.title }}</span>
          </div>
        </div>

        <div class="module-wrapper">
          <div :class="['module-card', journal.solicit.initialized ? 'is-solicit-active' : 'is-empty']">
            <div class="module-top">
              <div class="module-top-left">
                <span class="module-title">{{ $t('autoPromotion.autoSolicit') }}</span>
                <el-button
                  v-if="journal.solicit.initialized"
                  type="text"
                  size="mini"
                  icon="el-icon-refresh"
                  class="config-inline-btn"
                  :disabled="promotionUpdating && String(promotionUpdatingJournalId) === String(journal.journal_id)"
                  @click="openWizardForJournal(journal)"
                >
                  {{ $t('autoPromotion.editConfig') }}
                </el-button>
              </div>
              <el-switch 
                v-model="journal.solicit.enabled" 
                active-color="#409EFF" 
                @change="handleSwitch(journal, 'solicit', $event)" 
                size="small" 
                :disabled="promotionUpdating && String(promotionUpdatingJournalId) === String(journal.journal_id)"
              />
            </div>

            <div class="module-content">
              <template v-if="journal.solicit.initialized">
                <div class="status-row" v-if="journal.solicit.enabled">
                  <span class="dot-running"></span>
                  <span class="status-text">{{ $t('autoPromotion.running') }}</span>
                </div>
                <div class="template-info-row">
                  <div>
                    <div class="template-info blue-text">{{ $t('autoPromotion.emailTemplate') }}: {{ journal.solicit.templateName || '-' }}</div>
                    <div class="template-info blue-text">{{ $t('autoPromotion.emailStyle') }}: {{ journal.solicit.styleName || '-' }}</div>
                  </div>
                </div>
              </template>
              <div v-else class="empty-text">
                {{ isSolicitConfigured(journal) ? $t('autoPromotion.notStarted') : $t('autoPromotion.notInitializedTip') }}
              </div>
            </div>

            <div class="module-footer">
              <button
                class="action-btn btn-blue"
                :disabled="promotionUpdating && String(promotionUpdatingJournalId) === String(journal.journal_id)"
                @click="handleSolicitAction(journal)"
              >
                <span v-if="promotionUpdating && String(promotionUpdatingJournalId) === String(journal.journal_id)">
                  {{ $t('autoPromotion.loading') }}
                </span>
                <span v-else>
                  {{ getSolicitActionText(journal) }}
                </span>
              </button>
            </div>
          </div>
        </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"
      :availableFields="availableFields"
      :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"
      @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"
    />
  </div>
</template>

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

export default {
  components: { JournalDetailDialog, AutoPromotionWizard, TemplateSelectorDialog },
  data() {
    return {
      loading: true,
      detailVisible: false,
      currentJournal: null,
      showWizardDialog: false,
      showTemplateDialog: false,
      saving: false,
      promotionUpdating: false,
      promotionUpdatingJournalId: '',
      wizardJournal: null,
      wizardStartDate: '',
      wizardConfig: {
        defaultTemplateId: '',
        defaultStyleId: '',
        enabled: false
      },
      selectedTemplateThumbHtml: '',
      selectedTemplateName: '',
      selectedStyleName: '',
      selectedFieldIds: [],
      availableFields: [],
      fieldsLoading: false,
      fieldsSaving: false,
      templateDialogInitialStyleId: '',
      templateDialogInitialTemplateId: '',
      templateNameMap: {},
      allJournals: []
    };
  },
  created() {
    this.fetchPromotionJournals();
  },
  methods: {
    openTemplateSelector() {
      // 更换模板时优先回显当前已选 style/template；没有则由选择器回落到第一项
      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;
    },
    /**
     * 核心逻辑抽象：统一解析详情接口返回的数据结构
     */
    _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 userId = localStorage.getItem('U_id') || '';
        const res = await this.$api.post('api/email_client/getPromotionJournalList', { user_id: userId });
        const raw = (res && res.data && (res.data.list || res.data.journals || res.data)) || [];
        
        if (Array.isArray(raw) && raw.length) {
          this.allJournals = await Promise.all(raw.map(async (item) => {
            const journalId = item.journal_id || item.id;
            const tplId = String(item.default_template_id || item.template_id || '0');
            const styleId = String(item.default_style_id || item.style_id || '0');
            const initialized = tplId !== '0' && styleId !== '0';
            const enabled = String(item.start_promotion || item.enabled || '0') === '1';

            // 初始简单结构：先用列表接口回填基础状态
            let journalObj = {
              journal_id: journalId,
              title: item.title || item.journal_title || item.name || `Journal ${journalId}`,
              solicit: {
                enabled,
                initialized,
                templateId: tplId,
                styleId: styleId,
                templateName: '',
                styleName: '',
                html: ''
              }
            };

            // 只有在“有模板id和风格id”时，才拉取详情（避免未初始化期刊的无意义请求）
            if (initialized) {
              await this.refreshJournalByDetail(journalObj);
            }
            return journalObj;
          }));
        } else {
          this.allJournals = [];
        }
      } catch (e) {
        this.$message.error(this.$t('autoPromotion.loadListFailed'));
      } finally {
        this.loading = false;
      }
    },

    // 右上角刷新：重新拉取列表，并重新拉取每个期刊对应的模版/风格详情
    async refreshAll() {
      this.templateNameMap = {};
      this.allJournals = [];
      await this.fetchPromotionJournals();
    },

    async refreshJournalByDetail(journal) {
      if (!journal || !journal.journal_id) return;
      const journalId = String(journal.journal_id);
      
      try {
        const res = await this.$api.post('api/email_client/getPromotionJournalDetail', { journal_id: journalId });
        const detail = this._parseJournalDetail(res.data);
        
        // 更新缓存（供原本的 fetchJournalTemplateAndStyleNames 逻辑兼容）
        this.$set(this.templateNameMap, 'j_' + journalId, detail);

        // 使用 $set 确保响应式更新
        this.$set(journal, 'title', detail.title || journal.title);
        this.$set(journal, 'solicit', {
          ...(journal.solicit || {}),
          enabled: detail.enabled,
          initialized: detail.initialized,
          templateId: detail.templateId,
          styleId: detail.styleId,
          templateName: detail.templateName,
          styleName: detail.styleName,
          html: detail.html
        });
      } catch (e) {
        console.error('Refresh detail failed:', e);
      }
    },

    // 保持此方法以兼容 wizard 内的逻辑（实际上逻辑已被 _parseJournalDetail 整合）
    async fetchJournalTemplateAndStyleNames(journalId) {
      const cacheKey = 'j_' + journalId;
      if (this.templateNameMap[cacheKey]) return this.templateNameMap[cacheKey];
      
      try {
        const res = await this.$api.post('api/email_client/getPromotionJournalDetail', { journal_id: String(journalId) });
        const detail = this._parseJournalDetail(res.data);
        this.$set(this.templateNameMap, cacheKey, detail);
        return detail;
      } catch (e) {
        return { templateName: '', styleName: '', html: '' };
      }
    },

    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 && journal.solicit && journal.solicit.enabled
        ? this.$t('autoPromotion.goManagePlan')
        : this.$t('autoPromotion.startPlan');
    },
    findArray(obj) {
      if (Array.isArray(obj)) return obj;
      if (!obj || typeof obj !== 'object') return null;
      const keys = ['list', 'fields', 'rows', 'items', 'data', 'result'];
      for (const k of keys) {
        if (Array.isArray(obj[k])) return obj[k];
      }
      const values = Object.values(obj);
      if (values.length && Array.isArray(values[0])) return values[0];
      return null;
    },
    async loadPromotionFields(journalId) {
      this.fieldsLoading = true;
      this.availableFields = [];
      this.selectedFieldIds = [];
      try {
        const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
        
        const availablePayload = (availableRes && availableRes.data) || availableRes || {};
        let availableArr = this.findArray(availablePayload);
        if (!availableArr) {
          availableArr = Array.isArray(availablePayload) ? availablePayload : [];
        }

        this.availableFields = availableArr.map((item, idx) => {
          const id = item.expert_fetch_id || item.fetch_id || item.id || item.field_id || (idx + 1);
          const label = item.field || item.title || item.name || item.label || String(id);
          return { id: String(id), label };
        });
        } catch (e) {
         this.availableFields = [];
      }

      try {
        const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) });
        console.log('[getJournalPromotionFields] raw response:', JSON.stringify(selectedRes));

        const selectedPayload = (selectedRes && selectedRes.data) || selectedRes || {};
        let selectedArr = this.findArray(selectedPayload);

        if (selectedArr) {
          this.selectedFieldIds = selectedArr.map((it) => {
            return String(it.expert_fetch_id || it.fetch_id || it.id || it.field_id || it);
          });
        } else if (typeof selectedPayload === 'string') {
          this.selectedFieldIds = selectedPayload.split(',').map((s) => s.trim()).filter(Boolean);
        } else if (typeof selectedPayload.fetch_ids === 'string') {
          this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
        }
        console.log('[getJournalPromotionFields] parsed selected:', this.selectedFieldIds);
      } catch (e) {
        console.error('[getJournalPromotionFields] error:', e);
        this.selectedFieldIds = [];
      }

      this.fieldsLoading = false;
    },
    async savePromotionFieldsNow() {
      if (!this.wizardJournal || !this.wizardJournal.journal_id) return;
      this.fieldsSaving = true;
      try {
        await this.$api.post('api/email_client/setJournalPromotionFields', {
          journal_id: String(this.wizardJournal.journal_id),
          fetch_ids: (this.selectedFieldIds || []).join(',')
        });
        this.$message.success(this.$t('autoPromotion.fieldsSaved'));
      } catch (e) {
        this.$message.error(this.$t('autoPromotion.saveFailed'));
      } finally {
        this.fieldsSaving = false;
      }
    },

    async handleSolicitAction(journal) {
      if (!this.isSolicitConfigured(journal)) {
        this.openWizardForJournal(journal);
        return;
      }
      // 未开启时：必须等待 setDefaultPromotion 成功后才继续打开详情
      if (!journal.solicit.enabled) {
        const journalId = journal && journal.journal_id ? String(journal.journal_id) : '';
        this.promotionUpdating = true;
        this.promotionUpdatingJournalId = journalId;
        try {
          const userId = localStorage.getItem('U_id') || '';
          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: '1',
            user_id: userId
          });
          this.$message.success(`${journal.title} ${this.$t('autoPromotion.startedPlan')}`);
          await this.refreshJournalByDetail(journal);
          this.openDetail(journal);
        } catch (e) {
          // 接口失败时不要做后续动作（避免进入详情后数据未就绪）
          this.$message.error(this.$t('autoPromotion.updateRetryFailed'));
          return;
        } finally {
          this.promotionUpdating = false;
          this.promotionUpdatingJournalId = '';
        }
        return;
      }

      // 已开启：直接打开详情
      this.openDetail(journal);
    },

    async openWizardForJournal(journal) {
      this.wizardJournal = journal;
      const s = journal.solicit || {};
      this.wizardConfig = {
        defaultTemplateId: s.templateId !== '0' ? s.templateId : '',
        defaultStyleId: s.styleId !== '0' ? s.styleId : '',
        enabled: !!s.enabled
      };
      this.selectedTemplateName = s.templateName || '';
      this.selectedStyleName = s.styleName || '';
      this.selectedTemplateThumbHtml = `<div style="zoom:0.18; pointer-events:none; user-select:none;">${s.html || ''}</div>`;
      this.selectedFieldIds = [];
      this.availableFields = [];
      if (journal && journal.journal_id) {
        await this.loadPromotionFields(journal.journal_id);
      }
      this.showWizardDialog = true;
    },

    handleTemplateApply(payload) {
      if (!payload || !payload.template_id || !payload.style_id) {
        this.$message.warning(this.$t('autoPromotion.selectTemplateStyleFirst'));
        return;
      }
      this.wizardConfig.defaultTemplateId = String(payload.template_id);
      this.wizardConfig.defaultStyleId = String(payload.style_id);
      this.selectedTemplateName = payload.template && payload.template.name ? payload.template.name : '';
      this.selectedStyleName = payload.style && payload.style.name ? payload.style.name : '';
      this.selectedTemplateThumbHtml = `<div style="zoom:0.18; pointer-events:none; user-select:none;">${payload.html || ''}</div>`;
      this.showTemplateDialog = false;
    },

    async saveWizardConfig() {
      if (!this.wizardJournal || !this.wizardJournal.solicit) return;
      if (!this.wizardConfig.defaultTemplateId || !this.wizardConfig.defaultStyleId) {
        this.$message.warning(this.$t('autoPromotion.selectTemplateStyleFirst'));
        return;
      }
      this.saving = true;
      try {
        const userId = localStorage.getItem('U_id') || '';
        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: userId
        });
        await this.$api.post('api/email_client/setJournalPromotionFields', {
          journal_id: String(this.wizardJournal.journal_id),
          fetch_ids: (this.selectedFieldIds || []).join(',')
        });
        await this.refreshJournalByDetail(this.wizardJournal);
        this.$message.success(this.$t('autoPromotion.configSaved'));
        this.showWizardDialog = false;
      } catch (e) {
        this.$message.error(this.$t('autoPromotion.saveFailed'));
      } finally {
        this.saving = false;
      }
    },

    openDetail(journal) {
      this.$router.push({
        path: '/autoPromotionLogs',
        query: { journal_id: journal && journal.journal_id ? String(journal.journal_id) : '' }
      });
    },

    async handleSwitch(journal, type, nextVal) {
      if (!this.isSolicitConfigured(journal)) {
        this.$set(journal.solicit, 'enabled', false);
        this.$message.warning(this.$t('autoPromotion.notInitializedSwitchTip'));
        return;
      }
      try {
        this.promotionUpdating = true;
        this.promotionUpdatingJournalId = journal && journal.journal_id ? String(journal.journal_id) : '';
        const userId = localStorage.getItem('U_id') || '';
        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: userId
        });
        this.$message.success(nextVal ? this.$t('autoPromotion.planEnabled') : this.$t('autoPromotion.planDisabled'));
      } catch (e) {
        this.$set(journal.solicit, 'enabled', !nextVal);
        this.$message.error(this.$t('autoPromotion.updateFailed'));
      } finally {
        this.promotionUpdating = false;
        this.promotionUpdatingJournalId = '';
      }
    }
  }
};
</script>

<style scoped>
/* 保持您原始的 CSS 样式不变 */
.auto-promo-container { padding: 20px 24px; background-color: #f5f7f9; min-height: 100vh; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto; }
.page-header { margin-bottom: 16px; display: flex; justify-content: flex-start; align-items: center; }
.auto-promo-refresh-btn { margin-left: 12px; }
.journal-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.journal-item { background: #fff; border-radius: 10px; padding: 16px; border: 1px solid #ebedf0; box-shadow: 0 2px 6px rgba(0,0,0,0.03); }
.item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.journal-info { display: flex; align-items: center; }
.icon-box { width: 28px; height: 28px; background: #edf5ff; border-radius: 4px; display: flex; align-items: center; justify-content: center; margin-right: 10px; }
.icon-box i { color: #409eff; font-size: 14px; }
.journal-name { font-size: 14px; font-weight: 600; color: #1f2d3d; }
.module-wrapper { display: grid; grid-template-columns: 1fr; }
.module-card { border-radius: 6px; padding: 14px; display: flex; flex-direction: column; min-height: 160px; border: 1px solid transparent; }
.is-solicit-active { background: #f4f9ff; border-color: #e1eeff; }
.is-empty { background: #fafafa; border-color: #f0f0f0; }
.module-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.module-top-left { display: flex; align-items: center; gap: 8px; }
.module-title { font-size: 14px; font-weight: 600; color: #333; }
.config-inline-btn { padding: 0; }
.module-content { flex: 1; }
.status-row { display: flex; align-items: center; margin-bottom: 4px; }
.status-text { font-size: 12px; font-weight: 600; color: #52c41a; }
.template-info { font-size: 12px; color: #bbb; margin-bottom: 2px; }
.blue-text { color: #409eff; }
.template-info-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.empty-text { font-size: 12px; color: #bbb; height: 60px; display: flex; align-items: center; }
.dot-running { width: 6px; height: 6px; background: #52c41a; border-radius: 50%; margin-right: 6px; }
.module-footer { margin-top: 12px; }
.action-btn { width: 100%; padding: 6px 0; border: none; border-radius: 4px; font-size: 12px; font-weight: 600; cursor: pointer; transition: 0.2s; }
.btn-blue { background: #e8f3ff; color: #409eff; }
.btn-blue:hover { background: #409eff; color: #fff; }
@media (min-width: 1280px) { .journal-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1680px) { .journal-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
</style>