import {Component, OnDestroy} from '@angular/core';
import {FormControl, FormGroup} from "@angular/forms";
import {select, Store} from "@ngrx/store";
import {FiltersActions, MastodonApiActions} from "../../state/store/actions";
import {debounceTime, Observable, Subscription, tap} from "rxjs";
import {List} from 'projects/mastodon-api/src/public-api';
import {selectFilters, selectFiltersForForm, selectLists} from "../../state/store/selectors";
import {Filters} from "../../state/store/reducers";

interface FiltersForForm {
    fullText: string | undefined;
    lists: ReadonlyArray<string>;
    unlisted: boolean;
}

@Component({
    selector: 'app-filters',
    templateUrl: './filters.component.html',
    styleUrls: ['./filters.component.scss']
})
export class FiltersComponent implements OnDestroy {
    filtersForm = new FormGroup({
        text: new FormControl(),
        lists: new FormControl([] as string[]),
    });

    lists$: Observable<ReadonlyArray<List>>;
    filters$: Observable<FiltersForForm>;
    formSubscription: Subscription;

    constructor(private store: Store) {
        this.lists$ = this.store.pipe(select(selectLists));
        this.filters$ = this.store.pipe(
            select(selectFiltersForForm),
            tap(filters => {
                this.filtersForm.patchValue({
                    text: filters.fullText,
                    lists: filters.lists as string[],
                }, {emitEvent: false, onlySelf: true});
            }),
        );
        this.formSubscription = this.filtersForm.valueChanges
            .pipe(debounceTime(500))
            .subscribe(value => {
                if (value['lists'] && value['lists'].length > 0) {
                    this.store.dispatch(FiltersActions.setLists({lists: value.lists}));
                    this.store.dispatch(FiltersActions.setUnlisted({unlisted: false}));
                }
                if (!value['lists'] || value['lists'].length === 0) {
                    this.store.dispatch(FiltersActions.setLists({lists: []}));
                }
                if (value['text']) {
                    const text = value['text'];
                    if (text.length > 0) {
                        const parts = text.split(/[\s,]+/);
                        if (parts.some((part: string) => part.startsWith('@'))) {
                            const username = parts.find((part: string) => part.startsWith('@'));
                            this.store.dispatch(FiltersActions.setUsername({username: username.substring(1)}));
                        } else {
                            this.store.dispatch(FiltersActions.setUsername({username: ''}));
                        }
                        this.store.dispatch(FiltersActions.setFreeText({freeText: parts.filter((part: string) => !part.startsWith('@'))}));
                    } else {
                        this.store.dispatch(FiltersActions.setUsername({username: ''}));
                        this.store.dispatch(FiltersActions.setFreeText({freeText: []}));
                    }
                } else {
                    this.store.dispatch(FiltersActions.setUsername({username: ''}));
                    this.store.dispatch(FiltersActions.setFreeText({freeText: []}));
                }
            });
    }

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

    clearFilter() {
        this.store.dispatch(FiltersActions.clearFilters());
    }

    toggleUnlisted($event: boolean) {
        this.store.dispatch(FiltersActions.setUnlisted({unlisted: $event}));
    }
}
