Price per TB Calculator & Sorter

Calculates price per TB, sorts products by value, and applies a color gradient.

// ==UserScript==
// @name         Price per TB Calculator & Sorter
// @namespace    https://greasyfork.org/en/users/1019658-aayush-dutt// @version      1.0
// @description  Calculates price per TB, sorts products by value, and applies a color gradient.
// @author       aayushdutt
// @match        https://www.primeabgb.com/*
// @grant        none
// @license      MIT
// @version      1.0
// ==/UserScript==

(function() {
    'use strict';

    // --- CONFIGURATION ---
    // Adjust these values to tweak the color gradient logic.
    const CONFIG = {
        currencySymbol: '₹',
        medianPrice: 2500, // The price point considered "average" (yellow).
        gradientRange: 2000  // The range around the median for the full gradient.
    };

    /**
     * Calculates a darker, high-contrast color based on the price per TB.
     * @param {number} price - The price per terabyte.
     * @returns {string} An RGB color string (e.g., 'rgb(200, 0, 0)').
     */
    function getColorForPrice(price) {
        const normalized = (price - CONFIG.medianPrice) / CONFIG.gradientRange;
        const clamped = Math.max(-1, Math.min(1, normalized));

        let r, g;
        if (clamped < 0) { // Gradient from Dark Green to Dark Yellow
            r = 200 * (1 + clamped);
            g = 150;
        } else { // Gradient from Dark Yellow to Dark Red
            r = 200;
            g = 150 * (1 - clamped);
        }
        return `rgb(${Math.round(r)}, ${Math.round(g)}, 0)`;
    }

    /**
     * Parses a product element to extract its title, price, and storage capacity.
     * @param {HTMLElement} productEl - The product's container element.
     * @returns {object|null} An object with product data or null if essential data is missing.
     */
    function parseProductData(productEl) {
        const titleElement = productEl.querySelector('.product-title a');
        const priceElement = productEl.querySelector('.price ins .woocommerce-Price-amount.amount bdi');

        if (!titleElement || !priceElement) return null;

        const title = titleElement.innerText;
        const tbMatch = title.match(/(\d+)\s*TB/i);

        if (!tbMatch) return null;

        const terabytes = parseInt(tbMatch[1], 10);
        const priceText = priceElement.innerText.replace(new RegExp(`[${CONFIG.currencySymbol},]`, 'g'), '');
        const price = parseFloat(priceText);

        if (isNaN(price) || isNaN(terabytes) || terabytes <= 0) return null;

        const pricePerTb = price / terabytes;
        return { element: productEl, pricePerTb };
    }

    /**
     * Creates and injects the price-per-TB element into the DOM.
     * @param {object} productData - The object returned from parseProductData.
     */
    function injectPriceDisplay(productData) {
        if (!productData) return;

        // Remove old element if the script is re-run
        const oldDisplay = productData.element.querySelector('.price-per-tb');
        if (oldDisplay) oldDisplay.remove();

        const displayEl = document.createElement('div');
        displayEl.className = 'price-per-tb';
        displayEl.innerText = `${CONFIG.currencySymbol}${productData.pricePerTb.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} / TB`;

        // Apply styles
        displayEl.style.fontSize = '14px';
        displayEl.style.fontWeight = 'bold';
        displayEl.style.color = getColorForPrice(productData.pricePerTb);
        displayEl.style.marginTop = '5px';

        const priceContainer = productData.element.querySelector('.product-price');
        if (priceContainer) {
            priceContainer.appendChild(displayEl);
        }
    }

    /**
     * Main function to orchestrate the script's execution.
     */
    function main() {
        const productContainer = document.querySelector('.products.products-wrap');
        if (!productContainer) {
            console.error("PricePerTB Script: Product container not found.");
            return;
        }

        const products = Array.from(productContainer.querySelectorAll('.product.type-product'));

        const productsData = products.map(parseProductData).filter(Boolean);

        // Inject the price display for each valid product.
        productsData.forEach(injectPriceDisplay);

        // Sort the products based on price per TB (lowest to highest).
        productsData.sort((a, b) => a.pricePerTb - b.pricePerTb);

        // Re-append the sorted elements into the container.
        productsData.forEach(item => {
            productContainer.appendChild(item.element);
        });
    }

    // Run the script.
    main();

})();