/**
 * 发布流程集成测试
 * 测试发布→可见性完整流程
 */

import { describe, it, expect, beforeAll } from 'vitest';
import { apiGet, apiPost, apiPut, apiDelete, setAuthToken, initHttpClient, createTestUser } from '../../integration/http-client';

describe('发布流程集成测试', () => {
  let authToken: string;
  let userId: string;
  let testBookId: number;

  beforeAll(async () => {
    try {
      const user = await createTestUser();
      authToken = user.token;
      userId = user.userId;
      setAuthToken(authToken);
    } catch (e) {
      console.log('创建测试用户失败，跳过部分测试');
    }
  });

  describe('Step 1: 创建可发布的内容', () => {
    it('创建书籍', async () => {
      if (!authToken) return;

      const res = await apiPost('/api/book-generator/langgraph/create', {
        title: `发布测试书籍_${Date.now()}`,
        topic: '测试主题',
        wordCount: 10000,
        strategy: 'deep-plan-parallel',
      });

      expect(res.code).toBe(0);
      expect(res.data?.bookId).toBeDefined();
      testBookId = res.data?.bookId;
    });

    it('新创建书籍初始状态为草稿', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiGet(`/api/book-generator/langgraph/books/${testBookId}`);
      expect(res.code).toBe(0);
      // 初始状态应该是 draft 或类似
      expect(res.data?.status).toBeDefined();
    });
  });

  describe('Step 2: 发布状态管理', () => {
    it('获取当前发布状态', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiGet(`/api/book-generator/langgraph/books/${testBookId}`);
      expect(res.code).toBe(0);
      expect(res.data).toHaveProperty('status');
    });

    it('发布书籍', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiPut(`/api/book-generator/langgraph/books/${testBookId}/publish`);
      // 发布可能因状态限制返回不同结果，但不应是认证/权限错误
      expect(res.code).toBeDefined();
      expect([401, 403]).not.toContain(res.code);
    });

    it('已发布书籍状态更新', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiGet(`/api/book-generator/langgraph/books/${testBookId}`);
      expect(res.code).toBe(0);
      // 发布后状态应该变化
      expect(res.data?.status).toBeDefined();
    });

    it('取消发布', async () => {
      if (!authToken || !testBookId) return;

      // 再次调用发布接口应该可以切换状态
      const res = await apiPut(`/api/book-generator/langgraph/books/${testBookId}/publish`);
      // 发布/取消发布返回结果取决于当前状态，但不应是认证/权限错误
      expect(res.code).toBeDefined();
      expect([401, 403]).not.toContain(res.code);
    });
  });

  describe('Step 3: 发布可见性验证', () => {
    it('发布的书籍在列表中可见', async () => {
      if (!authToken) return;

      const res = await apiGet('/api/book-generator/langgraph/books');
      expect(res.code).toBe(0);
      expect(Array.isArray(res.data?.books)).toBe(true);

      // 如果之前发布了书籍，列表中应该能看到
      if (testBookId) {
        const found = res.data?.books?.some((b: any) => b.id === testBookId);
        expect(found).toBe(true);
      }
    });

    it('搜索接口能查到已发布内容', async () => {
      if (!authToken) return;

      // 搜索接口
      const res = await apiGet('/api/search', { keyword: '测试' });
      // 搜索可能返回任何结果
      expect(res.code).toBeDefined();
    });
  });

  describe('Step 4: 发布权限验证', () {
    it('未登录用户无法发布', async () => {
      // 设置无效 token
      setAuthToken('invalid_token');

      const res = await apiPut(`/api/book-generator/langgraph/books/${testBookId}/publish`);
      expect(res.code).not.toBe(0);
    });

    it('无书籍所有权的用户无法发布', async () => {
      if (!authToken) return;

      // 尝试发布不属于自己的书籍（ID 不存在或属于其他用户）
      const res = await apiPut('/api/book-generator/langgraph/books/99999/publish');
      // 应该返回权限错误(403)或不存在(404)，不应成功(0)
      expect([401, 403, 404]).toContain(res.code);
      expect(res.code).not.toBe(0);
    });
  });

  describe('Step 5: 发布后清理', () => {
    it('删除已发布的书籍', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiDelete(`/api/book-generator/langgraph/books/${testBookId}`);
      // 删除成功或返回权限错误(403)/不存在(404)，不应是认证错误(401)
      expect(res.code).toBeDefined();
      expect(res.code).not.toBe(401);
    });

    it('删除后列表中不再可见', async () => {
      if (!authToken || !testBookId) return;

      const res = await apiGet('/api/book-generator/langgraph/books');
      expect(res.code).toBe(0);

      // 被删除的书籍不应该在列表中
      const found = res.data?.books?.some((b: any) => b.id === testBookId);
      // 删除后可能返回 404 或列表中不存在
      expect(found).toBe(false);
    });
  });
});