// 模拟 PrintDevice 枚举
enum PrintDevice {
  Printer = 'Printer'
}

// 模拟 XpsDocument 类
class XpsDocument {
  constructor(private filePath: string, private access: string) {}
  CoreDocumentProperties = {
    Title: '',
    Description: '',
    Subject: '',
    ContentType: 'false'
  };
  getFixedDocumentSequence() {
    return {
      DocumentPaginator: {
        PageCount: 1,
        ComputePageCount() {},
        GetPage(index: number) {
          return {
            Visual: new FixedPage()
          };
        }
      }
    };
  }
  close() {}
}

// 模拟 FixedPage 类
class FixedPage {
  Children: any[] = [];
  Width = 0;
  Height = 0;
  Margin = { Left: 0, Top: 0, Right: 0, Bottom: 0 };
  addChild(child: any) {
    this.Children.push(child);
  }
}

// 模拟 FrameworkElement 类
class FrameworkElement {}

// 模拟 FileInfo 类
class FileInfo {
  constructor(public FullName: string) {}
  get Directory() {
    return {
      Exists: false,
      Create() {}
    };
  }
  get Exists() {
    return false;
  }
  Delete() {}
  CopyTo(destination: string, overwrite: boolean) {}
}

// 模拟 PlatformLogger 类
class PlatformLogger {
  static SystemErrorInfo(message: string, error: any) {
    console.error(message, error);
  }
}

// 模拟 DependencyObjectExtensions 类
class DependencyObjectExtensions {
  static FindVisualTreeChildren(parent: any, predicate: (item: any) => boolean) {
    return [];
  }
}

// 模拟 Glyphs 类
class Glyphs {
  Indices = '';
  FontUri = '';
}

// 模拟 ZipPackage 类
class ZipPackage {
  static Open(filePath: string) {
    return new ZipPackage();
  }
  GetPart(uri: string) {
    return {
      GetStream() {
        return {
          Length: 1024
        };
      }
    };
  }
  close() {}
}

// 模拟 Process 类
class Process {
  static GetProcessesByName(name: string) {
    return [];
  }
  StartInfo = {
    FileName: ''
  };
  Start() {}
}

// 模拟 AppDomain 类
class AppDomain {
  static get CurrentDomain() {
    return {
      BaseDirectory: ''
    };
  }
}

// 模拟 Platform.Common.RunningParameters.PlatformSettings 类
namespace Platform {
  export namespace Common {
    export namespace RunningParameters {
      export class PlatformSettings {
        static PrinterOffset = {
          X: 0,
          Y: 0
        };
      }
    }
  }
}

export class PrintManager {
  private _xpsFile: FileInfo;
  private _device: PrintDevice;
  private _isReprint: boolean;
  private _printBitmap: any;

  public Title: string;
  public Description: string;
  public Subject: string;
  public IsPrinted: boolean = false;
  public IsNotingPreview: boolean;
  public PrintElement: FixedPage;
  public ReprintFile: FileInfo;

  public static ReprintMarkup: FrameworkElement;

  constructor(file: FileInfo, printDevice: PrintDevice, reprint: boolean) {
    this._xpsFile = file;
    this._device = printDevice;
    this._isReprint = reprint;
    this.PrintElement = this.RenderPrintElement();
  }

  private RenderPrintElement(): FixedPage {
    const xpsDoc = new XpsDocument(this._xpsFile.FullName, 'Read');
    this.Title = xpsDoc.CoreDocumentProperties.Title;
    this.Description = xpsDoc.CoreDocumentProperties.Description;
    this.Subject = xpsDoc.CoreDocumentProperties.Subject;
    this.IsNotingPreview = Boolean(xpsDoc.CoreDocumentProperties.ContentType);

    const paginator = xpsDoc.getFixedDocumentSequence().DocumentPaginator;
    paginator.ComputePageCount();
    if (paginator.PageCount === 0) {
      throw new Error('xps文档为空文档！');
    }

    const visual = paginator.GetPage(0).Visual as FixedPage;
    if (!visual) {
      throw new Error('xps文档页面数据非法！');
    }

    if (this._isReprint) {
      let reprintMark = PrintManager.ReprintMarkup;
      if (!reprintMark) {
        const markup = new FrameworkElement();
        reprintMark = markup;
      }
      visual.addChild(reprintMark);
    }

    xpsDoc.close();

    const glyphs = DependencyObjectExtensions.FindVisualTreeChildren(visual, (x) => x instanceof Glyphs).map((x) => x as Glyphs);
    if (glyphs.length > 0) {
      const g = glyphs.find((x) => x.Indices !== '');
      if (g) {
        PlatformLogger.SystemErrorInfo(`打印乱码监测：从xps中发现Indices有效的Glyphs要素->${g.Indices}${this._xpsFile.FullName}`, null);
      }

      const zip = ZipPackage.Open(this._xpsFile.FullName);
      try {
        const part = zip.GetPart(glyphs[0].FontUri);
        const size = part.GetStream().Length / 1024;
        if (size < 100) {
          PlatformLogger.SystemErrorInfo(`打印乱码监测：从xps中发现小Size的字体文件->${size}${this._xpsFile.FullName}`, null);
        }
      } finally {
        zip.close();
      }
    }

    return visual;
  }

  private PrintImage() {
    this.ReprintFile = this.CrateReprintXps(this.PrintElement);
    if (this._device === PrintDevice.Printer) {
      PrintManager.SendToPrinter(this.ReprintFile, this.PrintElement.Width, this.PrintElement.Height, this.Title);
      this.IsPrinted = true;
    }
  }

  public static SendToPrinter(file: FileInfo, width: number, height: number, documentName: string | null = null, printerName: string | null = null) {
    const processes = Process.GetProcessesByName('Platform.PrintService');
    if (processes.length < 1) {
      const printProcess = new Process();
      printProcess.StartInfo.FileName = `${AppDomain.CurrentDomain.BaseDirectory}Platform.PrintService.exe`;
      printProcess.Start();
      // 模拟 Thread.Sleep
      setTimeout(() => {}, 1000);
    }

    let argumentsStr = `${file.FullName.replace(' ', '*')}&${documentName || file.FullName}&${width}&${height}&${printerName}`;
    PrintManager.SendMessage('D7D01788-86BC-4E9C-9BB9-041BF848EA4E', argumentsStr);
  }

  public static SendMessage(windowName: string, strMsg: string) {
    if (!strMsg) return;
    // 模拟 FindWindow 和 SendMessage
    console.log(`向窗口 ${windowName} 发送消息: ${strMsg}`);
  }

  private CrateReprintXps(page: FixedPage): FileInfo {
    let file: FileInfo | null = null;
    if (page) {
      file = new FileInfo(`print/${this._xpsFile.FullName}`);
      if (file.Exists) {
        file.Delete();
      }
      if (!file.Directory.Exists) {
        file.Directory.Create();
      }

      if (!this._isReprint) {
        this._xpsFile.CopyTo(file.FullName, true);
      } else {
        const doc = new XpsDocument(file.FullName, 'ReadWrite');
        doc.CoreDocumentProperties.Title = this.Title;
        doc.CoreDocumentProperties.Description = this.Description;
        if (this.Subject) {
          doc.CoreDocumentProperties.Subject = this.Subject;
        }

        const offsetX = Platform.Common.RunningParameters.PlatformSettings.PrinterOffset.X;
        const offsetY = Platform.Common.RunningParameters.PlatformSettings.PrinterOffset.Y;
        page.Margin = { Left: (offsetX * 96) / 25.4, Top: (offsetY * 96) / 25.4, Right: 0, Bottom: 0 };

        doc.close();
      }
    }
    return file!;
  }

  public Print() {
    this.PrintImage();
  }
}