import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { FormFieldComponent } from '@iqser/common-ui';
import { filter, map, tap } from 'rxjs/operators';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Watermark } from '@red/domain';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { shareLast } from '@iqser/common-ui/lib/utils';

@Component({
    selector: 'redaction-watermark-selector [dossierTemplateId] [label]',
    templateUrl: './watermark-selector.component.html',
    styleUrls: ['./watermark-selector.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            multi: true,
            useExisting: WatermarkSelectorComponent,
        },
        {
            provide: NG_VALIDATORS,
            multi: true,
            useExisting: WatermarkSelectorComponent,
        },
    ],
})
export class WatermarkSelectorComponent extends FormFieldComponent<number> implements OnChanges {
    #watermarks: Watermark[] = [];
    readonly #dossierTemplateId$ = new BehaviorSubject<string>(null);
    @Input() dossierTemplateId: string;
    @Input() label: string;
    @Input() isReadonly: boolean;
    readonly watermarks$: Observable<Watermark[]>;
    watermarksMap = new Map<number, Watermark>();

    constructor(private readonly _watermarksMapService: WatermarksMapService) {
        super();
        this.watermarks$ = this.#dossierTemplateId$.pipe(
            filter(dossierTemplateId => !!dossierTemplateId),
            map(dossierTemplateId => this._watermarksMapService.get(dossierTemplateId)),
            tap(watermarks => {
                this.#watermarks = watermarks;
                this.watermarksMap.clear();
                watermarks.forEach(watermark => this.watermarksMap.set(watermark.id, watermark));
            }),
            tap(watermarks => {
                if (!watermarks.length) {
                    this.selectWatermark(null);
                    this.setDisabledState(true);
                } else {
                    this.setDisabledState(false);
                    if (this.value && this.touched) {
                        this.selectWatermark(watermarks[0].id);
                    }
                }
            }),
            shareLast(),
        );
    }

    changeChecked($event: MatCheckboxChange): void {
        const { checked } = $event;
        if (!checked || this.#watermarks.length === 0) {
            this.selectWatermark(null);
        } else {
            this.selectWatermark(this.#watermarks[0].id);
        }
    }

    selectWatermark(watermarkId: number): void {
        this.markAsTouched();
        this._value = watermarkId;
        this.onChange(this._value);
    }

    ngOnChanges(changes: SimpleChanges) {
        if (changes.dossierTemplateId) {
            this.#dossierTemplateId$.next(this.dossierTemplateId);
        }
    }
}
