import { Location } from '@angular/common';
import { AfterContentChecked, AfterContentInit, Component, ContentChildren, EventEmitter, 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 'rxjs/add/operator/delay';

import 'rxjs/add/observable/of';

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

@Component({
    selector: 'knk-wizard',
    template: '<ng-content></ng-content>'
})
export class WizardComponent implements AfterContentInit, AfterContentChecked, OnInit {
    @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;

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

    ngOnInit(): void {
        if (!this.dataset) {
            this.dataset = Observable.empty();
        }
        this.dataset.subscribe((data) => {
                this.steps.forEach((s, i) => {
                    s.loadData(data);
                });
            },
            error => console.log(error),
            () => { setTimeout(() => this.isLoading = false, 100); }
        );
    }

    ngAfterContentInit(): void {
        let res: boolean = true;
        if (this.steps) {
            this.steps.forEach((s, i) => {
                res = res && s.valid;
                if (this.currStep === i) {
                    s.show();
                } else {
                    s.hide();
                }
                // if (this.dataset) {
                //    this.dataset.
                //        subscribe((d) => s.loadData(d));
                // }
            });
        }
        this.activeStep = this.steps.first;
        this.currentStep = this.steps.first;
        this.isInvalid = !res;
    }
    ngAfterContentChecked(): void {
        let res: boolean = true;
        if (this.steps) {
            this.steps.forEach((s) => {
                res = res && s.valid;
            });
        }
        setTimeout(f => this.isInvalid = !res, 100);
    }
    moveNext(): void {
        this.changeStep(true);
    }
    moveBack(): void {
        this.changeStep(false);
    }

    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];
    }
}
