import ngModule from '../module';
import './style.scss';

class Controller {
    constructor($scope, $state, $http, vnApp, $translate) {
        this.$scope = $scope;
        this.vnApp = vnApp;
        this.$translate = $translate;
        this.$state = $state;
        this.$stateParams = $state.params;
        this.$http = $http;
        this.deletable = false;
        this.edit = {};
        this.moreOptions = [
            {callback: this.markAsReserved, name: 'Mark as reserved'},
            {callback: this.unmarkAsReserved, name: 'Unmark as reserved'},
            {callback: this.showEditDialog, name: 'Update discount'},
            {callback: this.createClaim, name: 'Add claim'}
        ];

        this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
    }

    set sales(value) {
        this._sales = value;
        this.refreshTotal();
    }

    get sales() {
        return this._sales;
    }

    refreshTotal() {
        this.loadSubTotal();
        this.loadVAT();
    }

    loadSubTotal() {
        this.subTotal = 0.0;
        if (!this.sales) return;
        this.subTotal = this.sales.reduce((sum, sale) => sum + this.getSaleTotal(sale), 0.0);
    }

    getSaleTotal(sale) {
        return sale.quantity * sale.price * ((100 - sale.discount) / 100);
    }

    loadVAT() {
        this.VAT = 0.0;
        if (!this.$stateParams.id || !this.sales) return;
        this.$http.get(`/ticket/api/Tickets/${this.$stateParams.id}/getVAT`).then(res => {
            this.VAT = res.data || 0.0;
        });
    }

    get total() {
        return this.subTotal + this.VAT;
    }

    onMoreOpen() {
        let options = this.moreOptions.filter(o => o.always || this.isChecked);
        this.$scope.moreButton.data = options;
    }

    onMoreChange(callback) {
        callback.call(this);
    }

    get isEditable() {
        try {
            return !this.ticket.state.state.alertLevel;
        } catch (e) {}

        return true;
    }

    get isChecked() {
        if (this.sales) {
            for (let instance of this.sales)
                if (instance.checked) return true;
        }

        return false;
    }

    getCheckedLines() {
        let lines = [];
        let data = this.sales;
        if (data) {
            for (let i = 0; i < data.length; i++) {
                if (data[i].checked)
                    lines.push({id: data[i].id, instance: i});
            }
        }
        return lines;
    }

    // Change State
    onStateOkClick() {
        let filter = {where: {code: 'OK'}, fields: ['id']};
        let json = encodeURIComponent(JSON.stringify(filter));
        this.$http.get(`/ticket/api/States?filter=${json}`).then(res => {
            this.onStateChange(res.data[0].id);
        });
    }

    onStateChange(value) {
        let params = {ticketFk: this.$state.params.id, stateFk: value};
        this.$http.post(`/ticket/api/TicketTrackings/changeState`, params).then(() => {
            this.card.reload();
            this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
        });
    }

    // Remove Lines
    onRemoveLinesClick(response) {
        if (response === 'ACCEPT') {
            let sales = this.getCheckedLines();
            let params = {sales: sales, actualTicketFk: this.ticket.id};
            let query = `/ticket/api/Sales/removes`;
            this.$http.post(query, params).then(() => {
                this.removeInstances(sales);
                this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
            });
        }
    }

    removeInstances(instances) {
        for (let i of instances)
            this.sales.splice(i.instance, 1);
        this.refreshTotal();
    }

    showRemoveLinesDialog() {
        this.$scope.deleteLines.show();
    }

    // Move Lines
    showTransferPopover(event) {
        let filter = {clientFk: this.ticket.clientFk, ticketFk: this.ticket.id};
        let json = encodeURIComponent(JSON.stringify(filter));
        let query = `/ticket/api/Tickets/threeLastActive?filter=${json}`;
        this.$http.get(query).then(res => {
            this.lastThreeTickets = res.data;
        });
        this.$scope.transfer.parent = event.target;
        this.$scope.transfer.show();
    }

    moveLines(ticketID) {
        let sales = this.getCheckedLines();

        let params = {sales: sales, newTicketFk: ticketID, actualTicketFk: this.ticket.id};
        this.$http.post(`/ticket/api/Sales/moveToTicket`, params).then(() => {
            this.goToTicket(ticketID);
        });
    }

    linesToNewTicket() {
        let ticket = {
            oldTicketFk: this.ticket.id,
            clientFk: this.ticket.clientFk,
            addressFk: this.ticket.addressFk,
            agencyModeFk: this.ticket.agencyModeFk,
            warehouseFk: this.ticket.warehouseFk
        };

        let sales = this.getCheckedLines();

        this.$http.post(`/api/Sales/MoveToNewTicket`, {ticket: ticket, sales: sales}).then(res => {
            let url = this.$state.href('ticket.card.sale', {id: res.data.id}, {absolute: true});
            window.open(url, '_blank');
            this.$scope.transfer.hide();
            this.$scope.model.refresh();
        });
    }

    createClaim() {
        let claim = {
            ticketFk: this.ticket.id,
            clientFk: this.ticket.clientFk,
            ticketCreated: this.ticket.shipped,
            workerFk: this.ticket.client.salesPersonFk
        };
        let sales = this.getCheckedLines();
        for (let i = 0; i < sales.length; i++)
            sales[i].quantity = this.sales[sales[i].instance].quantity;
        this.$http.post(`claim/api/Claims/createFromSales`, {claim: claim, sales: sales}).then(res => {
            this.$state.go('claim.card.basicData', {id: res.data.id});
        });
    }

    goToTicket(ticketID) {
        this.$state.go('ticket.card.sale', {id: ticketID});
    }

    // Focus First Input
    focusFirstInput(e) {
        let firstFocusable = e.querySelector('input, textarea');
        if (firstFocusable) {
            firstFocusable.addEventListener('focus', () => {
                firstFocusable.select();
            });
            setTimeout(() => {
                firstFocusable.focus();
            }, 200);
        }
    }

    // Slesperson Mana
    getManaSalespersonMana() {
        this.$http.get(`/api/Tickets/${this.$state.params.id}/getSalesPersonMana`).then(res => {
            this.mana = res.data;
        });
    }

    // Item Descriptor
    showDescriptor(event, itemFk) {
        this.quicklinks = {
            btnThree: {
                icon: 'icon-transaction',
                state: `item.card.diary({
                    id: ${itemFk}, 
                    warehouseFk: ${this.ticket.warehouseFk},
                    ticketFk: ${this.ticket.id}
                })`,
                tooltip: 'Item diary'
            }
        };
        this.$scope.descriptor.itemFk = itemFk;
        this.$scope.descriptor.parent = event.target;
        this.$scope.descriptor.show();
    }

    onDescriptorLoad() {
        this.$scope.popover.relocate();
    }

    // Edit Line
    showEditPricePopover(event, sale) {
        this.sale = sale;
        this.editedPrice = this.sale.price;
        this.edit = {
            ticketFk: this.ticket.id,
            id: sale.id,
            quantity: sale.quantity
        };
        this.$scope.editPricePopover.parent = event.target;
        this.$scope.editPricePopover.show();
        this.focusFirstInput(this.$scope.editPricePopover.$element[0]);
    }

    updatePrice() {
        if (this.editedPrice != this.sale.price) {
            this.$http.post(`/ticket/api/Sales/updatePrice`, {id: this.edit.id, price: this.editedPrice, ticketFk: this.ticket.id}).then(() => {
                this.sale.price = this.edit.price;
                this.$scope.model.refresh();
                this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
            });
        }

        this.$scope.editPricePopover.hide();
    }

    showEditPopover(event, sale) {
        this.sale = sale;
        this.edit = [{
            ticketFk: this.ticket.id,
            id: sale.id,
            quantity: sale.quantity,
            price: sale.price,
            discount: sale.discount
        }];
        this.$scope.editPopover.parent = event.target;
        this.$scope.editPopover.show();
        this.focusFirstInput(this.$scope.editPopover.$element[0]);
    }

    showEditDialog() {
        this.edit = this.getCheckedLines();
        this.$scope.editDialog.show();
        this.focusFirstInput(this.$scope.editDialog.$element[0]);
    }

    hideEditDialog() {
        this.$scope.model.refresh();
        this.$scope.editDialog.hide();
    }

    hideEditPopover() {
        this.$scope.model.refresh();
        this.$scope.editPopover.hide();
    }

    updateQuantity(id, quantity) {
        this.$http.post(`/ticket/api/Sales/${id}/updateQuantity`, {quantity: parseInt(quantity)}).then(() => {
            this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
        }).catch(e => {
            this.vnApp.showError(e.data.error.message);
        }).finally(() => {
            this.$scope.model.refresh();
        });
    }

    /**
     * Unmark sale as reserved
     */
    unmarkAsReserved() {
        this.setReserved(false);
    }

    /**
     * Mark sale as reserved
     */
    markAsReserved() {
        this.setReserved(true);
    }

    setReserved(reserved) {
        let sales = this.getCheckedLines();
        let params = {sales: sales, ticketFk: this.ticket.id, reserved: reserved};

        this.$http.post(`/ticket/api/Sales/reserve`, params).then(() => {
            this.$scope.model.refresh();
        });
    }

    newOrderFromTicket() {
        this.$http.post(`/api/Orders/newFromTicket`, {ticketFk: this.ticket.id}).then(res => {
            this.$state.go('order.card.catalog', {id: res.data});
            this.vnApp.showSuccess(this.$translate.instant('Order created'));
        });
    }
}

Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];

ngModule.component('vnTicketSale', {
    template: require('./index.html'),
    controller: Controller,
    bindings: {
        ticket: '<'
    },
    require: {
        card: '?^vnTicketCard'
    }
});