import { Component, ElementRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { ModalDialogOptions, ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { Select, Store } from '@ngxs/store';

import { EventData, Switch, TextField } from '@nativescript/core';
import { action } from '@nativescript/core/ui/dialogs';
import { FeedbackType } from 'nativescript-feedback';
import { ListViewEventData } from 'nativescript-ui-listview';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/internal/operators';
import { ModalDatePickerComponent } from '../../components/modal-view-date-picker/modal-view-date-picker.component';
import { StockTakingInsertOutput } from '../../entities/output/stockTakingInsertOutput';
import { WarehouseAllOutput } from '../../entities/output/warehouseAllOutput';
import { CreateStockTakingInsert, LoadWarehouseAll } from '../../state-mgmt/inventory-new.action';
import { InventoryNewState } from '../../state-mgmt/inventory-new.state';
import { feedbackMessage } from '../../utils/feedback-messages';
import { czechStringfromDate, dateFromCzechString } from '../../utils/myFunctions';

@Component({
    selector: 'InventoryNew',
    moduleId: module.id,
    templateUrl: './inventory-new.component.html',
    styleUrls: ['./inventory-new.component.scss']
})

export class InventoryNewComponent implements OnInit {
    @Select(InventoryNewState.getStockTaking) stockTaking$: Observable<StockTakingInsertOutput>;
    @Select(InventoryNewState.getWarehouses) warehouses$: Observable<WarehouseAllOutput[]>;
    @Select(InventoryNewState.isLoading) isLoading$: Observable<boolean>;
    othersIsLoading: boolean;
    dateLastInventory: string;
    warehouses: WarehouseAllOutput[];
    inventoryTypes: Array<{
        id: string,
        name: string
    }>;

    @ViewChild('date', {static: true}) date: ElementRef;
    @ViewChild('inventoryType', {static: true}) inventoryType: ElementRef;
    @ViewChild('note', {static: true}) note: ElementRef;

    constructor(
        private router: Router,
        private routerExtensions: RouterExtensions,
        private route: ActivatedRoute,
        private store: Store,
        private modalService: ModalDialogService,
        private viewContainerRef: ViewContainerRef
    ) {
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (RegExp('\/material\/inventoryNew\/[^/]+').test(this.router.url)) {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    ngOnInit(): void {
        this.othersIsLoading = false;
        this.dateLastInventory = this.route.snapshot.params['date'];

        this.inventoryTypes = [
            {id: 'proper', name: 'Řádná'},
            {id: 'extra', name: 'Mimořádná'}];
        this.fillTextFields();
        this.store.dispatch(new LoadWarehouseAll())
            .pipe(withLatestFrom(this.warehouses$))
            .subscribe(([_, warehouses]) => {
                this.warehouses = warehouses;

            }, err => {
                feedbackMessage(FeedbackType.Error, 'Načtení skladů', 'Nepodařilo se načíst sklady.');
                console.log(err);
            });
    }

    templateSelector(): string {
        return 'default';
    }

    fillTextFields() {
        this.date.nativeElement.text = czechStringfromDate(new Date());
        this.inventoryType.nativeElement.text = this.inventoryTypes[0].name;
        this.note.nativeElement.text = '';
    }

    mainSwitchClicked(args: EventData) {
        this.warehouses.forEach(w => w.willBeInInventory = (<Switch>args.object).checked);
    }

    onTapItem(event: ListViewEventData) {
        this.warehouses[event.index].willBeInInventory = !this.warehouses[event.index].willBeInInventory;
    }

    onInventoryTypeTap(args: EventData) {
        const options = {
            message: 'Zvolte typ inventarizace',
            cancelButtonText: 'Zrušit',
            actions: this.inventoryTypes.map(obj => obj.name)
        };

        action(options).then(async (result) => {
            (<TextField>args.object).text = this.inventoryTypes.find(obj => obj.name === result).name;
        });
    }

    showDate(args: EventData) {
        this.othersIsLoading = true;
        const txtField = <TextField>args.object;
        const date = txtField.text.split('.');
        const options: ModalDialogOptions = {
            viewContainerRef: this.viewContainerRef,
            context: {
                day: date.length === 3 ? date[0].trim() : new Date().getDate(),
                month: date.length === 3 ? date[1].trim() : new Date().getMonth() + 1,
                year: date.length === 3 ? date[2].trim() : new Date().getFullYear(),
                minDate: this.dateLastInventory === '' ? null : new Date(this.dateLastInventory)
            },
            fullscreen: false
        };
        this.othersIsLoading = false;
        this.modalService.showModal(ModalDatePickerComponent, options)
            .then((result: Date) => {
                if (result) {
                    txtField.text = czechStringfromDate(result);
                }
            });
    }

    onBackButton(): void {
        this.routerExtensions.back();
    }

    createInventory() {
        if (this.warehouses.filter(w => w.willBeInInventory).length === 0) {
            feedbackMessage(FeedbackType.Error, 'Inventarizované sklady', 'Nebyl vybrán žádný sklad.');
        } else {
            this.store.dispatch(new CreateStockTakingInsert(
                this.warehouses.filter(w => w.willBeInInventory).map(w => +w.ID),
                dateFromCzechString(this.date.nativeElement.text).toISOString(),
                this.inventoryTypes.find(obj => obj.name === this.inventoryType.nativeElement.text).id,
                this.note.nativeElement.text))
                .pipe(withLatestFrom(this.stockTaking$))
                .subscribe(([_]) => {
                    feedbackMessage(FeedbackType.Success, 'Inventura vytvořena', 'Inventura byla úspěšně vytvořena.');
                    this.routerExtensions.back();
                }, err => {
                    feedbackMessage(FeedbackType.Error, 'Vytvoření inventarizace', 'Nepodařilo se založit novou inventarizaci.');
                    console.log(err);
                });
        }

    }

    get newIcon() {
        return String.fromCharCode(0xf271);
    }
}
