import { Component, inject, Input, OnChanges, signal, SimpleChanges, ViewChild } from '@angular/core';
import { InputWithActionComponent, LoadingService } from '@iqser/common-ui';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { trackByFactory } from '@iqser/common-ui/lib/utils';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import type { IComment, User } from '@red/domain';
import { CommentsApiService } from '@services/comments-api.service';
import { PermissionsService } from '@services/permissions.service';
import { NGXLogger } from 'ngx-logger';
import { FilePreviewStateService } from '../../services/file-preview-state.service';

@Component({
    selector: 'redaction-comments',
    templateUrl: './comments.component.html',
    styleUrls: ['./comments.component.scss'],
})
export class CommentsComponent implements OnChanges {
    readonly #commentsApiService = inject(CommentsApiService);
    readonly #logger = inject(NGXLogger);
    @ViewChild(InputWithActionComponent) protected readonly input: InputWithActionComponent;
    protected readonly trackBy = trackByFactory();
    protected readonly comments = signal<IComment[]>([]);
    protected readonly currentUser = getCurrentUser<User>();
    @Input({ required: true }) annotation: AnnotationWrapper;

    constructor(
        readonly permissionsService: PermissionsService,
        private readonly _loadingService: LoadingService,
        protected readonly state: FilePreviewStateService,
    ) {}

    ngOnChanges(changes: SimpleChanges) {
        const currentAnnotation: AnnotationWrapper = changes.annotation?.currentValue;
        const previousAnnotation: AnnotationWrapper = changes.annotation?.previousValue;
        const annotationChanged = currentAnnotation?.id !== previousAnnotation?.id;
        const commentsChanged = currentAnnotation?.numberOfComments !== previousAnnotation?.numberOfComments;
        if (annotationChanged || commentsChanged) {
            this.#logger.info(`[COMMENTS] State of annotation ${this.annotation.value} changed. Fetch comments.`);
            const request = this.#commentsApiService.fetch(this.state.dossierId, this.state.fileId, this.annotation.id);
            request.then(comments => this.comments.set(comments));
        }
    }

    async add(value: string): Promise<void> {
        if (!value) {
            return;
        }
        this._loadingService.start();
        const { dossierId, fileId } = this.state;
        const commentId = await this.#commentsApiService.add(value, this.annotation.id, dossierId, fileId);
        this.annotation.numberOfComments++;
        this.comments.update(current => [
            ...current,
            {
                text: value,
                id: commentId,
                annotationId: this.annotation.id,
                user: this.currentUser.id,
            },
        ]);
        this.input.reset();
        this._loadingService.stop();
    }

    async remove(comment: IComment): Promise<void> {
        this._loadingService.start();
        const { dossierId, fileId } = this.state;
        await this.#commentsApiService.remove(comment.id, this.annotation.id, dossierId, fileId);
        this.annotation.numberOfComments--;
        this.comments.update(current => current.filter(c => c.id !== comment.id));
        this._loadingService.stop();
    }
}
