import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';

export default class Controller extends Section {
    constructor($element, $) {
        super($element, $);
        this.$checkAll = false;

        this.smartTableOptions = {
            activeButtons: {
                search: true,
            },
            columns: [
                {
                    field: 'state',
                    searchable: false
                }, {
                    field: 'futureState',
                    searchable: false
                }, {
                    field: 'totalWithVat',
                    searchable: false
                }, {
                    field: 'futureTotalWithVat',
                    searchable: false
                }, {
                    field: 'shipped',
                    searchable: false
                }, {
                    field: 'futureShipped',
                    searchable: false
                }, {
                    field: 'ipt',
                    autocomplete: {
                        url: 'ItemPackingTypes',
                        where: `{isActive: true}`,
                        showField: 'description',
                        valueField: 'code'
                    }
                }, {
                    field: 'futureIpt',
                    autocomplete: {
                        url: 'ItemPackingTypes',
                        where: `{isActive: true}`,
                        showField: 'description',
                        valueField: 'code'
                    }
                }, {
                    field: 'futureZoneFk',
                    autocomplete: {
                        url: 'Zones',
                    }
                },
            ]
        };
    }

    $postLink() {
        this.setDefaultFilter();
    }

    setDefaultFilter() {
        let today = Date.vnNew();
        const tomorrow = new Date(today);
        tomorrow.setDate(tomorrow.getDate() + 1);
        this.$http.get(`UserConfigs/getUserConfig`)
            .then(res => {
                this.filterParams = {
                    dateFuture: tomorrow,
                    dateToAdvance: today,
                    warehouseFk: res.data.warehouseFk
                };
                this.$.model.addFilter({}, this.filterParams);
            });
    }

    get checked() {
        const tickets = this.$.model.data || [];
        const checkedLines = [];
        for (let ticket of tickets) {
            if (ticket.checked)
                checkedLines.push(ticket);
        }

        return checkedLines;
    }

    dateRange(value) {
        const minHour = new Date(value);
        minHour.setHours(0, 0, 0, 0);
        const maxHour = new Date(value);
        maxHour.setHours(23, 59, 59, 59);

        return [minHour, maxHour];
    }

    totalPriceColor(totalWithVat) {
        return this.isLessThan50(totalWithVat) ? 'warning' : '';
    }

    totalPriceTitle(totalWithVat) {
        return this.isLessThan50(totalWithVat) ? 'Less than 50€' : '';
    }

    isLessThan50(totalWithVat) {
        return (parseInt(totalWithVat) > 0 && parseInt(totalWithVat) < 50);
    }

    get confirmationMessage() {
        if (!this.$.model) return 0;

        return this.$t(`Advance confirmation`, {
            checked: this.checked.length
        });
    }

    agencies(futureAgency, agency) {
        return this.$t(`Origin agency`, {agency: futureAgency}) +
            '\n' + this.$t(`Destination agency`, {agency: agency});
    }

    async moveTicketsAdvance() {
        let ticketsToMove = [];
        for (const ticket of this.checked) {
            if (!ticket.id) {
                try {
                    const {query, params} = await this.requestComponentUpdate(ticket, false);
                    this.$http.post(query, params);
                } catch (e) {}
                continue;
            }
            ticketsToMove.push({
                originId: ticket.futureId,
                destinationId: ticket.id,
                originShipped: ticket.futureShipped,
                destinationShipped: ticket.shipped,
                workerFk: ticket.workerFk
            });
        }

        const params = {tickets: ticketsToMove};
        return this.$http.post('Tickets/merge', params)
            .then(() => {
                this.refresh();
                if (ticketsToMove.length)
                    this.vnApp.showSuccess(this.$t('Success', {tickets: ticketsToMove.length}));
            });
    }

    async getLanded(params) {
        const query = `Agencies/getLanded`;
        return this.$http.get(query, {params}).then(res => {
            if (res.data)
                return res.data;

            return this.vnApp.showError(
                this.$t(`No delivery zone available for this landing date`)
            );
        });
    }

    async splitTickets() {
        this.progress = [];
        this.splitErrors = [];
        this.$.splitTickets.hide();
        this.$.splitProgress.enable = true;
        this.$.splitProgress.cancel = false;
        this.$.splitProgress.show();

        for (const ticket of this.checked) {
            if (this.$.splitProgress.cancel) break;
            try {
                const {query, params} = await this.requestComponentUpdate(ticket, true);
                this.$http.post(query, params)
                    .catch(e => {
                        this.splitErrors.push({id: ticket.futureId, reason: e.message});
                    })
                    .finally(() => this.progressAdd(ticket.futureId));
            } catch (e) {
                this.splitErrors.push({id: ticket.futureId, reason: e.message});
                this.progressAdd(ticket.futureId);
            }
        }
    }

    progressAdd(ticketId) {
        this.progress.push(ticketId);
        if (this.progress.length == this.checked.length) {
            this.$.splitProgress.enable = false;
            this.refresh();
            if ((this.progress.length - this.splitErrors.length) > 0) {
                this.vnApp.showSuccess(this.$t('Success', {
                    tickets: this.progress.length - this.splitErrors.length
                }));
            }
        }
    }

    async requestComponentUpdate(ticket, isWithoutNegatives) {
        const query = `tickets/${ticket.futureId}/componentUpdate`;
        if (!ticket.landed) {
            const newLanded = await this.getLanded({
                shipped: this.$.model.userParams.dateToAdvance,
                addressFk: ticket.futureAddressFk,
                agencyModeFk: ticket.agencyModeFk ?? ticket.futureAgencyModeFk,
                warehouseFk: ticket.futureWarehouseFk
            });
            if (!newLanded)
                throw new Error(this.$t(`No delivery zone available for this landing date`));

            ticket.landed = newLanded.landed;
            ticket.zoneFk = newLanded.zoneFk;
        }
        const params = {
            clientFk: ticket.futureClientFk,
            nickname: ticket.nickname,
            agencyModeFk: ticket.agencyModeFk ?? ticket.futureAgencyModeFk,
            addressFk: ticket.futureAddressFk,
            zoneFk: ticket.zoneFk ?? ticket.futureZoneFk,
            warehouseFk: ticket.futureWarehouseFk,
            companyFk: ticket.futureCompanyFk,
            shipped: this.$.model.userParams.dateToAdvance,
            landed: ticket.landed,
            isDeleted: false,
            isWithoutNegatives,
            newTicket: ticket.id ?? undefined,
            keepPrice: true
        };

        return {query, params};
    }

    refresh() {
        this.$.model.refresh();
        this.$checkAll = null;
    }

    exprBuilder(param, value) {
        switch (param) {
        case 'id':
        case 'futureId':
        case 'liters':
        case 'futureLiters':
        case 'lines':
        case 'futureLines':
        case 'totalWithVat':
        case 'futureTotalWithVat':
        case 'futureZone':
        case 'notMovableLines':
        case 'futureZoneFk':
            return {[param]: value};
        case 'ipt':
            return {'ipt': {like: `%${value}%`}};
        case 'futureIpt':
            return {'futureIpt': {like: `%${value}%`}};
        }
    }
}

Controller.$inject = ['$element', '$scope'];

ngModule.vnComponent('vnTicketAdvance', {
    template: require('./index.html'),
    controller: Controller
});