import {Component, OnInit} from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import {
    MatTableDataSource,
    MatSelectModule,
    MatCheckboxModule,
    MatDatepickerModule,
    MatNativeDateModule
} from '@angular/material';
import {HttpClient} from '@angular/common/http';
import {Product} from '../products/products.component';
import {CartService} from '../core/cart.service';
import {AppConfig} from '../config/app.config';
import {AlertService} from '../core/alert.service';

import * as _moment from 'moment';

const moment = _moment;

@Component({
    templateUrl: 'cart.component.html'
})

export class CartComponent implements OnInit {
    displayedColumns = ['prodDesc', 'prodQty', 'remove'];
    dataSource;
    currentUser: any;
    cartData: any;
    userData: any;
    products = [];
    timeoutId;
    vehicles = [];
    states = [];
    branches = [];
    requestedTimeCodes = [];
    despatchType = 'CPKUP';
    clientName = '';
    clientAddress = '';
    clientSuburb = '';
    clientState = '';
    clientEmail = '';
    nameContact = '';
    phoneContact = '';
    orderNumber = '';
    branchID: string;
    instructions = '';
    requiredDate;
    vehicleTypeID: string;
    areaID = '';
    onSite = false;
    requiredTime;

    constructor(private route: ActivatedRoute,
                private router: Router,
                private http: HttpClient,
                private cartService: CartService,
                private alertService: AlertService) {
        this.currentUser = JSON.parse(sessionStorage.getItem(AppConfig.relativeURL + 'currentUser'));
        this.cartData = JSON.parse(sessionStorage.getItem(AppConfig.relativeURL + 'cartData'));
        this.userData = JSON.parse(sessionStorage.getItem(AppConfig.relativeURL + 'userData'));

        this.getVehicles(this.currentUser.sessionID).subscribe(
            data => {
                this.vehicles = data.dataset.VehicleTypes;
            },
            error => {
                console.log(error); // Error if any
            });

        this.getStates(this.currentUser.sessionID).subscribe(
            data => {
                this.states = data.dataset.stateList;
            },
            error => {
                console.log(error); // Error if any
            });
        this.getBranches(this.currentUser.sessionID).subscribe(
            data => {
                this.branches = data.dataset.BranchList;
            },
            error => {
                console.log(error); // Error if any
            });

        this.getListRequestedTimeCodes(this.currentUser).subscribe(
            data => {
                this.requestedTimeCodes = data.dataset.RequestedTimeList;
            },
            error => {
                console.log(error); // Error if any
            });
    }

    ngOnInit() {
        this.cartService.getCart(this.currentUser, this.cartData.sessionID).subscribe(
            data => {
                if (data.dataset) {
                    PRODUCT_DATA = data.dataset.CartContents;
                    this.dataSource = new MatTableDataSource(PRODUCT_DATA);
                }
            },
            error => {
                console.log(error); // Error if any
            });
    }

    increment(product) {
        if (isNaN(product.prodQty)) {
            product.prodQty = 1;
        }
        product.prodQty++;
        this.updateQty(product);
    }

    decrement(product) {
        if (isNaN(product.prodQty)) {
            product.prodQty = 1;
        }
        if (product.prodQty <= 1) {
            return;
        }
        product.prodQty--;
        this.updateQty(product);
    }

    tabChanged(event) {
        if (event.index === 0) {
            this.despatchType = 'CPKUP';
        } else {
            this.despatchType = 'LOCAR';
        }
    }

    remove(product) {
        this.cartService.removeItem(this.currentUser, this.cartData.sessionID, product);
        this.cartService.getCart(this.currentUser, this.cartData.sessionID).subscribe(
            data => {
                PRODUCT_DATA = data.dataset.CartContents;
                this.dataSource = new MatTableDataSource(PRODUCT_DATA);
                this.dataSource.paginator = this.dataSource.paginator;

            },
            error => {
                console.log(error); // Error if any
            });
    }

    process() {
        if (this.despatchType === 'CPKUP') {
            this.processComplete(this.currentUser.sessionID, this.cartData.sessionID).subscribe(
                data => {
                    this.processCompleteResponse(data.quoteNumber);
                },
                error => {
                    if (typeof error === 'string') {
                        this.alertService.error(error);
                    } else {
                        this.alertService.error('Connection error');
                    }
                });
        } else {
            this.getGeocode(this.currentUser, this.clientAddress, this.clientSuburb, this.clientState).subscribe(
                geocodeData => {
                    this.getClosestBranch(this.currentUser, geocodeData.latitude, geocodeData.longitude, this.vehicleTypeID).subscribe(
                        branchData => {
                            branchData.dataset.DeliveryBranch.forEach(item => {
                                if (item.closest) {
                                    this.getDeliveryCharge(this.currentUser, item.branchID, item.distanceKm, this.vehicleTypeID).subscribe(
                                        chargeData => {
                                            chargeData = chargeData.dataset.Delivery[0];
                                            const product = {
                                                productID: chargeData.deliveryChargeProduct
                                            };
                                            this.cartService.addItem(this.currentUser, this.cartData.sessionID, product, 1, chargeData.delivCharge);
                                            this.branchID = item.branchID;
                                            this.areaID = chargeData.areaID;
                                            this.processComplete(this.currentUser.sessionID, this.cartData.sessionID).subscribe(
                                                data => {
                                                    this.processCompleteResponse(data.quoteNumber);
                                                },
                                                error => {
                                                    if (typeof error === 'string') {
                                                        this.alertService.error(error);
                                                    } else {
                                                        this.alertService.error('Connection error');
                                                    }
                                                });
                                        },
                                        error => {
                                            if (typeof error === 'string') {
                                                this.alertService.error(error);
                                            } else {
                                                this.alertService.error('Connection error');
                                            }
                                        });
                                }
                            });
                        },
                        error => {
                            if (typeof error === 'string') {
                                this.alertService.error(error);
                            } else {
                                this.alertService.error('Connection error');
                            }
                        });
                },
                error => {
                    if (typeof error === 'string') {
                        this.alertService.error(error);
                    } else {
                        this.alertService.error('Connection error');
                    }
                });
        }
    }

    processCompleteResponse(quoteNumber: string) {
        this.alertService.success('Your transaction has now been saved. For future reference your transaction number is #' + quoteNumber);
        this.cartService.createCart(this.currentUser.sessionID, this.userData.id_cust)
            .subscribe(
                cartData => {
                    sessionStorage.setItem(AppConfig.relativeURL + 'cartData', JSON.stringify(cartData));
                    this.cartService.updateCartItems(this.currentUser, cartData.sessionID);
                },
                error => {
                    console.log(error);
                });
        this.router.navigate([AppConfig.routes.home]);
    }

    updateQty(product) {
        if (this.timeoutId) {
            window.clearTimeout(this.timeoutId);
        }
        this.timeoutId = window.setTimeout(() => {
            this.cartService.updateItem(this.currentUser, this.cartData.sessionID, product);
        }, 500);
    }

    private processComplete(sessionID: string, cartSessionID: string) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.processComplete + sessionID, {
            'deviceID': 'tportal',
            'sessionID': cartSessionID,
            'tpaID': 'tportal',
            'branchID': this.branchID,
            'customerID': this.userData.id_cust,
            'customerName': '',
            'customerAddress': '',
            'customerState': '',
            'customerPostcode': '',
            'customerEmail': this.userData.userEmailAddress,
            'clientName': this.clientName,
            'clientAddress': this.clientAddress,
            'clientSuburb': this.clientSuburb,
            'clientState': this.clientState,
            'clientPostcode': '',
            'clientEmail': this.clientEmail,
            'buildersRef': this.orderNumber,
            'buildersContact': this.nameContact,
            'salesRepID': 0,
            'dateRequired': moment(this.requiredDate).format(),
            'despatchMethod': this.despatchType,
            'shippingInstructions': this.instructions,
            'quoteOutput': '',
            'quoteProduceWithSellPrices': false,
            'specOutputType': '',
            'specModifier': '',
            'brochureOutputType': '',
            'transactionType': 'Order',
            'saleDeliveryDetails': [
                {
                    'id_deliv_area': this.areaID,
                    'qty_items_deliv': 0,
                    'id_vehicle': '',
                    'num_consign': '',
                    'id_transport_company': '',
                    'cost_freight': 0.0,
                    'weight_deliv_kg': 0,
                    'qty_cubes_deliv': 0.0,
                    'time_deliv_required': this.requiredTime,
                    'is_for_fixed_time': false,
                    'type_load': '',
                    'id_branch': this.branchID,
                    'num_deliv_run': 0,
                    'num_drop': 0,
                    'date_deliv': moment(this.requiredDate).format(),
                    'code_run_sheet': '',
                    'time_driver_start': 0,
                    'time_driver_end': 0,
                    'map_ref': '',
                    'map_xref': '',
                    'time_site_arrive': 0,
                    'time_site_depart': 0,
                    'has_site_signature': false,
                    'has_site_name': false,
                    'has_phoned': false,
                    'time_unloaded': 0,
                    'name_driver': '',
                    'comments_driver_1': '',
                    'comments_driver_2': '',
                    'comments_driver_3': '',
                    'latitude': '',
                    'longitude': '',
                    'is_contact_on_site': this.onSite,
                    'type_vehicle': this.vehicleTypeID,
                    'name_contact': this.nameContact,
                    'phone_contact': this.phoneContact
                }
            ]
        }, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            if (data && data.errorTable) {
                throw data.errorTable[0].msg;
            } else {
                return data;
            }
        });
    }

    private getVehicles(sessionID: string) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getVehicleTypes + sessionID, {}, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            return data;
        });
    }

    private getStates(sessionID: string) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getState + sessionID, {}, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            return data;
        });
    }

    private getBranches(sessionID: string) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getBranches + sessionID, {}, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            return data;
        });
    }

    private getListRequestedTimeCodes(currentUser) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getListRequestedTimeCodes + currentUser.sessionID, {
            'userName': currentUser.userName,
            'deviceID': 'tportal'
        }, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            return data;
        });
    }

    private getGeocode(currentUser, address, suburb, state) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getGeocode + currentUser.sessionID, {
            'addressLine1': address,
            'addressLine2': suburb,
            'addressLine3': state
        }, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            if (data && data.errorTable) {
                throw data.errorTable[0].msg;
            } else {
                return data;
            }
        });
    }

    private getClosestBranch(currentUser, latitude, longitude, vehicle) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getClosestBranch + currentUser.sessionID, {
            'userName': currentUser.userName,
            'deviceID': 'tportal',
            'latitudeDelivery': latitude,
            'longitudeDelivery': longitude,
            'vehicleType': vehicle
        }, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            if (data && data.errorTable) {
                throw data.errorTable[0].msg;
            } else {
                return data;
            }
        });
    }

    private getDeliveryCharge(currentUser, branchID, distanceKm, vehicleType) {
        return this.http.post<any>(AppConfig.endpointURL() + AppConfig.endpoints.getDeliveryCharge + currentUser.sessionID, {
            'userName': currentUser.userName,
            'deviceID': 'tportal',
            'branchID': branchID,
            'distanceKm': distanceKm,
            'vehicleType': vehicleType
        }, {headers: {'Content-Type': 'text/plain'}}).map(data => {
            if (data && data.errorTable) {
                throw data.errorTable[0].msg;
            } else {
                return data;
            }
        });
    }

}

let PRODUCT_DATA: Product[];
