class DataStore {
    constructor(vehicles) {
        this.vehicles = vehicles;
        this.subscribers = [];
        this.filters = {};
        this.notifySubscribers();
    }

    subscribe(subscriber) {
        this.subscribers.push(subscriber);
    }

    unsubscribe(subscriber) {
        this.subscribers = this.subscribers.filter((s) => s !== subscriber);
    }

    unsubscribeAll() {
        this.subscribers = [];
    }

    notifySubscribers(filteredVehicles = this.vehicles) {
        const activeFilters = Object.keys(this.filters);
        if (activeFilters.length > 0) {
            filteredVehicles = this.filterVehicles(filteredVehicles);
        }

        this.subscribers.forEach((subscriber) => {
            subscriber(filteredVehicles);
        });
    }

    addFilter(type, value) {
        this.filters[type] = this.filters[type] || [];
        this.filters[type].push(value);

        this.notifySubscribers();
    }

    removeFilter(type, value) {
        if (this.filters[type]) {
            this.filters[type] = this.filters[type].filter((filter) => filter !== value);
            if (this.filters[type].length === 0) {
                delete this.filters[type];
            }

            this.notifySubscribers();
        }
    }

    filterVehicles(vehicles = this.vehicles) {
        return vehicles.filter((vehicle) => {
            for (const [type, values] of Object.entries(this.filters)) {
                if(Array.isArray(vehicle[type])){
                    if(vehicle[type].some(value => values.includes(value))){
                        return true;
                    }
                }
                if (!values.includes(vehicle[type])) {
                    return false;
                }
            }
            return true;
        });
    }

    getAppliedFilters() {
        return Object.entries(this.filters).map(([type, values]) => ({ type, values }));

    }

    sortBy(property, order) {
        this.vehicles.sort((a, b) => {
            const aValue = a[property];
            const bValue = b[property];

            if (order === 'asc') {
                return aValue > bValue ? 1 : -1;
            } else {
                return bValue > aValue ? 1 : -1;
            }
        });

        this.notifySubscribers();
    }

    sortByFinance(order) {
        this.vehicles.sort((a, b) => {
            const aValue = this.calculateFinance(a);
            const bValue = this.calculateFinance(b);

            if (order === 'asc') {
                return aValue.payment - bValue.payment;
            } else {
                return bValue.payment - aValue.payment;
            }
        });

        this.notifySubscribers();
    }

    calculateFinance(vehicle) {
        let annInterest = 7.99;
        let monInt = annInterest / 1200;
        let months = 12;
        let amount = vehicle.advertise_price;
        let down = 0;
        let trade = 0;

        var financeTotal = amount - (down + trade);
        var numberOfPayments = months / (12 / 26);
        var interest = financeTotal * (annInterest / 26) * numberOfPayments;
        var additionalFees = 0;
        var totalCostOfCredit = interest + additionalFees;
        var totalObligation = financeTotal + totalCostOfCredit;

        var payment = ((monInt + (monInt / (Math.pow((1 + monInt), months) - 1))) * (amount - (down || 0)) / 2).toFixed(2);

        return {
            financeTotal: financeTotal,
            numberOfPayments: numberOfPayments,
            interest: interest,
            additionalFees: additionalFees,
            totalCostOfCredit: totalCostOfCredit,
            totalObligation: totalObligation,
            payment: parseFloat(payment) // Convert payment to a number
        };
    }

}
