import { EventEmitter, Injectable, OnDestroy } from '@angular/core';
import { ActiveDossiersService } from './active-dossiers.service';
import { ArchivedDossiersService } from './archived-dossiers.service';
import { firstValueFrom, merge, Subscription } from 'rxjs';
import { skip, tap } from 'rxjs/operators';
import { Dossier } from '@red/domain';

@Injectable({
    providedIn: 'root',
})
export class DossiersCacheService implements OnDestroy {
    readonly changed$ = new EventEmitter<void>();
    private _dossiers: Dossier[] = JSON.parse(localStorage.getItem('dossiers')) || [];
    readonly #subscriptions = new Subscription();

    constructor(
        private readonly _activeDossiersService: ActiveDossiersService,
        private readonly _archivedDossiersService: ArchivedDossiersService,
    ) {
        this.#subscriptions.add(this.#init().subscribe());
    }

    get empty(): boolean {
        return !localStorage.getItem('dossiers');
    }

    get all(): Dossier[] {
        return this._dossiers;
    }

    ngOnDestroy() {
        this.#subscriptions.unsubscribe();
    }

    async load(): Promise<void> {
        const activeDossiers = firstValueFrom(this._activeDossiersService.loadAll());
        const archivedDossiers = firstValueFrom(this._archivedDossiersService.loadAll());
        await Promise.all([activeDossiers, archivedDossiers]);
        this.set();
    }

    set(): void {
        this._dossiers = [this._activeDossiersService.all, this._archivedDossiersService.all].flat();
        localStorage.setItem('dossiers', JSON.stringify(this._dossiers));
        this.changed$.emit();
    }

    get(dossierId: string) {
        return this._dossiers.find(dossier => dossier.id === dossierId);
    }

    #init() {
        // Skip 1 to avoid clearing the cache when the dossier services are initialized
        const activeDossiers = this._activeDossiersService.all$.pipe(skip(1));
        const archivedDossiers = this._archivedDossiersService.all$.pipe(skip(1));
        return merge(activeDossiers, archivedDossiers).pipe(tap(() => this.set()));
    }
}
