import { Location } from '@angular/common';
import { AfterContentChecked, AfterContentInit, Component, ContentChildren, EventEmitter, OnDestroy, OnInit } from '@angular/core';
import { Directive, Input, NgModule } from '@angular/core';
import { FormControl, FormGroup, FormsModule, NgForm, Validators } from '@angular/forms';
import { WizardStepService, WizardStepServiceData } from './wizardstep.service';

import { QueryList } from '@angular/core';
import { Observable } from 'rxjs/Observable';

import { Subscription } from 'rxjs/Subscription';

import 'rxjs/add/operator/delay';

import 'rxjs/add/observable/of';
import { Subject } from 'rxjs/Subject';

@Directive({
    selector: '[knkWizardStep]'
})
export class WizardStepDirective {
}

@Component({
    selector: 'knk-wizard',
    template: '<ng-content></ng-content>'
})
export class WizardComponent implements AfterContentInit, OnInit, OnDestroy {
    @ContentChildren(WizardStepDirective, {read: WizardStepService})
    steps: QueryList<WizardStepService>;
    isLoading: boolean = true;
    isInvalid: boolean = true;
    currStep: number = 0;
    canMoveForward: boolean = true;
    canMoveBackward: boolean = false;
    isFinish: boolean = false;
    activeStep: WizardStepService;
    currentStep: WizardStepService;
    res: Subscription;

    @Input() dataset: Observable<{[key: string]: string}>;
    @Input() linear: boolean = false;

    ngOnInit(): void {
        if (!this.dataset) {
            this.dataset = Observable.empty();
        }
        let self: WizardComponent = this;
        let subject: Subject<{[key: string]: string}> = new Subject();
        subject.subscribe((data) => {
            setTimeout(() => self.isLoading = true, 10);
            setTimeout(() => {
                self.steps.forEach((s, i) => {
                    s.loadData(data);
                });
                setTimeout(() => self.isLoading = false, 10);
            }, 2000);
        },
        error => { self.res.unsubscribe();
                setTimeout(() => self.isLoading = false, 100);
                console.log(error); },
        () => {
            setTimeout(() => self.isLoading = false, 100);
        }
    );

    self.res = self.dataset.subscribe(subject);
    }

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

    ngAfterContentInit(): void {
        let res: boolean = true;
        let self: WizardComponent = this;
        if (this.steps) {
            this.steps.forEach((s, i) => {
                s.changeCallback = () => {
                    let resValid: boolean = true;
                    if (self.steps) {
                        self.steps.forEach((step) => {
                            resValid = resValid && step.valid;
                        });
                    }
                    setTimeout(f => this.isInvalid = !resValid, 100);
                };
                res = res && s.valid;
                if (this.currStep === i) {
                    s.show();
                } else {
                    s.hide();
                }
            });
        }
        this.activeStep = this.steps.first;
        this.currentStep = this.steps.first;
        this.isInvalid = !res;
    }

    moveNext(): void {
        this.changeStep(true);
    }
    moveBack(): void {
        this.changeStep(false);
    }

    payAndPublish(): void {
        console.log('payAndPublish');
    }

    movetoStep(step: WizardStepService): void {
        if (this.steps) {
            this.steps.forEach((s, i) => {
                if (step === s) {
                    this.currStep = i;
                    s.show();
                } else {
                    s.hide();
                }
            });
        }
        this.canMoveForward = this.currStep < (this.steps.length - 1);
        this.canMoveBackward = this.currStep > 0;
        this.isFinish = this.currStep === (this.steps.length - 1);

        this.activeStep = this.steps.toArray()[this.currStep];
        this.currentStep = this.steps.toArray()[this.currStep];
    }

    private changeStep(forward: boolean): void {
        if (this.steps && this.linear) {
            if (!this.steps.toArray()[this.currStep].valid) {
                this.steps.toArray()[this.currStep].markAsTouched();
                return;
            }
        }
        if (forward) {
            if (this.steps && (this.currStep < this.steps.length)) {
                this.steps.toArray()[this.currStep].hide();
                this.currStep++;
                this.steps.toArray()[this.currStep].show();
            }
        } else {
            if (this.steps && (this.currStep >  0)) {
                this.steps.toArray()[this.currStep].hide();
                this.currStep--;
                this.steps.toArray()[this.currStep].show();
                this.canMoveBackward = this.currStep > 0;
            }
        }
        this.canMoveForward = this.currStep < (this.steps.length - 1);
        this.canMoveBackward = this.currStep > 0;
        this.isFinish = this.currStep === (this.steps.length - 1);

        this.activeStep = this.steps.toArray()[this.currStep];
        this.currentStep = this.steps.toArray()[this.currStep];
    }
}
