import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { AuthService } from '../auth.service';
import { apiClient } from '../api';

// Mock axios client
vi.mock('../api', () => ({
  apiClient: {
    post: vi.fn(),
    get: vi.fn(),
  },
}));

describe('AuthService', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
  });

  afterEach(() => {
    localStorage.clear();
  });

  describe('login', () => {
    const mockLoginData = {
      username: 'testuser',
      password: 'password123',
    };

    const mockResponse = {
      data: {
        success: true,
        data: {
          token: 'test-token',
          user: {
            id: '1',
            username: 'testuser',
            email: 'test@example.com',
            created_at: '2024-01-01',
            updated_at: '2024-01-01',
          },
        },
      },
    };

    it('应该成功登录', async () => {
      vi.mocked(apiClient.post).mockResolvedValueOnce(mockResponse);

      const result = await AuthService.login(mockLoginData);

      expect(apiClient.post).toHaveBeenCalledWith('/auth/login', mockLoginData);
      expect(result).toEqual(mockResponse.data.data);
      expect(localStorage.getItem('auth_token')).toBe('test-token');
    });

    it('应该抛出登录失败错误', async () => {
      const errorResponse = {
        response: {
          data: {
            success: false,
            error: '用户名或密码错误',
          },
        },
      };
      vi.mocked(apiClient.post).mockRejectedValueOnce(errorResponse);

      await expect(AuthService.login(mockLoginData)).rejects.toThrow('用户名或密码错误');
    });

    it('应该验证必需字段', async () => {
      const invalidData = { username: '', password: '' };

      await expect(AuthService.login(invalidData)).rejects.toThrow();
    });
  });

  describe('register', () => {
    const mockRegisterData = {
      username: 'newuser',
      password: 'password123',
      email: 'new@example.com',
    };

    const mockResponse = {
      data: {
        success: true,
        data: {
          token: 'new-token',
          user: {
            id: '2',
            username: 'newuser',
            email: 'new@example.com',
            created_at: '2024-01-01',
            updated_at: '2024-01-01',
          },
        },
      },
    };

    it('应该成功注册', async () => {
      vi.mocked(apiClient.post).mockResolvedValueOnce(mockResponse);

      const result = await AuthService.register(mockRegisterData);

      expect(apiClient.post).toHaveBeenCalledWith('/auth/register', mockRegisterData);
      expect(result).toEqual(mockResponse.data.data);
      expect(localStorage.getItem('auth_token')).toBe('new-token');
    });

    it('应该处理用户名已存在', async () => {
      const errorResponse = {
        response: {
          data: {
            success: false,
            error: '用户名已存在',
          },
        },
      };
      vi.mocked(apiClient.post).mockRejectedValueOnce(errorResponse);

      await expect(AuthService.register(mockRegisterData)).rejects.toThrow('用户名已存在');
    });
  });

  describe('logout', () => {
    it('应该清除 token', () => {
      localStorage.setItem('auth_token', 'test-token');

      AuthService.logout();

      expect(localStorage.getItem('auth_token')).toBeNull();
    });

    it('应该多次调用不报错', () => {
      AuthService.logout();
      expect(() => AuthService.logout()).not.toThrow();
    });
  });

  describe('isAuthenticated', () => {
    it('有 token 时返回 true', () => {
      localStorage.setItem('auth_token', 'test-token');
      expect(AuthService.isAuthenticated()).toBe(true);
    });

    it('没有 token 时返回 false', () => {
      expect(AuthService.isAuthenticated()).toBe(false);
    });
  });
});
