import { Component, effect, EventEmitter, inject, Input, OnChanges, 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, startWith, tap } from 'rxjs/operators';
import { AppConfig, ViewedPage } from '@red/domain';
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
import { Observable, pairwise } from 'rxjs';
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
import { NGXLogger } from 'ngx-logger';

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

    constructor(
        private readonly _viewedPagesService: ViewedPagesService,
        private readonly _viewedPagesMapService: ViewedPagesMapService,
        private readonly _permissionService: PermissionsService,
        private readonly _state: FilePreviewStateService,
        private readonly _pdf: PdfViewer,
        readonly pageRotationService: PageRotationService,
    ) {
        this.assigneeChanged$ = this._state.file$.pipe(
            pairwise(),
            map(([prevFile, currFile]) => prevFile.assignee !== currFile.assignee),
            tap(assigneeChanged => assigneeChanged && this.handlePageRead()),
            startWith(true),
            map(() => true),
        );

        effect(() => {
            if (this.isActive) {
                this.handlePageRead();
            }
        });
    }

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

    ngOnChanges() {
        this.handlePageRead();
    }

    async toggleReadState() {
        if (!this._permissionService.canMarkPagesAsViewed(this._state.file())) {
            this.#logger.info('[PAGES] Cannot toggle read state');
            return;
        }

        if (this.read) {
            await this.#markPageUnread();
        } else {
            await this.#markPageRead();
        }
    }

    handlePageRead(): void {
        if (!this._permissionService.canMarkPagesAsViewed(this._state.file())) {
            this.#logger.info('[PAGES] Cannot mark pages as read');
            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() {
        this.#logger.info('[PAGES] Mark page read', this.number);

        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() {
        this.#logger.info('[PAGES] Mark page unread', this.number);

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