import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { DataSource } from 'typeorm';
import { createTestDataSource } from '@d8d/shared-test-util';
import { FeieApiService } from '../../src/services/feie-api.service';
import { PrinterService } from '../../src/services/printer.service';
import { PrintTaskService } from '../../src/services/print-task.service';
import { FeiePrinterMt } from '../../src/entities/feie-printer.mt.entity';
import { FeiePrintTaskMt } from '../../src/entities/feie-print-task.mt.entity';
import { FeieConfigMt } from '../../src/entities/feie-config.mt.entity';
import type { FeieApiConfig, PrinterDto, CreatePrintTaskDto } from '../../src/types/feie.types';

describe('飞鹅打印模块集成测试', () => {
  let dataSource: DataSource;
  let feieApiService: FeieApiService;
  let printerService: PrinterService;
  let printTaskService: PrintTaskService;

  // 测试配置 - 使用模拟配置，实际测试应该使用测试环境的飞鹅账号
  const testFeieConfig: FeieApiConfig = {
    baseUrl: process.env.TEST_FEIE_API_BASE_URL || 'http://api.feieyun.cn/Api/Open/',
    user: process.env.TEST_FEIE_API_USER || 'test_user',
    ukey: process.env.TEST_FEIE_API_UKEY || 'test_ukey',
    timeout: 5000,
    maxRetries: 1
  };

  beforeAll(async () => {
    // 创建测试数据库连接
    dataSource = await createTestDataSource({
      entities: [FeiePrinterMt, FeiePrintTaskMt, FeieConfigMt],
      synchronize: true,
      dropSchema: true
    });

    // 初始化服务
    feieApiService = new FeieApiService(testFeieConfig);
    printerService = new PrinterService(dataSource, testFeieConfig);
    printTaskService = new PrintTaskService(dataSource, testFeieConfig);
  });

  afterAll(async () => {
    if (dataSource && dataSource.isInitialized) {
      await dataSource.destroy();
    }
  });

  describe('数据库连接', () => {
    it('应该成功连接数据库', () => {
      expect(dataSource.isInitialized).toBe(true);
    });

    it('应该能够访问实体仓库', () => {
      const printerRepository = dataSource.getRepository(FeiePrinterMt);
      const taskRepository = dataSource.getRepository(FeiePrintTaskMt);
      const configRepository = dataSource.getRepository(FeieConfigMt);

      expect(printerRepository).toBeDefined();
      expect(taskRepository).toBeDefined();
      expect(configRepository).toBeDefined();
    });
  });

  describe('打印机管理', () => {
    const tenantId = 1;
    const testPrinter: PrinterDto = {
      printerSn: 'TEST_SN_' + Date.now(),
      printerKey: 'TEST_KEY_' + Date.now(),
      printerName: '测试打印机',
      printerType: '58mm',
      isDefault: true
    };

    it('应该能够添加打印机（模拟）', async () => {
      // 注意：实际测试需要有效的飞鹅账号
      // 这里我们主要测试服务层的逻辑，API调用会被模拟
      console.log('打印机添加测试（使用模拟配置）');

      // 由于我们使用测试配置，实际API调用会失败
      // 我们主要验证服务层的错误处理
      try {
        await printerService.addPrinter(tenantId, testPrinter);
        // 如果成功，验证打印机被创建
        const printers = await printerService.getPrinters(tenantId);
        expect(printers.length).toBeGreaterThan(0);
      } catch (error) {
        // 预期会失败，因为测试配置无效
        console.log('预期中的API调用失败:', error.message);
        expect(error).toBeDefined();
      }
    });

    it('应该能够查询打印机列表', async () => {
      // 直接测试数据库操作
      const printerRepository = dataSource.getRepository(FeiePrinterMt);

      // 创建测试数据
      const testPrinterData = printerRepository.create({
        tenantId,
        printerSn: 'TEST_QUERY_SN',
        printerKey: 'TEST_QUERY_KEY',
        printerName: '查询测试打印机',
        printerType: '80mm',
        printerStatus: 'ACTIVE',
        isDefault: 0
      });

      await printerRepository.save(testPrinterData);

      // 查询
      const printers = await printerService.getPrinters(tenantId);
      expect(Array.isArray(printers)).toBe(true);
    });

    it('应该能够设置默认打印机', async () => {
      // 创建两个打印机
      const printerRepository = dataSource.getRepository(FeiePrinterMt);

      const printer1 = printerRepository.create({
        tenantId,
        printerSn: 'DEFAULT_TEST_1',
        printerKey: 'KEY1',
        printerName: '打印机1',
        printerType: '58mm',
        printerStatus: 'ACTIVE',
        isDefault: 1
      });

      const printer2 = printerRepository.create({
        tenantId,
        printerSn: 'DEFAULT_TEST_2',
        printerKey: 'KEY2',
        printerName: '打印机2',
        printerType: '80mm',
        printerStatus: 'ACTIVE',
        isDefault: 0
      });

      await printerRepository.save([printer1, printer2]);

      // 设置打印机2为默认
      await printerService.setDefaultPrinter(tenantId, 'DEFAULT_TEST_2');

      // 验证
      const defaultPrinter = await printerService.getDefaultPrinter(tenantId);
      expect(defaultPrinter).toBeDefined();
      expect(defaultPrinter?.printerSn).toBe('DEFAULT_TEST_2');
      expect(defaultPrinter?.isDefault).toBe(1);
    });
  });

  describe('打印任务管理', () => {
    const tenantId = 2;
    let testPrinterSn: string;

    beforeAll(async () => {
      // 创建测试打印机
      const printerRepository = dataSource.getRepository(FeiePrinterMt);
      testPrinterSn = 'TASK_TEST_SN_' + Date.now();

      const testPrinter = printerRepository.create({
        tenantId,
        printerSn: testPrinterSn,
        printerKey: 'TASK_TEST_KEY',
        printerName: '任务测试打印机',
        printerType: '58mm',
        printerStatus: 'ACTIVE',
        isDefault: 1
      });

      await printerRepository.save(testPrinter);
    });

    it('应该能够创建立即打印任务', async () => {
      const taskDto: CreatePrintTaskDto = {
        printerSn: testPrinterSn,
        content: '<CB>测试打印内容</CB><BR>',
        printType: 'RECEIPT',
        delaySeconds: 0
      };

      const task = await printTaskService.createPrintTask(tenantId, taskDto);

      expect(task).toBeDefined();
      expect(task.taskId).toBeDefined();
      expect(task.printerSn).toBe(testPrinterSn);
      expect(task.printType).toBe('RECEIPT');
      expect(task.printStatus).toBe('PENDING'); // 立即打印任务状态为PENDING
    });

    it('应该能够创建延迟打印任务', async () => {
      const taskDto: CreatePrintTaskDto = {
        printerSn: testPrinterSn,
        content: '<CB>延迟打印测试</CB><BR>',
        printType: 'RECEIPT',
        delaySeconds: 10 // 10秒延迟
      };

      const task = await printTaskService.createPrintTask(tenantId, taskDto);

      expect(task).toBeDefined();
      expect(task.printStatus).toBe('DELAYED');
      expect(task.scheduledAt).toBeDefined();
      expect(task.scheduledAt).toBeInstanceOf(Date);
    });

    it('应该能够查询打印任务列表', async () => {
      const result = await printTaskService.getPrintTasks(tenantId, {}, 1, 10);

      expect(result).toBeDefined();
      expect(result.tasks).toBeInstanceOf(Array);
      expect(result.total).toBeGreaterThanOrEqual(0);
    });

    it('应该能够根据条件筛选打印任务', async () => {
      const filters = {
        printerSn: testPrinterSn,
        printType: 'RECEIPT' as const
      };

      const result = await printTaskService.getPrintTasks(tenantId, filters, 1, 10);

      expect(result).toBeDefined();
      // 验证筛选条件
      if (result.tasks.length > 0) {
        result.tasks.forEach(task => {
          expect(task.printerSn).toBe(testPrinterSn);
          expect(task.printType).toBe('RECEIPT');
        });
      }
    });
  });

  describe('错误处理', () => {
    const tenantId = 3;

    it('应该在打印机不存在时抛出错误', async () => {
      const taskDto: CreatePrintTaskDto = {
        printerSn: 'NONEXISTENT_PRINTER',
        content: '测试内容',
        printType: 'RECEIPT'
      };

      await expect(printTaskService.createPrintTask(tenantId, taskDto))
        .rejects
        .toThrow('打印机不存在');
    });

    it('应该在打印任务不存在时抛出错误', async () => {
      await expect(printTaskService.getPrintTaskStatus(tenantId, 'NONEXISTENT_TASK'))
        .rejects
        .toThrow('打印任务不存在');
    });
  });
});