import {Injectable} from '@angular/core';
import {concatMap, from, map, mergeAll, mergeMap, Observable, reduce, switchMap, tap, toArray} from "rxjs";
import {VerifyCredentialsResponse} from "../interfaces/responses/verify_credentials_response";
import {MastodonApiService} from "./mastodon-api.service";
import {GetListsResponse} from "../interfaces/responses/get_lists_response";
import {GetAccountResponse} from "../interfaces/responses/get_account_response";
import {List} from "../interfaces/public/list";
import {Account} from "../interfaces/public/account";

@Injectable({
    providedIn: 'root'
})
export class MastodonApiListsService {

    constructor(private mastodonApiService: MastodonApiService) {
    }

    getLists(instanceName: string, accessToken: string): Observable<List[]> {
        const url = `https://${instanceName}/api/v1/lists`;
        return this.mastodonApiService
            .getAuthenticated<GetListsResponse[]>(url, accessToken)
            .pipe(map((responses) => {
                    return responses.map((response) => {
                        return <List>{
                            id: response.id,
                            title: response.title,
                            repliesPolicy: response.repliesPolicy,
                        }
                    })
                })
            );
    }

    getAccountsForList(instanceName: string, accessToken: string, listId: string, url: string = ''): Observable<[nextLink: string, accounts: Account[]]> {
        if (url === '') {
            url = `https://${instanceName}/api/v1/lists/${listId}/accounts`;
        }
        return this.mastodonApiService
            .getAuthenticatedWithResponseHeaders<GetAccountResponse[]>(url, accessToken)
            .pipe(map(response => {
                    const links = response.headers.get('link');
                    let rel = '';
                    let nextUrl = '';
                    if (links) {
                        const nextLink = links!.split(',')[0];
                        rel = nextLink.split(';')[1].replace(' rel="', '').replace('"', '');
                        nextUrl = nextLink.split(';')[0].replace('<', '').replace('>', '');
                    }
                    const accounts = response!.body!.map((response) => {
                        return <Account>{
                            id: response.id,
                            username: response.username,
                            acct: response.acct,
                            displayName: response.display_name,
                            note: response.note,
                            url: response.url,
                            avatar: response.avatar,
                            avatarStatic: response.avatar_static,
                            fields: response.fields,
                        };
                    });
                    return [rel === 'next' ? nextUrl : '', accounts];
                })
            );
    }

    addAccountToList(instanceName: string, accessToken: string, listId: string, accountId: string) {
        const url = `https://${instanceName}/api/v1/lists/${listId}/accounts`;
        return this.mastodonApiService
            .postAuthenticated(url, {account_ids: [accountId]}, accessToken);
    }

    removeAccountFromList(instanceName: string, accessToken: string, listId: string, accountId: string) {
        const url = `https://${instanceName}/api/v1/lists/${listId}/accounts`;
        return this.mastodonApiService
            .deleteAuthenticated(url, {account_ids: [accountId]}, accessToken);
    }
}
