import { GenericCrudService } from '@d8d/shared-crud';
import { DataSource, Repository } from 'typeorm';
import { FeiePrinterMt } from '../entities/feie-printer.mt.entity';
import { FeieApiService } from './feie-api.service';
import { FeieApiConfig, PrinterDto, UpdatePrinterDto, PrinterStatus } from '../types/feie.types';

export class PrinterService extends GenericCrudService<FeiePrinterMt> {
  private feieApiService: FeieApiService;
  private feieConfig: FeieApiConfig;

  constructor(dataSource: DataSource, feieConfig: FeieApiConfig) {
    super(dataSource, FeiePrinterMt, {
      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
    });

    this.feieConfig = feieConfig;
    this.feieApiService = new FeieApiService(feieConfig);
  }

  /**
   * 添加打印机
   */
  async addPrinter(tenantId: number, printerDto: PrinterDto): Promise<FeiePrinterMt> {
    // 验证打印机配置
    const isValid = await this.feieApiService.validatePrinterConfig(
      printerDto.printerSn,
      printerDto.printerKey
    );

    if (!isValid) {
      throw new Error('打印机配置验证失败，请检查序列号和密钥');
    }

    // 调用飞鹅API添加打印机
    await this.feieApiService.addPrinter({
      sn: printerDto.printerSn,
      key: printerDto.printerKey,
      name: printerDto.printerName,
      type: printerDto.printerType
    });

    // 如果设置为默认打印机，先取消其他默认打印机
    if (printerDto.isDefault) {
      await this.clearDefaultPrinter(tenantId);
    }

    // 创建打印机记录
    const printer = await this.create({
      tenantId,
      printerSn: printerDto.printerSn,
      printerKey: printerDto.printerKey,
      printerName: printerDto.printerName,
      printerType: printerDto.printerType || '58mm',
      printerStatus: PrinterStatus.ACTIVE,
      isDefault: printerDto.isDefault ? 1 : 0
    });

    return printer;
  }

  /**
   * 更新打印机
   */
  async updatePrinter(
    tenantId: number,
    printerSn: string,
    updateDto: UpdatePrinterDto
  ): Promise<FeiePrinterMt> {
    const printer = await this.findOne({
      where: { tenantId, printerSn }
    });

    if (!printer) {
      throw new Error('打印机不存在');
    }

    // 如果设置为默认打印机，先取消其他默认打印机
    if (updateDto.isDefault) {
      await this.clearDefaultPrinter(tenantId);
    }

    const updateData: Partial<FeiePrinterMt> = {};

    if (updateDto.printerName !== undefined) {
      updateData.printerName = updateDto.printerName;
    }

    if (updateDto.printerType !== undefined) {
      updateData.printerType = updateDto.printerType;
    }

    if (updateDto.printerStatus !== undefined) {
      updateData.printerStatus = updateDto.printerStatus;
    }

    if (updateDto.isDefault !== undefined) {
      updateData.isDefault = updateDto.isDefault ? 1 : 0;
    }

    return this.update(printer.id, updateData);
  }

  /**
   * 删除打印机
   */
  async deletePrinter(tenantId: number, printerSn: string): Promise<void> {
    const printer = await this.findOne({
      where: { tenantId, printerSn }
    });

    if (!printer) {
      throw new Error('打印机不存在');
    }

    // 调用飞鹅API删除打印机
    await this.feieApiService.deletePrinter(printerSn);

    // 删除数据库记录
    await this.delete(printer.id);
  }

  /**
   * 获取打印机列表
   */
  async getPrinters(tenantId: number): Promise<FeiePrinterMt[]> {
    return this.findMany({
      where: { tenantId },
      order: { isDefault: 'DESC', createdAt: 'DESC' }
    });
  }

  /**
   * 获取默认打印机
   */
  async getDefaultPrinter(tenantId: number): Promise<FeiePrinterMt | null> {
    return this.findOne({
      where: { tenantId, isDefault: 1 }
    });
  }

  /**
   * 查询打印机状态
   */
  async getPrinterStatus(tenantId: number, printerSn: string): Promise<any> {
    const printer = await this.findOne({
      where: { tenantId, printerSn }
    });

    if (!printer) {
      throw new Error('打印机不存在');
    }

    // 调用飞鹅API查询状态
    const status = await this.feieApiService.queryPrinterStatus(printerSn);

    // 更新本地状态
    const online = status.data && status.data.length > 0 ? status.data[0].online === 1 : false;
    const newStatus = online ? PrinterStatus.ACTIVE : PrinterStatus.INACTIVE;

    if (printer.printerStatus !== newStatus) {
      await this.update(printer.id, { printerStatus: newStatus });
    }

    return {
      ...status,
      localStatus: printer.printerStatus,
      isDefault: printer.isDefault === 1
    };
  }

  /**
   * 批量查询打印机状态
   */
  async batchGetPrinterStatus(tenantId: number): Promise<any[]> {
    const printers = await this.getPrinters(tenantId);
    const snList = printers.map(p => p.printerSn);

    if (snList.length === 0) {
      return [];
    }

    const status = await this.feieApiService.batchQueryPrinterStatus(snList);

    // 更新本地状态并返回结果
    const results = [];

    for (const printer of printers) {
      const remoteStatus = status.data?.find((s: any) => s.sn === printer.printerSn);
      const online = remoteStatus ? remoteStatus.online === 1 : false;
      const newStatus = online ? PrinterStatus.ACTIVE : PrinterStatus.INACTIVE;

      if (printer.printerStatus !== newStatus) {
        await this.update(printer.id, { printerStatus: newStatus });
      }

      results.push({
        printerSn: printer.printerSn,
        printerName: printer.printerName,
        printerType: printer.printerType,
        isDefault: printer.isDefault === 1,
        localStatus: newStatus,
        remoteStatus: remoteStatus || null,
        online
      });
    }

    return results;
  }

  /**
   * 清除默认打印机设置
   */
  private async clearDefaultPrinter(tenantId: number): Promise<void> {
    const defaultPrinter = await this.getDefaultPrinter(tenantId);

    if (defaultPrinter) {
      await this.update(defaultPrinter.id, { isDefault: 0 });
    }
  }

  /**
   * 设置默认打印机
   */
  async setDefaultPrinter(tenantId: number, printerSn: string): Promise<FeiePrinterMt> {
    const printer = await this.findOne({
      where: { tenantId, printerSn }
    });

    if (!printer) {
      throw new Error('打印机不存在');
    }

    // 清除其他默认打印机
    await this.clearDefaultPrinter(tenantId);

    // 设置新的默认打印机
    return this.update(printer.id, { isDefault: 1 });
  }

  /**
   * 获取可用的打印机
   */
  async getAvailablePrinters(tenantId: number): Promise<FeiePrinterMt[]> {
    return this.findMany({
      where: {
        tenantId,
        printerStatus: PrinterStatus.ACTIVE
      },
      order: { isDefault: 'DESC', createdAt: 'DESC' }
    });
  }
}