import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { PermissionsService } from '@services/permissions.service';
import { ViewedPagesService } from '@services/files/viewed-pages.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { PageRotationService } from '../../../pdf-viewer/services/page-rotation.service';
import { getConfig } from '@iqser/common-ui';
import { map, tap } from 'rxjs/operators';
import { AppConfig, ViewedPage } from '@red/domain';
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
import { pairwise } from 'rxjs';
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
import { ContextComponent } from '@iqser/common-ui/lib/utils';

interface PageIndicatorContext {
    isRotated: boolean;
    assigneeChanged: boolean;
}

@Component({
    selector: 'redaction-page-indicator',
    templateUrl: './page-indicator.component.html',
    styleUrls: ['./page-indicator.component.scss'],
})
export class PageIndicatorComponent extends ContextComponent<PageIndicatorContext> implements OnChanges, OnInit {
    readonly #config = getConfig<AppConfig>();
    @Input({ required: true }) number: number;
    @Input() showDottedIcon = false;
    @Input() activeSelection = false;
    @Input() read = false;
    @Output() readonly pageSelected = new EventEmitter<number>();
    pageReadTimeout: number = null;

    constructor(
        private readonly _viewedPagesService: ViewedPagesService,
        private readonly _viewedPagesMapService: ViewedPagesMapService,
        private readonly _permissionService: PermissionsService,
        private readonly _state: FilePreviewStateService,
        private readonly _pdf: PdfViewer,
        readonly pageRotationService: PageRotationService,
    ) {
        super();
    }

    get isActive() {
        return this.number === this._pdf.currentPage();
    }

    ngOnInit() {
        const assigneeChanged$ = this._state.file$.pipe(
            pairwise(),
            map(([prevFile, currFile]) => prevFile.assignee !== currFile.assignee),
            tap(assigneeChanged => assigneeChanged && this.handlePageRead()),
        );
        super._initContext({ assigneeChanged: assigneeChanged$ });
    }

    ngOnChanges() {
        this.handlePageRead();
    }

    async toggleReadState() {
        if (this._permissionService.canMarkPagesAsViewed(this._state.file())) {
            if (this.read) {
                await this.#markPageUnread();
            } else {
                await this.#markPageRead();
            }
        }
    }

    handlePageRead(): void {
        if (!this._permissionService.canMarkPagesAsViewed(this._state.file())) {
            return;
        }

        if (this.pageReadTimeout) {
            clearTimeout(this.pageReadTimeout);
        }

        if (this.isActive && !this.read) {
            this.pageReadTimeout = window.setTimeout(async () => {
                if (this.isActive && !this.read) {
                    await this.#markPageRead();
                }
            }, this.#config.AUTO_READ_TIME * 1000);
        }
    }

    async #markPageRead() {
        const fileId = this._state.fileId;
        await this._viewedPagesService.add({ page: this.number }, this._state.dossierId, fileId);
        const viewedPage = new ViewedPage({ page: this.number, fileId });
        this._viewedPagesMapService.add(fileId, viewedPage);
    }

    async #markPageUnread() {
        const fileId = this._state.fileId;
        await this._viewedPagesService.remove(this._state.dossierId, fileId, this.number);
        this._viewedPagesMapService.delete(fileId, this.number);
    }
}
