import { PriceChangeFilter, Money, FlashSaleData } from "./types";

class PriceChangeService {
    readonly flashSalePercent: number;
    constructor() {
        this.flashSalePercent = 30;
    }
    /**
     * Decorates items with price changes based on tracking history
     * @param items - Array of items to decorate
     * @param options - Configuration options
     */
    public decor(items: any[], options: any) {
        if (items && items.length > 0) {
            const filter = this.buildFilter(options);

            items.forEach((item) => {
                const pId = this.getByCol(item, filter.pIdCol);
                if (!pId) {
                    return;
                }
                if (filter.decorMoney) {
                    this.decorItem(item, filter.decorMoney, filter.columns);
                    console.log(item);
                }
                this.decorItemFlashSale(item, filter.columns, filter);
            });
        }
    }

    /**
     * Builds filter options from provided options
     * @param options - Configuration options
     * @returns Filter options
     */
    protected buildFilter(options: any): PriceChangeFilter {
        const columns = options.columns || ["price", "high_price"];
        const pIdCol = options.pIdCol || "id";
        const flashSaleData = options.flashSaleData;
        const decorMoney = options.decorMoney;
        const result: PriceChangeFilter = {
            columns,
            pIdCol,
            flashSaleData,
            decorMoney,
        };
        return result;
    }

    /**
     * Decorates a single item
     * @param item - Item to decorate
     * @param money - Money to apply
     * @param columns - Columns to update
     */
    public decorItem(item: any, money: Money, columns: string[] = ["price", "high_price"]) {
        columns.forEach((column) => {
            const value = this.getByCol(item, column);
            if (!value || value < 1) {
                return;
            }

            let newValue = value;
            if (money.type === "replace") {
                newValue = money.value;
            } else if (money.type === "add") {
                newValue += money.value;
            } else if (money.type === "percent") {
                newValue *= money.value;
                newValue = Math.round(newValue * 100) / 100;
            }

            if (item[column] !== undefined) {
                item[column] = newValue;
            }
        });
    }

    /**
     * Decorates a flash sale item
     * @param item - Item to decorate
     * @param columns - Columns to update
     * @param filter - Filter options
     */
    public decorItemFlashSale(item: any, columns: string[] = ["high_price"], filter: PriceChangeFilter) {
        columns.forEach((column) => {
            if (column === "high_price") {
                const flashSaleData = this.decorFlashSaleHighPrice(item, filter);

                if (flashSaleData.is_flash_sale && flashSaleData.high_price) {
                    this.decorItem(item, { type: "replace", value: flashSaleData.high_price }, [column]);
                    item.flash_sale_data = {
                        is_flash_sale: 1,
                        end_at: flashSaleData.end_at,
                        sale_percent: flashSaleData.sale_percent,
                        high_price: flashSaleData.high_price,
                    }
                }

            }
        });
    }

    /**
     * Decorates flash sale high price
     * @param item - Item to decorate
     * @param column - Column to update
     * @param filter - Filter options
     * @returns Flash sale data
     */
    protected decorFlashSaleHighPrice(item: any, filter: PriceChangeFilter): FlashSaleData {
        const result: FlashSaleData = {
            is_flash_sale: false,
        };

        if (filter.flashSaleData && filter.flashSaleData.sale_percent) {
            const flashSale = filter.flashSaleData;
            const percentFlashSale = flashSale.sale_percent || this.flashSalePercent;
            const price = this.getByCol(item, "price");
            let highPrice = Math.round((price / (100 - percentFlashSale)) * 100 * 100) / 100;
            const fee = this.getByCol(item, "fee");

            if (fee && fee > 0) {
                highPrice = Math.round(((price - fee) / (100 - percentFlashSale)) * 100 + fee * 100) / 100;
            }

            result.is_flash_sale = true;
            result.end_at = flashSale.end_at || undefined;
            result.sale_percent = percentFlashSale;
            result.high_price = highPrice;

            return result;
        }

        return result;
    }

    protected getByCol(item: any, column: string) {
        let val = null;
        if (item && item[column]) {
            val = item[column];
        }
        return val;
    }
}

// Export a singleton instance
export default PriceChangeService;
