import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { Actions, ofAction, Select, Store } from '@ngxs/store';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { DriveState } from '../../state/drive-state';
import { DriveFolder } from '../../folders/models/driveFolder';
import { take } from 'rxjs/operators';
import { FoldersTreeService } from '../../sidebar/folders-tree/folders-tree.service';
import { MoveEntries } from '../../state/actions/commands';
import { MoveEntriesFailed, MoveEntriesSuccess } from '../../state/actions/events';
import { DriveEntry } from '../../files/models/drive-entry';
import { ROOT_FOLDER, RootFolder } from '../../folders/root-folder';

@Component({
    selector: 'move-entries-dialog',
    templateUrl: './move-entries-dialog.component.html',
    styleUrls: ['./move-entries-dialog.component.scss'],
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [FoldersTreeService],
})
export class MoveEntriesDialogComponent implements OnInit, OnDestroy {
    public selectedFolder: DriveFolder|RootFolder = ROOT_FOLDER;
    @Select(DriveState.selectedEntries) selectedEntries$: Observable<DriveEntry[]>;
    public loading$ = new BehaviorSubject<boolean>(false);
    private subscriptions: Subscription[] = [];

    constructor(
        protected dialogRef: MatDialogRef<MoveEntriesDialogComponent>,
        protected store: Store,
        protected actions: Actions,
    ) {}

    ngOnInit() {
        const failure = this.actions.pipe(ofAction(MoveEntriesFailed)).subscribe(() => {
            this.loading$.next(false);
        });

        const success = this.actions.pipe(ofAction(MoveEntriesSuccess), take(1))
            .subscribe(() => {
                this.selectedFolder = null;
                this.close();
            });

        this.subscriptions.push(...[success, failure]);
    }

    ngOnDestroy() {
        this.subscriptions.forEach(s => s.unsubscribe());
    }

    public confirm() {
        this.loading$.next(true);
        this.store.dispatch(new MoveEntries(this.selectedFolder))
            .subscribe(() => {
                this.loading$.next(false);
            });
    }

    public getRootFolder() {
        return ROOT_FOLDER;
    }

    public canMove(): boolean {
        const folder = this.selectedFolder,
            movingEntries = this.store.selectSnapshot(DriveState.selectedEntries);
        return DriveState.canMoveEntriesTo(movingEntries, folder);
    }

    public close() {
        this.dialogRef.close();
    }
}
