import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox';
import { MatFormField } from '@angular/material/form-field';
import { MatIcon } from '@angular/material/icon';
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
import { FormFieldComponent } from '@common-ui/inputs/form-field/form-field-component.directive';
import { shareLast } from '@iqser/common-ui/lib/utils';
import { Watermark } from '@red/domain';
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs';
import { filter, map, tap } from 'rxjs/operators';
import { WatermarkService } from '@services/entity-services/watermark.service';

@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,
        },
    ],
    standalone: true,
    imports: [NgIf, AsyncPipe, MatCheckbox, MatFormField, MatSelectTrigger, MatSelect, MatIcon, MatOption, NgForOf],
})
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,
        private readonly _watermarksService: WatermarkService,
    ) {
        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);
    }

    async ngOnChanges(changes: SimpleChanges) {
        if (changes.dossierTemplateId) {
            if (!this._watermarksMapService.get(changes.dossierTemplateId.currentValue).length) {
                await firstValueFrom(this._watermarksService.loadForDossierTemplate(changes.dossierTemplateId.currentValue));
            }
            this.#dossierTemplateId$.next(this.dossierTemplateId);
        }
    }
}
