import { describe, it, expect, vi, beforeEach } from 'vitest';
import { DocumentService } from '../document.service';
import { apiClient } from '../api';

vi.mock('../api', () => ({
  apiClient: {
    get: vi.fn(),
    post: vi.fn(),
    put: vi.fn(),
    delete: vi.fn(),
  },
}));

describe('DocumentService', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('create', () => {
    const mockCreateData = {
      content: '测试内容',
      title: '测试标题',
      category_id: 'cat-1',
    };

    const mockResponse = {
      data: {
        success: true,
        data: {
          id: 'doc-1',
          content: '测试内容',
          title: '测试标题',
          created_at: '2024-01-01',
        },
      },
    };

    it('应该创建文档', async () => {
      vi.mocked(apiClient.post).mockResolvedValueOnce(mockResponse);

      const result = await DocumentService.create(mockCreateData);

      expect(apiClient.post).toHaveBeenCalledWith('/documents', mockCreateData);
      expect(result).toEqual(mockResponse.data.data);
    });

    it('应该处理空内容错误', async () => {
      const errorResponse = {
        response: {
          data: {
            success: false,
            error: '文档内容不能为空',
          },
        },
      };
      vi.mocked(apiClient.post).mockRejectedValueOnce(errorResponse);

      await expect(DocumentService.create({ content: '' })).rejects.toThrow('文档内容不能为空');
    });
  });

  describe('getUserDocuments', () => {
    it('应该获取用户文档列表', async () => {
      const mockResponse = {
        data: {
          success: true,
          data: [
            { id: '1', title: '文档1', content: '内容1' },
            { id: '2', title: '文档2', content: '内容2' },
          ],
          count: 2,
        },
      };
      vi.mocked(apiClient.get).mockResolvedValueOnce(mockResponse);

      const result = await DocumentService.getUserDocuments();

      expect(apiClient.get).toHaveBeenCalledWith('/documents');
      expect(result).toEqual(mockResponse.data.data);
    });

    it('应该支持分页参数', async () => {
      vi.mocked(apiClient.get).mockResolvedValueOnce({ data: { success: true, data: [] } });

      await DocumentService.getUserDocuments({ page: 2, limit: 20 });

      expect(apiClient.get).toHaveBeenCalledWith('/documents?page=2&limit=20');
    });
  });

  describe('getById', () => {
    it('应该获取指定文档', async () => {
      const mockResponse = {
        data: {
          success: true,
          data: { id: 'doc-1', title: '标题', content: '内容' },
        },
      };
      vi.mocked(apiClient.get).mockResolvedValueOnce(mockResponse);

      const result = await DocumentService.getById('doc-1');

      expect(apiClient.get).toHaveBeenCalledWith('/documents/doc-1');
      expect(result).toEqual(mockResponse.data.data);
    });

    it('应该处理文档不存在', async () => {
      const errorResponse = {
        response: {
          data: {
            success: false,
            error: '文档不存在',
          },
          status: 404,
        },
      };
      vi.mocked(apiClient.get).mockRejectedValueOnce(errorResponse);

      await expect(DocumentService.getById('nonexistent')).rejects.toThrow('文档不存在');
    });
  });

  describe('update', () => {
    const mockUpdateData = {
      title: '更新标题',
      content: '更新内容',
    };

    it('应该更新文档', async () => {
      const mockResponse = {
        data: {
          success: true,
          data: { id: 'doc-1', ...mockUpdateData },
        },
      };
      vi.mocked(apiClient.put).mockResolvedValueOnce(mockResponse);

      const result = await DocumentService.update('doc-1', mockUpdateData);

      expect(apiClient.put).toHaveBeenCalledWith('/documents/doc-1', mockUpdateData);
      expect(result).toEqual(mockResponse.data.data);
    });
  });

  describe('delete', () => {
    it('应该删除文档', async () => {
      const mockResponse = {
        data: {
          success: true,
          message: '文档已删除',
        },
      };
      vi.mocked(apiClient.delete).mockResolvedValueOnce(mockResponse);

      await DocumentService.delete('doc-1');

      expect(apiClient.delete).toHaveBeenCalledWith('/documents/doc-1');
    });

    it('应该处理删除失败', async () => {
      const errorResponse = {
        response: {
          data: {
            success: false,
            error: '删除失败',
          },
        },
      };
      vi.mocked(apiClient.delete).mockRejectedValueOnce(errorResponse);

      await expect(DocumentService.delete('doc-1')).rejects.toThrow('删除失败');
    });
  });

  describe('search', () => {
    it('应该搜索文档', async () => {
      const mockResponse = {
        data: {
          success: true,
          data: [{ id: '1', title: '搜索结果', content: '内容' }],
        },
      };
      vi.mocked(apiClient.get).mockResolvedValueOnce(mockResponse);

      const result = await DocumentService.search('关键词');

      expect(apiClient.get).toHaveBeenCalledWith('/documents/search?q=%E5%85%B3%E9%94%AE%E8%AF%8D');
      expect(result).toEqual(mockResponse.data.data);
    });
  });
});
