import { Component, OnInit, ViewChild, ElementRef, Input, Inject } from '@angular/core';
import { SignaturesContentService } from '../service/signatures.service';
import { DomSanitizer } from '@angular/platform-browser';
import * as $ from 'jquery';
import { SignaturePad } from 'angular2-signaturepad/signature-pad';
import {
    MatDialogRef,
    MatDialog,
    MAT_DIALOG_DATA,
    MatBottomSheet,
    MatBottomSheetRef,
    MatBottomSheetConfig,
    MatSidenav
} from '@angular/material';
import { SignaturesComponent } from '../signatures/signatures.component';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { NotificationService } from '../service/notification.service';
import { trigger, transition, style, animate } from '@angular/animations';
import { CookieService } from 'ngx-cookie-service';
import { PDFDocumentProxy } from 'ng2-pdf-viewer';

@Component({
    selector: 'app-document',
    templateUrl: 'document.component.html',
    styleUrls: ['document.component.scss'],
    animations: [
        trigger(
            'enterApp',
            [
                transition(
                    ':leave', [
                        style({ transform: 'translateY(0)' }),
                        animate('500ms', style({ transform: 'translateY(-100%)' })),
                    ]
                )]
        ),
        trigger(
            'slideDown',
            [
                transition(
                    ':enter', [
                        style({ transform: 'translateY(-100%)', opacity: 0 }),
                        animate('500ms', style({ transform: 'translateY(0)', 'opacity': 1 }))
                    ]
                ),
                transition(
                    ':leave', [
                        style({ transform: 'translateY(0)', 'opacity': 1 }),
                        animate('500ms', style({ transform: 'translateY(-100%)', 'opacity': 0 })),
                    ]
                )]
        ),
        trigger(
            'slideUp',
            [
                transition(
                    ':enter', [
                        style({ transform: 'translateY(100%)', opacity: 0 }),
                        animate('500ms', style({ transform: 'translateY(0)', 'opacity': 1 }))
                    ]
                ),
                transition(
                    ':leave', [
                        style({ transform: 'translateY(0)', 'opacity': 1 }),
                        animate('500ms', style({ transform: 'translateY(100%)', 'opacity': 0 })),
                    ]
                )]
        )
    ],
})
export class DocumentComponent implements OnInit {
    enterApp = true;
    loadingPage = true;
    pageNum = 1;
    signaturesContent: any = [];
    pageRendering = false;
    pageNumPending: null;
    scale = 1;
    totalPages: number;
    draggable: boolean;
    loadingDoc = true;
    renderingDoc = true;
    signaturePadPosX = 0;
    signaturePadPosY = 50;
    currentDoc = 0;
    docList: any = [];
    actionsList: any = [];
    currentAction = 0;
    lockSignaturePad = false;
    pdfDataArr: any;
    annotationPadOptions = {
        throttle: 0,
        minWidth: 1,
        maxWidth: 2.5,
        backgroundColor: 'rgba(255, 255, 255, 0)',
        canvasWidth: 768,
        canvasHeight: 270
    };
    freezeSidenavClose = false;
    penColors = [{ id: 'black' }, { id: '#1a75ff' }, { id: '#FF0000' }];

    @Input() mainDocument: any = {};

    @ViewChild('pdfpage') elPdfContainer: ElementRef;
    @ViewChild('snav') snav: MatSidenav;
    @ViewChild('snavRight') snavRight: MatSidenav;
    @ViewChild('canvas') canvas: ElementRef;
    @ViewChild('canvasWrapper') canvasWrapper: ElementRef;
    @ViewChild(SignaturePad) signaturePad: SignaturePad;


    public context: CanvasRenderingContext2D;

    constructor(private router: Router, private route: ActivatedRoute, public http: HttpClient,
        public signaturesService: SignaturesContentService,
        public notificationService: NotificationService,
        private sanitization: DomSanitizer, public dialog: MatDialog, private bottomSheet: MatBottomSheet, 
        private cookieService: CookieService) {
        this.draggable = false;
    }

    ngOnInit(): void {
        const cookieInfo = JSON.parse(atob(this.cookieService.get('maarchParapheurAuth')));
        setTimeout(() => {
            this.enterApp = false;
        }, 500);
        this.route.params.subscribe(params => {
            if (typeof params['id'] !== 'undefined') {
                this.renderingDoc = true;
                this.loadingDoc = true;
                this.http.get('../rest/documents/' + params['id'])
                    .subscribe((data: any) => {
                        this.initDoc();
                        this.mainDocument = data.document;
                        this.signaturesService.mainDocumentId = this.mainDocument.id;
                        this.actionsList = data.document.actionsAllowed;
                        if (this.signaturesService.signaturesList.length === 0) {
                            this.http.get('../rest/users/' + cookieInfo.id + '/signatures')
                            .subscribe((dataSign: any) => {
                                this.signaturesService.signaturesList = dataSign.signatures;
                                this.signaturesService.loadingSign = false;
                            });
                        }
                        this.docList.push({ 'id': this.mainDocument.id, 'encodedDocument': this.mainDocument.encodedDocument, 'subject': this.mainDocument.subject });
                        this.mainDocument.attachments.forEach((attach: any, index: any) => {
                            this.docList.push({ 'id': attach.id, 'encodedDocument': '', 'title': '' });
                        });
                        this.loadingDoc = false;

                        this.pdfRender(this.docList[this.currentDoc]);
                        setTimeout(() => {
                            this.loadingPage = false;
                            this.renderingDoc = false;
                        }, 500);
                        this.loadNextDoc();
                    }, (err: any) => {
                        this.notificationService.handleErrors(err);
                    });
            } else {
                this.snav.open();
                this.freezeSidenavClose = true;
            }
        });
    }

    initDoc() {
        this.docList = [];
        this.signaturesService.signaturesContent = [];
        this.signaturesService.notesContent = [];
        this.signaturesService.currentAction = 0;
        this.signaturesService.currentPage = 1;
        this.pageNum = 1;
        this.signaturesContent.currentDoc = 1;
        this.currentDoc = 0;
    }

    pdfRender(document: any) {
        const binary_string = window.atob(document.encodedDocument);
        const len = binary_string.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
            bytes[i] = binary_string.charCodeAt(i);
        }
        this.pdfDataArr = bytes.buffer;
    }

    pdfRendered(pdf: PDFDocumentProxy) {
        this.totalPages = pdf.numPages;
        this.signaturesService.totalPage = this.totalPages;
    }

    pageRendered(e: any) {

        this.signaturesService.workingAreaWidth = e.target.clientWidth;
        this.signaturesService.workingAreaHeight = e.target.clientHeight;

        this.canvasWrapper.nativeElement.style.width = this.signaturesService.workingAreaWidth + 'px';
        this.canvasWrapper.nativeElement.style.height = this.signaturesService.workingAreaHeight + 'px';

        this.annotationPadOptions.canvasWidth = this.signaturesService.workingAreaWidth;
        this.annotationPadOptions.canvasHeight = this.signaturesService.workingAreaHeight;

        const ratio =  Math.max(window.devicePixelRatio || 1, 1);
        this.annotationPadOptions.canvasHeight = this.annotationPadOptions.canvasHeight * ratio;
        this.annotationPadOptions.canvasWidth = this.annotationPadOptions.canvasWidth * ratio;

        if (this.signaturePad !== undefined) {
            this.signaturePad.set('canvasWidth', this.annotationPadOptions.canvasWidth);
            this.signaturePad.set('canvasHeight', this.annotationPadOptions.canvasHeight);
        }

        this.signaturesService.signWidth = this.signaturesService.workingAreaWidth / 4.5;

        this.renderingDoc = false;
    }

    prevPage() {
        this.pageNum--;
        if (this.pageNum === 0) {
            this.pageNum = 1;
        } else {
        }

        if (this.currentDoc === 0) {
            this.signaturesService.currentPage = this.pageNum;
        }
    }

    nextPage() {
        if (this.pageNum >= this.totalPages) {
            this.pageNum = this.totalPages;
        } else {
            this.pageNum++;
        }

        // only for main document
        if (this.currentDoc === 0) {
            this.signaturesService.currentPage = this.pageNum;
        }
    }

    nextDoc() {
        this.renderingDoc = true;
        this.signaturesService.isTaggable = false;
        this.pageNum = 1;
        this.currentDoc++;
        this.pdfRender(this.docList[this.currentDoc]);
        this.loadNextDoc();
    }

    prevDoc() {
        this.renderingDoc = true;
        this.pageNum = 1;
        this.currentDoc--;
        if (this.currentDoc === 0) {
            this.signaturesService.currentPage = 1;
            this.signaturesService.isTaggable = true;
        }
        this.pdfRender(this.docList[this.currentDoc]);
    }

    addAnnotation() {
        if (!this.signaturesService.lockNote && this.currentDoc === 0) {
            this.signaturesService.annotationMode = true;
            this.signaturePadPosX = 0;
            this.signaturePadPosY = 0;
            this.signaturesService.lockNote = true;
        }
    }

    moveSign(event: any, i: number) {
        this.signaturesService.signaturesContent[this.signaturesService.currentPage][i].positionX = event.x;
        this.signaturesService.signaturesContent[this.signaturesService.currentPage][i].positionY = event.y;
    }

    moveNote(event: any, i: number) {
        this.signaturesService.notesContent[this.signaturesService.currentPage][i].positionX = event.x;
        this.signaturesService.notesContent[this.signaturesService.currentPage][i].positionY = event.y;
    }

    movePad(event: any) {
        this.signaturePadPosX = event.x;
        this.signaturePadPosY = event.y;
        $('.page-viewer, .canvas-wrapper, .mat-sidenav-content').css({ 'overflow': 'auto' });
    }

    deleteSignature(index: number) {
        this.signaturesService.signaturesContent[this.signaturesService.currentPage].splice(index, 1);
    }

    deleteNote(index: number) {
        this.signaturesService.notesContent[this.signaturesService.currentPage].splice(index, 1);
    }

    validateAnnotation() {
        if (!this.signaturesService.notesContent[this.signaturesService.currentPage]) {
            this.signaturesService.notesContent[this.signaturesService.currentPage] = [];
        }
        this.signaturesService.notesContent[this.signaturesService.currentPage].push(
            {
                'fullPath': this.signaturePad.toDataURL('image/svg+xml'),
                'positionX': (this.signaturePadPosX * 100) / this.annotationPadOptions.canvasWidth,
                'positionY': (this.signaturePadPosY * 100) / this.annotationPadOptions.canvasHeight,
                'height': this.annotationPadOptions.canvasHeight,
                'width': 768,
            }
        );
        this.signaturePad.clear();
        if (this.scale > 1) {
            this.renderingDoc = true;
        }
        this.scale = 1;
        this.signaturesService.annotationMode = false;
        this.signaturesService.lockNote = false;
        this.notificationService.success('Annotation ajoutée');
    }

    cancelAnnotation() {
        this.signaturePad.clear();
        this.scale = 1;
        this.signaturesService.annotationMode = false;
        this.signaturesService.lockNote = false;
    }

    freezDoc() {
        $('.page-viewer, .canvas-wrapper, .mat-sidenav-content').css({ 'overflow': 'hidden' });
    }

    onColorChange(entry: any) {
        this.signaturePad.set('penColor', entry.id);
    }

    onDotChange(entry: any) {
        this.signaturePad.set('minWidth', parseFloat(entry));
        this.signaturePad.set('maxWidth', parseFloat(entry) + 2);
    }

    openDialog(): void {
        const dialogRef = this.dialog.open(WarnModalComponent, {
            width: '350px',
            data: {}
        });

        dialogRef.afterClosed().subscribe(result => {
            if (result === 'sucess') {
                const config: MatBottomSheetConfig = {
                    disableClose: true,
                    direction: 'ltr'
                };
                this.bottomSheet.open(RejectInfoBottomSheetComponent, config);
            } else if (result === 'annotation') {
                this.signaturesService.annotationMode = true;
                this.signaturesService.lockNote = true;
            }
        });
    }

    confirmDialog(mode: any): void {
        const dialogRef = this.dialog.open(ConfirmModalComponent, {
            width: '350px',
            data: { msg: 'Êtes-vous sûr  ?' }
        });

        dialogRef.afterClosed().subscribe(result => {
            if (result) {
                const config: MatBottomSheetConfig = {
                    disableClose: true,
                    direction: 'ltr'
                };
                this.bottomSheet.open(SuccessInfoValidBottomSheetComponent, config);
            }
        });
    }

    openDrawer(): void {
        if (this.currentDoc > 0) {
            this.currentDoc = 0;
            this.pageNum = 1;
            this.pdfRender(this.docList[this.currentDoc]);
        }
        this.signaturesService.showSign = true;
        const config: MatBottomSheetConfig = {
            disableClose: false,
            direction: 'ltr'
        };
        this.bottomSheet.open(SignaturesComponent, config);
    }

    removeTags() {
        this.signaturesService.currentAction = 0;
        const dialogRef = this.dialog.open(ConfirmModalComponent, {
            width: '350px',
            data: { msg: 'Effacer toutes les annotations et signatures ?' }
        });

        dialogRef.afterClosed().subscribe(result => {
            if (result) {
                this.signaturesService.signaturesContent = [];
                this.signaturesService.notesContent = [];
                this.notificationService.success('Annotations / signatures supprimées du document');
            }
        });
    }

    undoTag() {
        if (this.signaturesService.notesContent[this.pageNum]) {
            this.signaturesService.notesContent[this.pageNum].pop();
        }
    }

    loadNextDoc () {
        if (this.docList[this.currentDoc + 1] && this.docList[this.currentDoc + 1].id && this.docList[this.currentDoc + 1].encodedDocument === '') {
            this.http.get('../rest/attachments/' + this.docList[this.currentDoc + 1].id)
                .subscribe((dataPj: any) => {
                    this.docList[this.currentDoc + 1] = dataPj.attachment;
                }, (err: any) => {
                    this.notificationService.handleErrors(err);
                });
        }
    }

    launchEvent(action: any) {
        this.signaturesService.currentAction = action.id;
        this[action.event]();
    }

    test() {
        if (this.lockSignaturePad) {
            this.lockSignaturePad = false;
            this.signaturePad.on();
        } else {
            this.lockSignaturePad = true;
            this.signaturePad.off();
        }
    }

    zoomPlus() {
        this.renderingDoc = true;
        this.lockSignaturePad = true;
        this.scale = 2;
    }

    zoomMinus() {
        this.renderingDoc = true;
        this.signaturePad.clear();
        this.lockSignaturePad = true;
        this.scale = 1;
    }

    undo() {
        const data = this.signaturePad.toData();
        if (data) {
            data.pop(); // remove the last dot or line
            this.signaturePad.fromData(data);
        }
    }
}

@Component({
    templateUrl: '../modal/warn-modal.component.html',
    styleUrls: ['../modal/warn-modal.component.scss']
})
export class WarnModalComponent {
    constructor(@Inject(MAT_DIALOG_DATA) public data: any, public http: HttpClient, public dialogRef: MatDialogRef<WarnModalComponent>, public signaturesService: SignaturesContentService, public notificationService: NotificationService) { }

    confirmDoc () {
        const signatures: any[] = [];
        if (this.signaturesService.currentAction > 0) {
            for (let index = 1; index <= this.signaturesService.totalPage; index++) {
                if (this.signaturesService.signaturesContent[index]) {
                    this.signaturesService.signaturesContent[index].forEach((signature: any) => {
                        signatures.push(
                            {
                                'encodedImage'  : signature.encodedSignature,
                                'width'         : (this.signaturesService.signWidth * 100) / signature.pdfAreaX,
                                'positionX'     : (signature.positionX * 100) / signature.pdfAreaX,
                                'positionY'     : (signature.positionY * 100) / signature.pdfAreaY,
                                'type'          : 'PNG',
                                'page'          : index
                            }
                        );
                    });
                }
                if (this.signaturesService.notesContent[index]) {
                    this.signaturesService.notesContent[index].forEach((note: any) => {
                        signatures.push(
                            {
                                'encodedImage'  : note.fullPath,
                                'width'         : note.width,
                                'positionX'     : note.positionX,
                                'positionY'     : note.positionY,
                                'type'          : 'SVG',
                                'page'          : index
                            }
                        );
                    });
                }
            }
            this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, {'signatures': signatures})
                .subscribe(() => {
                    this.signaturesService.documentsList.splice(this.signaturesService.indexDocumentsList, 1);
                    this.signaturesService.documentsListCount--;
                    this.dialogRef.close('sucess');
                }, (err: any) => {
                    this.notificationService.handleErrors(err);
                });
        } else {
            this.dialogRef.close('sucess');
        }
    }
}

@Component({
    templateUrl: '../modal/confirm-modal.component.html',
    styleUrls: ['../modal/confirm-modal.component.scss']
})
export class ConfirmModalComponent {
    constructor(@Inject(MAT_DIALOG_DATA) public data: any, public http: HttpClient, public dialogRef: MatDialogRef<ConfirmModalComponent>, public signaturesService: SignaturesContentService, public notificationService: NotificationService) { }

    confirmDoc () {
        const signatures: any[] = [];
        if (this.signaturesService.currentAction > 0) {
            for (let index = 1; index <= this.signaturesService.totalPage; index++) {
                if (this.signaturesService.signaturesContent[index]) {
                    this.signaturesService.signaturesContent[index].forEach((signature: any) => {
                        signatures.push(
                            {
                                'encodedImage'  : signature.encodedSignature,
                                'width'         : (this.signaturesService.signWidth * 100) / signature.pdfAreaX,
                                'positionX'     : (signature.positionX * 100) / signature.pdfAreaX,
                                'positionY'     : (signature.positionY * 100) / signature.pdfAreaY,
                                'type'          : 'PNG',
                                'page'          : index,
                            }
                        );
                    });
                }
                if (this.signaturesService.notesContent[index]) {
                    this.signaturesService.notesContent[index].forEach((note: any) => {
                        signatures.push(
                            {
                                'encodedImage'  : note.fullPath,
                                'width'         : note.width,
                                'positionX'     : note.positionX,
                                'positionY'     : note.positionY,
                                'type'          : 'SVG',
                                'page'          : index,
                            }
                        );
                    });
                }
            }
            this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, {'signatures': signatures})
                .subscribe(() => {
                    this.dialogRef.close('sucess');
                    this.signaturesService.documentsList.splice(this.signaturesService.indexDocumentsList, 1);
                    this.signaturesService.documentsListCount--;
                }, (err: any) => {
                    this.notificationService.handleErrors(err);
                });
        } else {
            this.dialogRef.close('sucess');
        }
    }
}

@Component({
    templateUrl: '../modal/success-info-valid.html',
    styleUrls: ['../modal/success-info-valid.scss']
})
export class SuccessInfoValidBottomSheetComponent implements OnInit {
    date: Date = new Date();
    constructor(private router: Router, public signaturesService: SignaturesContentService, private bottomSheetRef: MatBottomSheetRef<SuccessInfoValidBottomSheetComponent>) { }
     ngOnInit(): void {
        setTimeout(() => {
            if (this.signaturesService.documentsList[this.signaturesService.indexDocumentsList]) {
                this.router.navigate(['/documents/' + this.signaturesService.documentsList[this.signaturesService.indexDocumentsList].id]);
            } else {
                this.router.navigate(['/documents']);
            }
            this.bottomSheetRef.dismiss();
        }, 2000);
     }
}

@Component({
    templateUrl: '../modal/reject-info.html',
    styleUrls: ['../modal/reject-info.scss']
})
export class RejectInfoBottomSheetComponent implements OnInit {
    date: Date = new Date();
    constructor(private router: Router, public signaturesService: SignaturesContentService, private bottomSheetRef: MatBottomSheetRef<RejectInfoBottomSheetComponent>) { }
    ngOnInit(): void {
        setTimeout(() => {
            if (this.signaturesService.documentsList[this.signaturesService.indexDocumentsList]) {
                this.router.navigate(['/documents/' + this.signaturesService.documentsList[this.signaturesService.indexDocumentsList].id]);
            } else {
                this.router.navigate(['/documents']);
            }
            this.bottomSheetRef.dismiss();
        }, 2000);
     }
}