//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { REGULAR } from '@/model/test-enum.ts';

// Mock 所有依赖
vi.mock('@/utils/composition.ts', () => ({
  getStoreData: vi.fn(),
  setStoreData: vi.fn(),
  resetLoctData: vi.fn(),
}));

vi.mock('@/utils/http-service.ts', () => ({
  default: {
    get: vi.fn(),
    post: vi.fn(),
  },
}));

vi.mock('@/utils/utils.ts', () => ({
  updateLocalLoginCount: vi.fn(),
}));

vi.mock('@/stores', () => ({
  default: vi.fn(() => ({
    state: {
      loct: { $state: {} },
    },
  })),
}));

describe('工具函数基础测试', () => {
  let localStorageMock;
  let URLMock;

  beforeEach(() => {
    vi.clearAllMocks();

    // Mock localStorage
    localStorageMock = {
      store: {},
      getItem: vi.fn(key => localStorageMock.store[key] || null),
      setItem: vi.fn((key, value) => {
        localStorageMock.store[key] = value.toString();
      }),
      removeItem: vi.fn(key => {
        delete localStorageMock.store[key];
      }),
      clear: vi.fn(() => {
        localStorageMock.store = {};
      }),
    };

    // Mock URL
    URLMock = {
      createObjectURL: vi.fn(() => 'blob:test-url'),
      revokeObjectURL: vi.fn(),
    };

    // Mock document
    const createElementMock = vi.fn(() => ({
      setAttribute: vi.fn(),
      href: '',
      download: '',
      click: vi.fn(),
    }));

    const bodyMock = {
      appendChild: vi.fn(),
    };

    // 设置全局对象
    vi.stubGlobal('localStorage', localStorageMock);
    vi.stubGlobal('URL', URLMock);
    vi.stubGlobal('document', {
      createElement: createElementMock,
      getElementsByTagName: vi.fn(() => [bodyMock]),
    });
  });

  describe('downloadFileWithResponse', () => {
    it('应该创建并触发下载链接', async () => {
      const moduleA = await import('@/utils/common-service.ts');
      const mockBlob = new Blob(['test content']);
      const fileName = 'test.txt';
      moduleA.downloadFileWithResponse(mockBlob, fileName);
      expect(document.createElement).toHaveBeenCalledWith('a');
      expect(URL.createObjectURL).toHaveBeenCalledWith(mockBlob);
      expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:test-url');
    });
  });

  describe('restDownloadFile', () => {
    it('应该成功下载文件', async () => {
      const moduleA = await import('@/utils/http-service.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const $http = moduleA.default;
      const mockResponse = {
        headers: {
          'content-disposition': 'attachment; filename=test.txt',
        },
        data: new Blob(['content']),
      };
      $http.get.mockResolvedValue(mockResponse);

      await expect(moduleB.restDownloadFile('/api/download')).resolves.toBeUndefined();
      expect($http.get).toHaveBeenCalledWith('/api/download', {
        responseType: 'blob',
      });
    });

    it('应该处理下载失败', async () => {
      const moduleA = await import('@/utils/http-service.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const $http = moduleA.default;
      $http.get.mockRejectedValue(new Error('Download failed'));

      await expect(moduleB.restDownloadFile('/api/download')).rejects.toThrow();
    });
  });

  describe('saveSessionData', () => {
    it('saveSessionData 应该调用 setStoreData 多次', async () => {
      // 解决 pinia 引入问题
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const sessionInfo = {
        Role: 'admin',
        SessionID: '123',
        UserID: 'user1',
        UserName: 'test',
        IP: '127.0.0.1',
        LoginTime: '2024-01-01T00:00:00Z',
      };
      moduleB.saveSessionData(sessionInfo);

      expect(moduleA.setStoreData).toHaveBeenCalledTimes(8); // 7次setStoreData + 1次saveStoreToLocal
    });

    it('应该保存会话数据到 store', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const sessionInfo = {
        Role: 'admin',
        SessionID: 'session123',
        UserID: 'user123',
        UserName: 'testuser',
        IP: REGULAR.IPV4_ADDRESS_VAILD_1,
        LoginTime: '2024-01-01T10:00:00.000Z',
      };
      moduleB.saveSessionData(sessionInfo);

      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'ur', 'admin');
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'rn', 'session123');
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'uid', 'user123');
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'un', 'testuser');
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'uip', REGULAR.IPV4_ADDRESS_VAILD_1);
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'utime', '2024-01-01 10:00:00');
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'isLogin', true);
      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'isExited', false);
    });

    it('应该处理没有 LoginTime 的情况', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');

      const sessionInfo = {
        Role: 'admin',
        SessionID: 'session123',
        UserID: 'user123',
        UserName: 'testuser',
        IP: REGULAR.IPV4_ADDRESS_VAILD_1,
        LoginTime: null,
      };

      moduleB.saveSessionData(sessionInfo);

      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'utime', '');
    });
  });

  describe('saveUserPermission', () => {
    it('应该保存用户权限', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const userRole = ['Admin'];
      const serverRoleList = [
        {
          Name: 'Admin',
          CanRead: true,
          CanWrite: true,
          CanDelete: false,
        },
        {
          Name: 'User',
          CanRead: true,
          CanWrite: false,
          CanDelete: false,
        },
      ];
      moduleB.saveUserPermission(userRole, serverRoleList);

      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'privil', ['CanRead', 'CanWrite']);
    });

    it('应该处理空权限列表', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      moduleB.saveUserPermission([], []);

      expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'privil', []);
    });
  });

  describe('clearCurrentLoginInfo', () => {
    it('应该清除登录信息', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      const moduleC = await import('@/utils/utils.ts');
      moduleB.clearCurrentLoginInfo();

      expect(moduleA.resetLoctData).toHaveBeenCalled();
      expect(moduleC.updateLocalLoginCount).toHaveBeenCalledWith('delete');
    });
  });

  describe('getBackgroundImage', () => {
    it('应该从 ptc 信息获取背景图', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      moduleA.getStoreData.mockReturnValue('default');
      localStorageMock.store.ptc = JSON.stringify({ login: '/custom/bg.jpg' });
      const result = moduleB.getBackgroundImage();

      expect(result).toBe('/custom/bg.jpg');
      expect(moduleA.getStoreData).toHaveBeenCalledWith('glob', 'webStyle');
    });

    it('应该返回默认背景图当 ptc 信息不存在', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      moduleA.getStoreData.mockReturnValue('default');
      const result = moduleB.getBackgroundImage();

      expect(result).toBe('/extern/custom/login.png');
    });
  });

  describe('getLogoImage', () => {
    it('应该从 ptc 信息获取 Logo', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      moduleA.getStoreData.mockReturnValue('default');
      localStorageMock.store.ptc = JSON.stringify({ logo: '/custom/logo.png' });
      const result = moduleB.getLogoImage();
      expect(result).toBe('/custom/logo.png');
    });

    it('应该返回默认 Logo 当 ptc 信息不存在', async () => {
      const moduleA = await import('@/utils/composition.ts');
      const moduleB = await import('@/utils/common-service.ts');
      moduleA.getStoreData.mockReturnValue('default');
      const result = moduleB.getLogoImage();

      expect(result).toBe('/extern/custom/login_logo.png');
    });

    it('应该接受 position 参数', async () => {
      const moduleB = await import('@/utils/common-service.ts');
      const result = moduleB.getLogoImage('header');
      expect(result).toBeDefined();
    });
  });

  it('saveUserPermission 应该提取权限', async () => {
    const moduleA = await import('@/utils/composition.ts');
    const moduleB = await import('@/utils/common-service.ts');
    const userRole = ['Admin'];
    const serverRoleList = [
      {
        Name: 'Admin',
        CanRead: true,
        CanWrite: true,
      },
    ];
    moduleB.saveUserPermission(userRole, serverRoleList);

    expect(moduleA.setStoreData).toHaveBeenCalledWith('loct', 'privil', ['CanRead', 'CanWrite']);
  });
});
