import {Injectable, OnDestroy} from '@angular/core';
import {EMPTY, expand, map, Observable, reduce, Subscription} from "rxjs";
import {select, Store} from "@ngrx/store";
import {List, MastodonApiListsService} from 'projects/mastodon-api/src/public-api';
import {selectDataForAuthorizedRequest} from "../state/store";

@Injectable({
    providedIn: 'root'
})
export class ListService implements OnDestroy {

    private instanceName: string | undefined;
    private accessToken: string | undefined;
    private storeSubscription: Subscription;

    constructor(private mastodonApiListsService: MastodonApiListsService, private store: Store) {
        this.storeSubscription = this.store.pipe(select(selectDataForAuthorizedRequest)).subscribe(data => {
            this.instanceName = data?.instanceName;
            this.accessToken = data?.accessToken;
        });
    }

    loadLists(): Observable<List[]> {
        return this.mastodonApiListsService.getLists(this.instanceName!, this.accessToken!)
    }


    createList(title: string) {
        return this.mastodonApiListsService.createList(this.instanceName!, this.accessToken!, title);
    }

    updateList(listId: string, newName: string) {
        return this.mastodonApiListsService.updateList(this.instanceName!, this.accessToken!, listId, newName);
    }


    loadAccountsIdsForList(listId: string): Observable<{ [id: string]: string[] }> {
        return this.mastodonApiListsService
            .getAccountsForList(this.instanceName!, this.accessToken!, listId)
            .pipe(
                expand(result => {
                    const nextLink = result[0];
                    if (nextLink && nextLink.length > 0) {
                        return this.mastodonApiListsService.getAccountsForList(this.instanceName!, this.accessToken!, listId, nextLink);
                    }
                    return EMPTY;
                }),
                map(result => {
                        const accounts = result[1];
                        return {[listId]: accounts.map(account => account.id)};
                    }
                ),
                reduce((acc: { [listId: string]: string[] }, res: { [listId: string]: string[] }) => {
                    const listId = Object.keys(res)[0];
                    if (acc[listId] !== undefined && acc[listId].length > 0) {
                        acc[listId] = acc[listId].concat(res[listId]);
                        return acc;
                    }
                    return {...acc, ...res};
                }, {}),
            );
    }

    addAccountToSelectedList(accountId: string, listId: string) {
        return this.mastodonApiListsService.addAccountToList(this.instanceName!, this.accessToken!, listId, accountId)
    }

    removeAccountFromList(accountId: string, listId: string) {
        return this.mastodonApiListsService.removeAccountFromList(this.instanceName!, this.accessToken!, listId, accountId)
    }

    ngOnDestroy(): void {
        this.storeSubscription.unsubscribe();
    }
}

