<template>
  <div class="publish-page">
    <div class="page-header">
      <h2>发布管理</h2>
      <div class="header-actions">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索标题/文件名..."
          style="width: 200px; margin-right: 12px"
          clearable
          @clear="loadTasks"
          @keyup.enter="loadTasks"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-button @click="loadTasks" :loading="loading">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
        <el-button type="primary" @click="showCreateDialog = true">
          <el-icon><Plus /></el-icon>
          新建发布
        </el-button>
      </div>
    </div>
    
    <div class="page-card">
      <el-table :data="filteredTasks" v-loading="loading">
        <el-table-column label="视频" min-width="200">
          <template #default="{ row }">
            <div class="video-info">
              <div class="video-title">{{ row.title }}</div>
              <div class="video-file">{{ row.videoFilename }}</div>
            </div>
          </template>
        </el-table-column>
        
        <el-table-column label="目标账号" min-width="180">
          <template #default="{ row }">
            <span>{{ row.targetAccounts?.length || 0 }} 个</span>
            <el-tag
              v-for="platform in getTaskPlatforms(row)"
              :key="platform"
              size="small"
              style="margin-left: 4px"
            >
              {{ getPlatformName(platform) }}
            </el-tag>
          </template>
        </el-table-column>
        
        <el-table-column label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)">
              {{ getStatusText(row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        
        <el-table-column label="定时发布" width="160">
          <template #default="{ row }">
            {{ row.scheduledAt ? formatDate(row.scheduledAt) : '-' }}
          </template>
        </el-table-column>
        
        <el-table-column label="创建时间" width="160">
          <template #default="{ row }">
            {{ formatDate(row.createdAt) }}
          </template>
        </el-table-column>
        
        <el-table-column label="操作" width="150" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="viewDetail(row)">
              详情
            </el-button>
            <el-button
              v-if="row.status === 'pending'"
              type="danger"
              link
              size="small"
              @click="cancelTask(row.id)"
            >
              取消
            </el-button>
            <el-button
              v-if="row.status === 'failed' || row.status === 'processing'"
              type="warning"
              link
              size="small"
              @click="retryTask(row.id)"
            >
              重试
            </el-button>
            <el-button
              v-if="row.status !== 'processing'"
              type="danger"
              link
              size="small"
              @click="deleteTask(row.id)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <el-pagination
        v-model:current-page="pagination.page"
        v-model:page-size="pagination.pageSize"
        :total="pagination.total"
        :page-sizes="[10, 20, 50]"
        layout="total, sizes, prev, pager, next"
        style="margin-top: 20px"
        @change="loadTasks"
      />
    </div>
    
    <!-- 创建发布对话框 -->
    <el-dialog v-model="showCreateDialog" title="新建发布" width="600px">
      <el-form :model="createForm" label-width="100px">
        <!-- 平台提示：根据选择的目标平台动态显示必填要求 -->
        <el-alert
          v-if="createSelectedPlatforms.length > 0"
          :title="createPlatformHint"
          type="info"
          :closable="false"
          show-icon
          style="margin-bottom: 16px"
        />
        
        <el-form-item label="视频文件" :required="createRequireVideo">
          <el-upload
            action=""
            :auto-upload="false"
            :on-change="handleFileChange"
            :show-file-list="false"
          >
            <el-button type="primary">选择视频</el-button>
          </el-upload>
          <span v-if="createForm.videoFile" style="margin-left: 12px">
            {{ createForm.videoFile.name }}
          </span>
          <span v-if="createRequireImage && !createForm.videoFile" class="form-tip">
            也可上传图片发布
          </span>
        </el-form-item>
        
        <el-form-item v-if="createRequireTitle" label="标题" required>
          <el-input v-model="createForm.title" placeholder="视频标题" show-word-limit :maxlength="createTitleMaxLength" />
        </el-form-item>
        <el-form-item v-else label="标题">
          <el-input v-model="createForm.title" placeholder="视频标题（可选）" />
        </el-form-item>
        
        <el-form-item v-if="createRequireDescription" label="描述" required>
          <el-input v-model="createForm.description" type="textarea" :rows="3" placeholder="视频描述" show-word-limit :maxlength="createDescMaxLength" />
        </el-form-item>
        <el-form-item v-else label="描述">
          <el-input v-model="createForm.description" type="textarea" :rows="3" placeholder="视频描述（可选）" />
        </el-form-item>
        
        <el-form-item v-if="createShowTags" label="标签">
          <el-select v-model="createForm.tags" multiple filterable allow-create placeholder="添加标签" style="width: 100%">
          </el-select>
        </el-form-item>
        
        <el-form-item label="目标账号">
          <el-checkbox-group v-model="createForm.targetAccounts" v-if="accounts.length > 0">
            <el-checkbox
              v-for="account in accounts"
              :key="account.id"
              :label="account.id"
              :disabled="account.status !== 'active'"
            >
              <div class="account-option">
                <el-avatar :size="24" :src="account.avatarUrl || undefined">
                  {{ account.accountName?.[0] }}
                </el-avatar>
                <span class="account-name">{{ account.accountName }}</span>
                <el-tag size="small" :type="account.platform === 'douyin' ? 'danger' : 'primary'">
                  {{ getPlatformName(account.platform) }}
                </el-tag>
                <el-tag v-if="account.status !== 'active'" size="small" type="warning">
                  {{ account.status === 'expired' ? '已过期' : '异常' }}
                </el-tag>
              </div>
            </el-checkbox>
          </el-checkbox-group>
          <el-empty v-else description="暂无可用账号，请先在账号管理中添加" :image-size="60" />
        </el-form-item>
        
        <el-form-item label="定时发布">
          <el-date-picker
            v-model="createForm.scheduledAt"
            type="datetime"
            placeholder="选择时间（留空则立即发布）"
          />
        </el-form-item>

        <el-form-item label="发布代理">
          <el-switch v-model="createForm.usePublishProxy" />
        </el-form-item>

        <el-form-item v-if="createForm.usePublishProxy" label="代理城市">
          <el-cascader
            v-model="createForm.publishProxyRegionPath"
            :options="publishProxyCityRegions"
            :props="{ checkStrictly: false }"
            placeholder="选择城市（省/市）"
            clearable
            filterable
            style="width: 100%"
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="handleCreate" :loading="submitting">
          创建
        </el-button>
      </template>
    </el-dialog>
    
    <!-- 任务详情对话框 -->
    <el-dialog v-model="showDetailDialog" title="发布详情" width="700px">
      <template v-if="currentTask">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="任务ID">{{ currentTask.id }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag :type="getStatusType(currentTask.status)">
              {{ getStatusText(currentTask.status) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="标题" :span="2">{{ currentTask.title }}</el-descriptions-item>
          <el-descriptions-item label="描述" :span="2">{{ currentTask.description || '-' }}</el-descriptions-item>
          <el-descriptions-item label="视频文件" :span="2">{{ currentTask.videoFilename || currentTask.videoPath }}</el-descriptions-item>
          <el-descriptions-item label="标签" :span="2">
            <el-tag v-for="tag in (currentTask.tags || [])" :key="tag" size="small" style="margin-right: 4px">
              {{ tag }}
            </el-tag>
            <span v-if="!currentTask.tags?.length">-</span>
          </el-descriptions-item>
          <el-descriptions-item label="目标账号">{{ taskDetail?.results?.length || currentTask?.targetAccounts?.length || 0 }} 个</el-descriptions-item>
          <el-descriptions-item label="定时发布">
            {{ currentTask.scheduledAt ? formatDate(currentTask.scheduledAt) : '立即发布' }}
          </el-descriptions-item>
          <el-descriptions-item label="发布代理" :span="2">
            {{ formatPublishProxy(currentTask.publishProxy as any) }}
          </el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ formatDate(currentTask.createdAt) }}</el-descriptions-item>
          <el-descriptions-item label="发布时间">
            {{ currentTask.publishedAt ? formatDate(currentTask.publishedAt) : '-' }}
          </el-descriptions-item>
        </el-descriptions>
        
        <!-- 发布结果 -->
        <div v-if="taskDetail?.results?.length" class="publish-results">
          <h4>发布结果</h4>
          <el-table :data="taskDetail.results" size="small">
            <el-table-column label="账号" prop="accountId" width="80" />
            <el-table-column label="平台" width="100">
              <template #default="{ row }">
                {{ getPlatformName(row.platform) }}
              </template>
            </el-table-column>
            <el-table-column label="状态" width="100">
              <template #default="{ row }">
                <el-tag :type="row.status === 'success' ? 'success' : (row.status === 'failed' ? 'danger' : 'info')" size="small">
                  {{ row.status === 'success' ? '成功' : (row.status === 'failed' ? '失败' : '待发布') }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="错误信息" min-width="260">
              <template #default="{ row }">
                <div v-if="isCaptchaError(row.errorMessage)" class="captcha-error">
                  <el-text type="warning">检测到验证码，需要手动验证</el-text>
                  <el-button
                    type="primary"
                    size="small"
                    link
                    @click="openBrowserForCaptcha(row.accountId, row.platform)"
                  >
                    打开浏览器验证
                  </el-button>
                </div>
                <div v-else-if="isScreenshotPendingError(row.errorMessage)" class="screenshot-pending">
                  <span>{{ row.errorMessage?.replace('请查看截图', '').trim() || '发布结果待确认' }}</span>
                  <el-button
                    type="primary"
                    size="small"
                    link
                    @click="openScreenshotView(row)"
                  >
                    查看截图
                  </el-button>
                  <el-button
                    v-if="canRetryWithHeadful(row)"
                    type="primary"
                    size="small"
                    link
                    @click="openBrowserForCaptcha(row.accountId, row.platform)"
                  >
                    使用有头浏览器重新发布
                  </el-button>
                </div>
                <div v-else class="normal-error">
                  <span>{{ row.errorMessage || '-' }}</span>
                  <el-button
                    v-if="canRetryWithHeadful(row)"
                    type="primary"
                    size="small"
                    link
                    @click="openBrowserForCaptcha(row.accountId, row.platform)"
                  >
                    使用有头浏览器重新发布
                  </el-button>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="发布时间" width="160">
              <template #default="{ row }">
                {{ row.publishedAt ? formatDate(row.publishedAt) : '-' }}
              </template>
            </el-table-column>
          </el-table>
        </div>
      </template>
      
      <template #footer>
        <el-button @click="showDetailDialog = false">关闭</el-button>
        <el-button
          v-if="hasPendingConfirmResults"
          type="success"
          @click="confirmAllPendingResults"
        >
          确认
        </el-button>
        <el-button type="primary" @click="openEditDialog">
          <el-icon><Edit /></el-icon>
          修改并重新发布
        </el-button>
      </template>
    </el-dialog>
    
    <!-- 修改重新发布对话框 -->
    <el-dialog v-model="showEditDialog" title="修改并重新发布" width="600px">
      <el-alert type="info" :closable="false" style="margin-bottom: 16px">
        修改内容后将创建一条新的发布任务
      </el-alert>
      
      <el-form :model="editForm" label-width="100px">
        <el-form-item label="视频文件">
          <div>
            <span>{{ editForm.videoFilename || '使用原视频' }}</span>
            <el-upload
              action=""
              :auto-upload="false"
              :on-change="handleEditFileChange"
              :show-file-list="false"
              style="display: inline-block; margin-left: 12px"
            >
              <el-button size="small">更换视频</el-button>
            </el-upload>
          </div>
        </el-form-item>
        
        <el-form-item label="标题">
          <el-input v-model="editForm.title" placeholder="视频标题" />
        </el-form-item>
        
        <el-form-item label="描述">
          <el-input v-model="editForm.description" type="textarea" :rows="3" placeholder="视频描述" />
        </el-form-item>
        
        <el-form-item label="标签">
          <el-select v-model="editForm.tags" multiple filterable allow-create placeholder="添加标签" style="width: 100%">
          </el-select>
        </el-form-item>
        
        <el-form-item label="目标账号">
          <el-checkbox-group v-model="editForm.targetAccounts" v-if="accounts.length > 0">
            <el-checkbox
              v-for="account in accounts"
              :key="account.id"
              :label="account.id"
              :disabled="account.status !== 'active'"
            >
              <div class="account-option">
                <el-avatar :size="24" :src="account.avatarUrl || undefined">
                  {{ account.accountName?.[0] }}
                </el-avatar>
                <span class="account-name">{{ account.accountName }}</span>
                <el-tag size="small" :type="account.platform === 'douyin' ? 'danger' : 'primary'">
                  {{ getPlatformName(account.platform) }}
                </el-tag>
                <el-tag v-if="account.status !== 'active'" size="small" type="warning">
                  {{ account.status === 'expired' ? '已过期' : '异常' }}
                </el-tag>
              </div>
            </el-checkbox>
          </el-checkbox-group>
          <el-empty v-else description="暂无可用账号" :image-size="60" />
        </el-form-item>
        
        <el-form-item label="定时发布">
          <el-date-picker
            v-model="editForm.scheduledAt"
            type="datetime"
            placeholder="选择时间（留空则立即发布）"
          />
        </el-form-item>

        <el-form-item label="发布代理">
          <el-switch v-model="editForm.usePublishProxy" />
        </el-form-item>

        <el-form-item v-if="editForm.usePublishProxy" label="代理城市">
          <el-cascader
            v-model="editForm.publishProxyRegionPath"
            :options="publishProxyCityRegions"
            :props="{ checkStrictly: false }"
            placeholder="选择城市（省/市）"
            clearable
            filterable
            style="width: 100%"
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="showEditDialog = false">取消</el-button>
        <el-button type="primary" @click="handleRepublish" :loading="submitting">
          创建新发布
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from 'vue';
import { Plus, Refresh, Search, Edit } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox, ElLoading, type UploadFile } from 'element-plus';
import { accountsApi } from '@/api/accounts';
import request from '@/api/request';
import { PLATFORMS } from '@media-manager/shared';
import type { PublishTask, PublishTaskDetail, PlatformAccount, PlatformType } from '@media-manager/shared';
import { useTaskQueueStore } from '@/stores/taskQueue';
import { useTabsStore } from '@/stores/tabs';
import dayjs from 'dayjs';

const taskStore = useTaskQueueStore();
const tabsStore = useTabsStore();

const loading = ref(false);
const submitting = ref(false);
const showCreateDialog = ref(false);
const showDetailDialog = ref(false);
const showEditDialog = ref(false);
const searchKeyword = ref('');

const tasks = ref<PublishTask[]>([]);
const accounts = ref<PlatformAccount[]>([]);
const currentTask = ref<PublishTask | null>(null);
const taskDetail = ref<PublishTaskDetail | null>(null);

// 过滤后的任务列表
const filteredTasks = computed(() => {
  if (!searchKeyword.value) return tasks.value;
  const keyword = searchKeyword.value.toLowerCase();
  return tasks.value.filter(t => 
    t.title?.toLowerCase().includes(keyword) ||
    t.videoFilename?.toLowerCase().includes(keyword)
  );
});

// ===== Bug #6069: 创建表单平台感知字段 =====

// 当前选中的目标平台列表
const createSelectedPlatforms = computed<PlatformType[]>(() => {
  const ids = new Set(createForm.targetAccounts);
  const platforms = new Set<PlatformType>();
  for (const account of accounts.value) {
    if (ids.has(Number(account.id))) {
      platforms.add(account.platform);
    }
  }
  return Array.from(platforms);
});

// 各平台发布要求
const PLATFORM_PUBLISH_REQUIREMENTS: Record<string, {
  requireTitle: boolean;
  requireDescription: boolean;
  requireVideo: boolean;
  requireImage: boolean;
  showTags: boolean;
}> = {
  douyin: { requireTitle: true, requireDescription: false, requireVideo: true, requireImage: false, showTags: true },
  xiaohongshu: { requireTitle: true, requireDescription: true, requireVideo: false, requireImage: true, showTags: true },
  weixin_video: { requireTitle: true, requireDescription: false, requireVideo: true, requireImage: false, showTags: true },
  baijiahao: { requireTitle: true, requireDescription: true, requireVideo: false, requireImage: false, showTags: true },
  kuaishou: { requireTitle: true, requireDescription: false, requireVideo: true, requireImage: false, showTags: true },
  bilibili: { requireTitle: true, requireDescription: false, requireVideo: true, requireImage: false, showTags: true },
};

// 只要任一选中平台要求某字段，就显示必填
const createRequireTitle = computed(() => createSelectedPlatforms.value.some(p => PLATFORM_PUBLISH_REQUIREMENTS[p]?.requireTitle));
const createRequireDescription = computed(() => createSelectedPlatforms.value.some(p => PLATFORM_PUBLISH_REQUIREMENTS[p]?.requireDescription));
const createRequireVideo = computed(() => createSelectedPlatforms.value.some(p => PLATFORM_PUBLISH_REQUIREMENTS[p]?.requireVideo));
const createRequireImage = computed(() => createSelectedPlatforms.value.some(p => PLATFORM_PUBLISH_REQUIREMENTS[p]?.requireImage));
const createShowTags = computed(() => createSelectedPlatforms.value.some(p => PLATFORM_PUBLISH_REQUIREMENTS[p]?.showTags));

// 取最严格的标题/描述长度限制
const createTitleMaxLength = computed(() => {
  let max = 100;
  for (const p of createSelectedPlatforms.value) {
    const info = PLATFORMS[p];
    if (info?.maxTitleLength && info.maxTitleLength < max) max = info.maxTitleLength;
  }
  return max;
});
const createDescMaxLength = computed(() => {
  let max = 2000;
  for (const p of createSelectedPlatforms.value) {
    const info = PLATFORMS[p];
    if (info?.maxDescriptionLength && info.maxDescriptionLength < max) max = info.maxDescriptionLength;
  }
  return max;
});

// 平台提示文案
const createPlatformHint = computed(() => {
  const platforms = createSelectedPlatforms.value;
  if (!platforms.length) return '';
  const names = platforms.map(p => PLATFORMS[p]?.name || p).join('、');
  const tips: string[] = [];
  if (createRequireTitle.value) tips.push('标题必填');
  if (createRequireDescription.value) tips.push('正文必填');
  if (createRequireVideo.value) tips.push('视频必填');
  if (createRequireImage.value) tips.push('图片或视频必填');
  return `已选平台：${names}。要求：${tips.join('、')}`;
});

const pagination = reactive({
  page: 1,
  pageSize: 20,
  total: 0,
});

const publishProxyRegions = ref<any[]>([]);
const publishProxyCityRegions = computed(() => {
  const provinces = Array.isArray(publishProxyRegions.value) ? publishProxyRegions.value : [];
  return provinces.map((p: any) => ({
    ...p,
    children: Array.isArray(p?.children)
      ? p.children.map((c: any) => ({
          ...c,
          children: undefined,
        }))
      : [],
  }));
});

const createForm = reactive({
  videoFile: null as File | null,
  title: '',
  description: '',
  tags: [] as string[],
  targetAccounts: [] as number[],
  scheduledAt: null as Date | null,
  usePublishProxy: false,
  publishProxyRegionPath: [] as string[],
});

const editForm = reactive({
  videoFile: null as File | null,
  videoPath: '',
  videoFilename: '',
  title: '',
  description: '',
  tags: [] as string[],
  targetAccounts: [] as number[],
  scheduledAt: null as Date | null,
  usePublishProxy: false,
  publishProxyRegionPath: [] as string[],
});

function getSelectableAccountIds(): Set<number> {
  return new Set(
    accounts.value
      .filter(account => account.status === 'active')
      .map(account => Number(account.id))
      .filter(id => Number.isFinite(id))
  );
}

function sanitizeTargetAccounts(targetAccounts: Array<number | string | null | undefined>): number[] {
  const selectableIds = getSelectableAccountIds();
  const normalized = (targetAccounts || [])
    .map(id => Number(id))
    .filter(id => Number.isFinite(id) && selectableIds.has(id));
  return Array.from(new Set(normalized));
}

async function loadSystemConfig() {
  try {
    await loadPublishProxyRegions();
  } catch {
    publishProxyRegions.value = [];
  }
}

async function loadPublishProxyRegions() {
  try {
    const res = await request.get('/api/system/publish-proxy/regions');
    publishProxyRegions.value = Array.isArray(res?.regions) ? res.regions : [];
  } catch {
    publishProxyRegions.value = [];
  }
}

function getRegionLabelsByPath(options: any[], regionPath: string[]): string[] {
  const labels: string[] = [];
  let currentOptions = options;
  for (const value of regionPath) {
    const hit = currentOptions?.find((o: any) => String(o?.value) === String(value));
    if (!hit) break;
    labels.push(String(hit.label || ''));
    currentOptions = hit.children || [];
  }
  return labels.filter(Boolean);
}

function resolvePublishProxyFromRegionPath(regionPath: string[]) {
  const path = Array.isArray(regionPath) ? regionPath.map(v => String(v)) : [];
  if (!path.length) return null;

  const labels = getRegionLabelsByPath(publishProxyRegions.value, path);
  const regionCode = path[path.length - 1];
  const regionName = labels[labels.length - 1] || '';

  const specialCityLabels = new Set(['市辖区', '县', '省直辖县级行政区划', '自治区直辖县级行政区划']);
  let city = '';
  if (labels.length >= 2) {
    city = labels[1];
    if (specialCityLabels.has(city)) city = labels[0] || city;
  } else {
    city = labels[0] || '';
  }

  return {
    city: city || undefined,
    regionCode: regionCode || undefined,
    regionName: regionName || undefined,
    regionPath: path,
  };
}

function normalizePublishProxyCityRegionPath(regionPath: string[]) {
  const path = Array.isArray(regionPath) ? regionPath.map(v => String(v)) : [];
  if (path.length <= 2) return path;
  return path.slice(0, 2);
}

function formatPublishProxy(publishProxy: any): string {
  const enabled = Boolean(publishProxy?.enabled);
  if (!enabled) return '-';

  const provider = String(publishProxy?.provider || 'shenlong');
  const city = String(publishProxy?.city || '').trim();
  const regionCode = String(publishProxy?.regionCode || '').trim();
  const regionName = String(publishProxy?.regionName || '').trim();
  const regionPath = Array.isArray(publishProxy?.regionPath) ? publishProxy.regionPath.map((v: any) => String(v)) : [];

  let regionText = '';
  if (regionPath.length && publishProxyRegions.value.length) {
    const labels = getRegionLabelsByPath(publishProxyRegions.value, regionPath);
    if (labels.length) {
      regionText = labels.join('/');
    }
  }

  if (!regionText && regionName) regionText = regionName;

  const parts: string[] = [];
  parts.push(`启用(${provider})`);
  if (regionText && regionCode) parts.push(`地区: ${regionText}(${regionCode})`);
  else if (regionText) parts.push(`地区: ${regionText}`);
  else if (regionCode) parts.push(`地区编号: ${regionCode}`);
  if (city) parts.push(`城市: ${city}`);
  return parts.join('，');
}

function findRegionPathByCode(options: any[], targetCode: string): string[] | null {
  for (const opt of options || []) {
    if (!opt) continue;
    const value = String(opt.value || '');
    if (value === targetCode) return [value];
    const children = Array.isArray(opt.children) ? opt.children : [];
    const childPath = findRegionPathByCode(children, targetCode);
    if (childPath) return [value, ...childPath];
  }
  return null;
}

function getPlatformName(platform: PlatformType) {
  return PLATFORMS[platform]?.name || platform;
}

// 根据 targetAccounts 获取关联的平台列表（Bug #6066: 显示渠道）
function getTaskPlatforms(task: PublishTask): PlatformType[] {
  const ids = new Set(task.targetAccounts || []);
  const platforms = new Set<PlatformType>();
  for (const account of accounts.value) {
    if (ids.has(Number(account.id))) {
      platforms.add(account.platform);
    }
  }
  return Array.from(platforms);
}

function getStatusType(status: string) {
  const types: Record<string, string> = {
    pending: 'info',
    processing: 'warning',
    completed: 'success',
    failed: 'danger',
    cancelled: 'info',
  };
  return types[status] || 'info';
}

function getStatusText(status: string) {
  const texts: Record<string, string> = {
    pending: '待发布',
    processing: '发布中',
    completed: '已完成',
    failed: '失败',
    cancelled: '已取消',
  };
  return texts[status] || status;
}

function formatDate(date: string) {
  return dayjs(date).format('YYYY-MM-DD HH:mm');
}

// 检查是否是验证码错误
function isCaptchaError(errorMessage: string | null | undefined): boolean {
  return !!errorMessage && errorMessage.includes('CAPTCHA_REQUIRED');
}

// 检查是否是"发布结果待确认，请查看截图"类错误
function isScreenshotPendingError(errorMessage: string | null | undefined): boolean {
  return !!errorMessage && errorMessage.includes('请查看截图');
}

// 是否可以使用有头浏览器重新发布
function canRetryWithHeadful(row: { platform: string; status: string | null | undefined }): boolean {
  if (row.status !== 'failed') return false;
  return row.platform === 'xiaohongshu' || row.platform === 'baijiahao' || row.platform === 'douyin' || row.platform === 'weixin_video';
}

// 打开查看截图（平台暂打开创作者中心，用户可自行查看发布状态）
function openScreenshotView(row: { platform: string; accountId: number }) {
  if (row.platform === 'xiaohongshu') {
    window.open('https://creator.xiaohongshu.com/publish/publish', '_blank', 'noopener,noreferrer');
    return;
  }
  if (row.platform === 'baijiahao') {
    window.open('https://baijiahao.baidu.com/builder/rc/content', '_blank', 'noopener,noreferrer');
    return;
  }
  if (row.platform === 'douyin') {
    window.open('https://creator.douyin.com/creator-micro/content/upload', '_blank', 'noopener,noreferrer');
    return;
  }
  if (row.platform === 'weixin_video') {
    window.open('https://channels.weixin.qq.com/platform', '_blank', 'noopener,noreferrer');
    return;
  }
  ElMessage.info('请前往对应平台查看发布状态');
}

// 是否存在待确认的发布结果
const hasPendingConfirmResults = computed(() => {
  const results = taskDetail.value?.results || [];
  return results.some(r => isScreenshotPendingError(r.errorMessage));
});

// 确认所有待确认的发布结果
async function confirmAllPendingResults() {
  if (!currentTask.value || !taskDetail.value?.results?.length) return;
  const pending = taskDetail.value.results.filter(r => isScreenshotPendingError(r.errorMessage));
  if (!pending.length) return;
  try {
    for (const r of pending) {
      await request.post(`/api/publish/${currentTask.value.id}/results/${r.id}/confirm`);
    }
    ElMessage.success('已确认发布成功');
    const detail = await request.get(`/api/publish/${currentTask.value.id}`);
    taskDetail.value = detail;
  } catch {
    ElMessage.error('确认失败');
  }
}

// 使用有头浏览器重新执行发布流程（用于验证码场景）
async function openBrowserForCaptcha(accountId: number, platform: string) {
  if (!currentTask.value) {
    ElMessage.error('任务信息不存在');
    return;
  }
  
  const account = accounts.value.find(a => a.id === accountId);
  const accountName = account?.accountName || `账号${accountId}`;
  const taskId = currentTask.value.id;
  
  // 确认操作
  try {
    await ElMessageBox.confirm(
      `即将使用有头浏览器重新发布到 ${accountName}。\n\n浏览器会自动执行发布流程，遇到验证码时会暂停等待您手动操作。\n\n确认继续吗？`,
      '有头浏览器发布',
      {
        confirmButtonText: '开始发布',
        cancelButtonText: '取消',
        type: 'info',
      }
    );
  } catch {
    // 用户取消
    return;
  }
  
  // 关闭详情对话框
  showDetailDialog.value = false;
  
  // 显示正在执行的提示
  const loadingInstance = ElLoading.service({
    lock: true,
    text: `正在使用有头浏览器发布到 ${accountName}，请在弹出的浏览器窗口中完成验证码验证...`,
    background: 'rgba(0, 0, 0, 0.7)',
  });
  
  try {
    // 调用后端 API 执行有头浏览器发布
    const result = await request.post(`/api/publish/${taskId}/retry-headful/${accountId}`);
    
    loadingInstance.close();
    
    if (result.success) {
      ElMessage.success(`${accountName} 发布成功！`);
    } else {
      ElMessage.error(result.error || `${accountName} 发布失败`);
    }
    
    // 刷新任务列表
    await loadTasks();
    
  } catch (error: unknown) {
    loadingInstance.close();
    const errorMsg = error instanceof Error ? error.message : '发布失败';
    ElMessage.error(errorMsg);
  }
}

async function loadTasks() {
  loading.value = true;
  try {
    const result = await request.get('/api/publish', {
      params: {
        page: pagination.page,
        pageSize: pagination.pageSize,
      },
    });
    tasks.value = result.items;
    pagination.total = result.total;
  } catch {
    // 错误已处理
  } finally {
    loading.value = false;
  }
}

async function loadAccounts() {
  try {
    // 获取所有账号，不限制状态
    accounts.value = await accountsApi.getAccounts();
  } catch {
    // 错误已处理
  }
}

function handleFileChange(file: UploadFile) {
  createForm.videoFile = file.raw || null;
}

async function handleCreate() {
  if (createForm.targetAccounts.length === 0) {
    ElMessage.warning('请至少选择一个目标账号');
    return;
  }
  if (createRequireTitle.value && !createForm.title) {
    ElMessage.warning('所选平台要求标题必填');
    return;
  }
  if (createRequireDescription.value && !createForm.description) {
    ElMessage.warning('所选平台要求正文必填');
    return;
  }
  if (createRequireVideo.value && !createForm.videoFile) {
    ElMessage.warning('所选平台要求视频必填');
    return;
  }

  if (createForm.usePublishProxy && publishProxyRegions.value.length > 0 && !createForm.publishProxyRegionPath.length) {
    ElMessage.warning('请选择代理城市');
    return;
  }
  
  submitting.value = true;
  try {
    // 1. 上传视频
    const formData = new FormData();
    formData.append('video', createForm.videoFile);
    
    const uploadResult = await request.post('/api/upload/video', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    
    // 2. 创建发布任务
    const proxy = createForm.usePublishProxy
      ? resolvePublishProxyFromRegionPath(createForm.publishProxyRegionPath)
      : null;

    await request.post('/api/publish', {
      videoPath: uploadResult.path,
      videoFilename: uploadResult.originalname,
      title: createForm.title,
      description: createForm.description,
      tags: createForm.tags,
      targetAccounts: createForm.targetAccounts,
      scheduledAt: createForm.scheduledAt ? createForm.scheduledAt.toISOString() : null,
      publishProxy: proxy
        ? {
            enabled: true,
            provider: 'shenlong',
            city: proxy.city,
            regionCode: proxy.regionCode,
            regionName: proxy.regionName,
            regionPath: proxy.regionPath,
          }
        : null,
    });
    
    ElMessage.success('发布任务创建成功');
    showCreateDialog.value = false;
    
    // 重置表单
    createForm.videoFile = null;
    createForm.title = '';
    createForm.description = '';
    createForm.tags = [];
    createForm.targetAccounts = [];
    createForm.scheduledAt = null;
    createForm.usePublishProxy = false;
    createForm.publishProxyRegionPath = [];
    
    loadTasks();
  } catch {
    // 错误已处理
  } finally {
    submitting.value = false;
  }
}

async function viewDetail(task: PublishTask) {
  currentTask.value = task;
  showDetailDialog.value = true;
  
  // 加载任务详情（包含发布结果）
  try {
    const detail = await request.get(`/api/publish/${task.id}`);
    taskDetail.value = detail;
  } catch {
    // 错误已处理
  }
}

function openEditDialog() {
  if (!currentTask.value) return;
  
  // 复制当前任务信息到编辑表单
  editForm.videoFile = null;
  editForm.videoPath = currentTask.value.videoPath || '';
  editForm.videoFilename = currentTask.value.videoFilename || '';
  editForm.title = currentTask.value.title || '';
  editForm.description = currentTask.value.description || '';
  editForm.tags = [...(currentTask.value.tags || [])];
  const originalTargetAccounts = [...(currentTask.value.targetAccounts || [])];
  editForm.targetAccounts = sanitizeTargetAccounts(originalTargetAccounts);
  editForm.scheduledAt = null;
  editForm.usePublishProxy = Boolean(currentTask.value.publishProxy?.enabled);
  editForm.publishProxyRegionPath = Array.isArray((currentTask.value.publishProxy as any)?.regionPath)
    ? normalizePublishProxyCityRegionPath((currentTask.value.publishProxy as any).regionPath)
    : [];

  if (originalTargetAccounts.length > 0 && editForm.targetAccounts.length !== originalTargetAccounts.length) {
    ElMessage.warning('原任务中的部分账号已不可用，已自动移除，请重新选择可用账号');
  }

  const regionCode = String((currentTask.value.publishProxy as any)?.regionCode || '').trim();
  if (editForm.usePublishProxy && !editForm.publishProxyRegionPath.length && regionCode && publishProxyRegions.value.length > 0) {
    const inferred = findRegionPathByCode(publishProxyRegions.value, regionCode);
    if (inferred) editForm.publishProxyRegionPath = normalizePublishProxyCityRegionPath(inferred);
  }
  
  showDetailDialog.value = false;
  showEditDialog.value = true;
}

function handleEditFileChange(file: UploadFile) {
  editForm.videoFile = file.raw || null;
  if (file.raw) {
    editForm.videoFilename = file.raw.name;
  }
}

async function handleRepublish() {
  const targetAccounts = sanitizeTargetAccounts(editForm.targetAccounts);
  editForm.targetAccounts = targetAccounts;

  if (!editForm.title || targetAccounts.length === 0) {
    ElMessage.warning('请填写完整信息');
    return;
  }

  if (editForm.usePublishProxy && publishProxyRegions.value.length > 0 && !editForm.publishProxyRegionPath.length) {
    ElMessage.warning('请选择代理城市');
    return;
  }
  
  submitting.value = true;
  try {
    let videoPath = editForm.videoPath;
    
    // 如果选择了新视频，先上传
    if (editForm.videoFile) {
      const formData = new FormData();
      formData.append('video', editForm.videoFile);
      
      const uploadResult = await request.post('/api/upload/video', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      videoPath = uploadResult.path;
    }
    
    // 创建新的发布任务
    const proxy = editForm.usePublishProxy
      ? resolvePublishProxyFromRegionPath(editForm.publishProxyRegionPath)
      : null;

    await request.post('/api/publish', {
      videoPath,
      videoFilename: editForm.videoFilename,
      title: editForm.title,
      description: editForm.description,
      tags: editForm.tags,
      targetAccounts,
      scheduledAt: editForm.scheduledAt ? editForm.scheduledAt.toISOString() : null,
      publishProxy: proxy
        ? {
            enabled: true,
            provider: 'shenlong',
            city: proxy.city,
            regionCode: proxy.regionCode,
            regionName: proxy.regionName,
            regionPath: proxy.regionPath,
          }
        : null,
    });
    
    ElMessage.success('新发布任务已创建');
    showEditDialog.value = false;
    loadTasks();
  } catch {
    // 错误已处理
  } finally {
    submitting.value = false;
  }
}

async function cancelTask(id: number) {
  try {
    await ElMessageBox.confirm('确定要取消该任务吗？', '提示');
    await request.post(`/api/publish/${id}/cancel`);
    ElMessage.success('任务已取消');
    loadTasks();
  } catch {
    // 取消或错误
  }
}

async function retryTask(id: number) {
  try {
    await request.post(`/api/publish/${id}/retry`);
    ElMessage.success('任务已重新开始');
    loadTasks();
  } catch {
    // 错误已处理
  }
}

async function deleteTask(id: number) {
  try {
    await ElMessageBox.confirm('确定要删除该任务吗？删除后不可恢复。', '提示', {
      type: 'warning',
    });
    await request.delete(`/api/publish/${id}`);
    ElMessage.success('任务已删除');
    loadTasks();
  } catch {
    // 取消或错误
  }
}

// 监听 taskStore 的任务列表变化，当发布任务完成时刷新列表
watch(() => taskStore.tasks, (newTasks, oldTasks) => {
  // 检查是否有发布任务状态变化
  const hasPublishTaskChange = newTasks.some(task => {
    if (task.type !== 'publish_video') return false;
    const oldTask = oldTasks?.find(t => t.id === task.id);
    return !oldTask || oldTask.status !== task.status;
  });
  
  if (hasPublishTaskChange) {
    loadTasks();
  }
}, { deep: true });

onMounted(() => {
  loadTasks();
  loadAccounts();
  loadSystemConfig();
});
</script>

<style lang="scss" scoped>
@use '@/styles/variables.scss' as *;

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  
  h2 {
    margin: 0;
  }
  
  .header-actions {
    display: flex;
    align-items: center;
  }
}

.video-info {
  .video-title {
    font-weight: 500;
  }
  
  .video-file {
    font-size: 12px;
    color: $text-secondary;
    margin-top: 4px;
  }
}

.form-tip {
  margin-left: 12px;
  color: $text-secondary;
  font-size: 13px;
}

.publish-results {
  margin-top: 20px;
  
  h4 {
    margin: 0 0 12px;
    font-size: 14px;
    color: var(--el-text-color-primary);
  }
}

.captcha-error,
.screenshot-pending {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.normal-error {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.account-option {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  
  .account-name {
    font-weight: 500;
  }
}

:deep(.el-checkbox-group) {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

:deep(.el-checkbox) {
  height: auto;
  
  .el-checkbox__label {
    padding-left: 8px;
  }
}
</style>
