import { Injectable } from '@angular/core';
import { clearStamps, stampPDFPage } from '../../../utils';
import { FilePreviewStateService } from './file-preview-state.service';
import { ViewModeService } from './view-mode.service';
import { TranslateService } from '@ngx-translate/core';
import { Core } from '@pdftron/webviewer';
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
import { LicenseService } from '@services/license.service';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { WATERMARK_HORIZONTAL_ALIGNMENTS, WATERMARK_VERTICAL_ALIGNMENTS } from '@red/domain';
import PDFNet = Core.PDFNet;

@Injectable()
export class StampService {
    constructor(
        private readonly _pdf: PdfViewer,
        private readonly _documentViewer: REDDocumentViewer,
        private readonly _state: FilePreviewStateService,
        private readonly _viewModeService: ViewModeService,
        private readonly _translateService: TranslateService,
        private readonly _watermarksMapService: WatermarksMapService,
        private readonly _licenseService: LicenseService,
    ) {}

    async stampPDF(): Promise<void> {
        const pdfDoc = await this._documentViewer.PDFDoc;
        if (!pdfDoc) {
            return;
        }

        const file = this._state.file();
        const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);

        await pdfDoc.lock();
        try {
            await clearStamps(pdfDoc, this._pdf.PDFNet, allPages, this._licenseService.activeLicenseKey);
        } catch (e) {
            console.error('Error clearing stamps: ', e);
            return;
        }

        if (this._viewModeService.isRedacted()) {
            const { dossierTemplateId, previewWatermarkId } = this._state.dossier();
            if (previewWatermarkId) {
                await this._stampPreview(pdfDoc, dossierTemplateId, previewWatermarkId);
            }
        } else {
            await this._stampExcludedPages(pdfDoc, file.excludedPages);
        }

        this._documentViewer.refreshAndUpdateView(Array.from({ length: await pdfDoc.getPageCount() }, (_x, i) => i + 1));
        await pdfDoc.unlock();
    }

    private async _stampExcludedPages(document: PDFNet.PDFDoc, excludedPages: number[]): Promise<void> {
        if (excludedPages && excludedPages.length > 0) {
            await stampPDFPage(
                document,
                this._pdf.PDFNet,
                this._translateService.instant('file-preview.excluded-from-redaction') as string,
                17,
                'courier',
                'TOP_LEFT',
                WATERMARK_HORIZONTAL_ALIGNMENTS.CENTER,
                WATERMARK_VERTICAL_ALIGNMENTS.CENTER,
                50,
                '#dd4d50',
                excludedPages,
                this._licenseService.activeLicenseKey,
            );
        }
    }

    private async _stampPreview(document: PDFNet.PDFDoc, dossierTemplateId: string, watermarkId: number): Promise<void> {
        const watermark = this._watermarksMapService.get(dossierTemplateId, watermarkId);
        await stampPDFPage(
            document,
            this._pdf.PDFNet,
            watermark.text,
            watermark.fontSize,
            watermark.fontType,
            watermark.orientation,
            watermark.horizontalTextAlignment,
            watermark.verticalTextAlignment,
            watermark.opacity,
            watermark.hexColor,
            Array.from({ length: await document.getPageCount() }, (_x, i) => i + 1),
            this._licenseService.activeLicenseKey,
        );
    }
}
