const API_KEY = '3d87c9707f96efe2a046e39865b0e84dda8b9c8345d0c22f7f646f4b0d67';
const API_V0 = 'https://api.cryptorank.io/v0/';
const API_V1 = 'https://api.cryptorank.io/v1/';
const container = document.querySelector('#fetchedItems'); // items container
let activeFilter; // market | ath | gainers
let theme; // dark | light

let graphPeriod = 'day'; // day | week
const graphType = 'USD'; // USD | marketCap | volumes

function onFilter(filter) {
    if(filter === activeFilter) return;
    if(!filter) filter = activeFilter;
    activeFilter = filter;
    theme = (filter === 'gainers') ? 'light' : 'dark';

    const FMC = document.querySelector('#filterMarketCap');
    const FATH = document.querySelector('#filterATH');
    const ATHSort = document.querySelector('#ATHSort');
    const ATHFilter = document.querySelector('#athFi');
    const FTG = document.querySelector('#filterGainers');
    const TGSorting = document.querySelector('#topGainers');

    // Remove active class from all filter buttons
    const filters = [FMC, FATH, FTG];
    filters.forEach(i => {
        if(i.classList.contains('active')) i.classList.remove('active');
    })

    // Fetch coins by selected filter
    if(filter === 'market') {
        FMC.classList.add('active'); // Select active filter btn
        TGSorting.classList.add('hidden')
        ATHSort.classList.add('hidden')
        ATHFilter.classList.add('hidden')
        getMarketCap();
        theme = 'dark';
    }
    if(filter === 'ath') {
        FATH.classList.add('active'); // Select active filter btn
        ATHSort.classList.remove('hidden')
        ATHFilter.classList.remove('hidden')
        TGSorting.classList.add('hidden')
        getATH();
        theme = 'dark';
    }
    if(filter === 'gainers') {
        FTG.classList.add('active'); // Select active filter btn
        TGSorting.classList.remove('hidden')
        ATHSort.classList.add('hidden')
        getTopGainers();
    }
}

function getMarketCap(options) {
    onShowPreloader();
    getCurrencies(null, options ? 0 : 10)
        .then(async resp => {
            const filteredResp = sortAndFilter(options, resp).slice(0, 10)
            return [
                filteredResp,
                await getCoins(filteredResp.map(item => item.name)),
                await getExchanges(filteredResp.map(item => item['slug'])),
                await getHistory(filteredResp.map(item => item['slug']))
            ]
        })
        .then(([currencies, coins, exchanges, history]) => {
            onPrepareData(currencies, coins, exchanges, history)
        })
}

function getATH(options) {
    onShowPreloader();

    const isSortBy = options && options.sortBy;

    function sortByPrice(a, b) {
        return (a['athPrice']['USD'] === null) - (b['athPrice']['USD'] === null) || + (a['athPrice']['USD'] > b['athPrice']['USD']) || - (a['athPrice']['USD'] < b['athPrice']['USD'])
    }

    function sortByRank(a, b) {
        return (a['rank'] === null) - (b['rank'] === null) || + (a['rank'] > b['rank']) || - (a['rank'] < b['rank'])
    }

    getCoins()
        .then(resp => {
            return sortAndFilter(options, resp)
                .filter(i => i['athPrice'])
                .sort((a,b) => new Date(a.athPrice['date']).getTime() - new Date(b.athPrice['date']).getTime())
                .reverse()
                .filter(i => i.athPrice['date'] === getFormattedTodayDate())
                .sort((a, b) => (!isSortBy || options.sortBy === 'rank') ? sortByRank(a, b) : sortByPrice(a, b))
                .slice(0, 10);
        })
        .then(async resp => {
            return [
                resp,
                await getCurrencies(resp.map(item => item.name)),
                await getExchanges(resp.map(item => item['key'])),
                await getHistory(resp.map(item => item['key']))
            ]
        })
        .then(([coins, currencies, exchanges, history]) => {
            const data = coins.map(item => {

                let percentage = currencies.find(c => c.name === item.name) ? item.athPrice['USD'] / currencies.find(c => c.name === item.name).values['USD']['low24h'] : null;
                let dir = currencies.find(c => c.name === item.name) ? Math.sign(item.athPrice['USD'] / currencies.find(c => c.name === item.name).values['USD']['low24h']) : null;

                if(options && options.period === 'percentChange7d') {
                    const min = Math.min.apply(null, history.find(e => e.name === item['key']).values.map(i => i['USD']))
                    percentage = item.athPrice['USD'] / min;
                    dir = Math.sign(item.athPrice['USD'] / min);
                }

                // NEW CALCULATION
                // const percentage = currencies.find(c => c.name === item.name) ? currencies.find(c => c.name === item.name).values['USD']['percentChange24h'] : null;
                // const dir = currencies.find(c => c.name === item.name) ? Math.sign(currencies.find(c => c.name === item.name).values['USD']['percentChange24h']) : null;

                return {
                    coinLogo: item['image'] ? item['image'] : '',
                    ticker: item['symbol'] ? item['symbol'] : '',
                    coinName: item.name ? item.name : 'N/A',
                    marketCap: item.marketCap > 0 ? '$' + convertToAbbreviate(item.marketCap) : 'N/A',
                    percentage: percentage ? (activeFilter === 'ath' ? (percentage * 100 - 100).toFixed(2) : percentage.toFixed(2)) : 'N/A',
                    percentagePeriod: options && options.period === 'percentChange7d' ? '7D' : '24H',
                    direction: (dir && dir === -1) ? 'down' : (dir && dir === 1 ? 'up' : 'na'),
                    athPrice: item.athPrice['USD'] ? convertToCurrency(item.athPrice['USD']) : 'N/A',
                    exchangeLogo: item['key'] ? exchanges.find(e => e.coin === item['key']).logo : '',
                    exchangeName: item['key'] ? exchanges.find(e => e.coin === item['key']).name : '',
                    graphImg: history ? generateSVG(history.find(e => e.name === item['key'])['values'], true) : null
                }
            })

            showData((!isSortBy || options.sortBy === 'rank') ? data : data.reverse())
        })
}

function getTopGainers(options) {
    const sortBy = (options && options.sortBy) ? options.sortBy : 'percentChange24h';
    onShowPreloader();

    getCurrencies()
        .then(resp => {
            let filteredResp = resp;

            if(options && options.filters) {
                if (options.filters.marketCap) {
                    const minValue = options.filters.marketCap;
                    filteredResp = filteredResp.filter(i => i['values'] && i['values']['USD'] && i['values']['USD']['marketCap'] > minValue)
                }
                if (options.filters.rank) {
                    const minValue = options.filters.rank;
                    filteredResp = filteredResp.filter(i => i['rank'] && i['rank'] > minValue)
                }
                if (options.filters.volume) {
                    const minValue = options.filters.volume;
                    filteredResp = filteredResp.filter(i => i['values'] && i['values']['USD'] && i['values']['USD']['volume24h'] > minValue)
                }
            }

            return filteredResp
                .filter(i => Math.sign(i['values']['USD'][sortBy]) === 1 || Math.sign(i['values']['USD'][sortBy]) === 0)
                .filter(i => i['values']['USD'][sortBy])
                .sort((a,b) => a['values']['USD'][sortBy] - b['values']['USD'][sortBy])
                .reverse()
                .slice(0,10)
        })
        .then(async resp => {
            return [
                resp,
                await getCoins(resp.map(item => item.name)),
                null,// await getExchanges(resp.map(item => item['slug'])),
                await getHistory(resp.map(item => item['slug']))
            ]
        })
        .then(([currencies, coins, exchanges, history]) => {
            onPrepareData(currencies, coins, exchanges, history, sortBy)
        })
}

function getIEO() {
    onShowPreloader();
    getCoins()
        .then(async resp => [resp, await getCrowdSales()])
        .then(([coins, crowdSales]) => {
            const CS = [];
            Object.keys(crowdSales).forEach(name => {
                const coin = coins.find(c => c.key === name);
                if(coin['price'] && coin['price']['USD'] && coin['athPrice'] && coin['athPrice']['USD']) {
                    crowdSales[name].forEach(i => {
                        if(i['type'] === 'IEO' && i['price'] && i['price']['USD']){
                            CS.push({
                                image: coin['image'],
                                key: coin['key'],
                                symbol: coin['symbol'],
                                name: coin['name'],
                                ROI: (coin['price']['USD'] - i['price']['USD']) / i['price']['USD'] * 100,
                                ATH_ROI: (coin['athPrice']['USD'] - i['price']['USD']) / i['price']['USD'] * 100
                            })
                        }
                    })
                }
            })

            const TOP = CS.sort((a, b) => ((a && a['ROI']) > (b && b['ROI'])) ? 1 : -1).reverse().slice(0, 10);

            return getExchanges(TOP.map(i => i.key)).then(resp => {
                resp.forEach(i => {
                    TOP.find(c => c.key === i.coin).exchangeLogo = i['logo'];
                    TOP.find(c => c.key === i.coin).exchangeName = i['name'];
                })

                container.innerHTML = TOP.map((item, index) => {
                    return `
                        <tr>
                            <td>${index + 1}</td>
                            <td>
                                <div class="sc-coin-label" style="user-select: auto;">
                                    <div class="sc-coin-logo" style="user-select: auto;">
                                        <img src="${item['image']}" alt="" style="user-select: auto;" class="should-be-updated">
                                    </div>
                                    <div class="sc-coin-name" style="user-select: auto;">
                                        <div class="sc-coin-shortname" style="user-select: auto;"><span class="accent-color" style="user-select: auto;">${item['symbol']}</span></div>
                                        <div class="sc-coin-fullname opacity-6" style="user-select: auto;">${item['name']}</div>
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="ieo-topexchange">
                                    <span><img src="${item['exchangeLogo']}" alt="" class="should-be-updated"></span>${item['exchangeName']}
                                </div>
                            </td>
                            <td class="ieo-chart-td">
                                <div class="ieo-chartline ieo-currentvalue-chartline" style="width: ${item['ROI'] / (item['ATH_ROI'] / 100)}%;">
                                    <span class="ieo-chart-label" style="right: ${item['ROI'] / (item['ATH_ROI'] / 100) > 80 ? '7rem' : '-1.8rem'}">${item['ROI'].toFixed(2)}%</span>
                                </div>
                                <div class="ieo-chartline ieo-ath-chartline" style="width: ${100 - item['ROI'] / (item['ATH_ROI'] / 100)}%;">
                                    <span class="ieo-chart-label">${item['ATH_ROI'].toFixed(2)}%</span>
                                </div>
                            </td>
                        </tr>
                    `
                }).join("");

                updateImages();

            })

        })
}

function onPrepareData(currencies, coins, exchanges, history, GPT) {
    const data = currencies.map(item => {
        const percentage = item.values['USD'][GPT ? GPT : 'percentChange24h'];
        let percentagePeriod = '24H';
        const dir = Math.sign(item.values['USD'][GPT? GPT : 'percentChange24h']);
        let athPrice = 0;
        let ATH = 0;

        if(activeFilter === 'gainers') {
            const z = currencies.find(c => c.name === item.name)['values']['USD']['price'];
            console.log(z)
            ATH = '$' + removeZeroFromTheEnd(z > 1 ? z.toFixed(2) : (z + '').includes('e') ? z.toFixed(20) : z.toPrecision(4))
        } else {
            athPrice = coins.find(c => c.name === item.name).athPrice;
            ATH = athPrice ? convertToCurrency(coins.find(c => c.name === item.name).athPrice['USD']) : 'N/A'
        }

        if(GPT) {
            if(GPT === 'percentChange24h') { percentagePeriod = '24H'}
            if(GPT === 'percentChange7d') { percentagePeriod = '7D'}
            if(GPT === 'percentChange30d') { percentagePeriod = '30D'}
            if(GPT === 'percentChange3m') { percentagePeriod = '3M'}
        }

        return {
            coinLogo: item.images ? item.images['200x200'] : '',
            ticker: item['symbol'] ? item['symbol'] : 'N/A',
            coinName: item.name ? item.name : 'N/A',
            marketCap: item.values['USD'].marketCap === 0 ? 'N/A' : (item.values['USD'].marketCap > 0 ? '$' + convertToAbbreviate(item.values['USD'].marketCap) : 'N/A'),
            percentage: percentage ? (activeFilter === 'ath' ? (percentage * 100 - 100).toFixed(2) : percentage.toFixed(2)) : 'N/A',
            percentagePeriod: percentagePeriod,
            direction: (dir && dir === -1) ? 'down' : (dir && dir === 1 ? 'up' : 'na'),
            athPrice: ATH,
            exchangeLogo: exchanges ? exchanges.find(e => e.coin === item['slug']).logo : '',
            exchangeName: exchanges ? exchanges.find(e => e.coin === item['slug']).name : 'N/A',
            volume: item.values['USD']['volume24h'] && item.values['USD']['volume24h'] > 0 ? '$' + convertToAbbreviate(item.values['USD']['volume24h']) : 'N/A',
            graphImg: history ? generateSVG(history.find(e => e.name === item['slug'])['values']) : null,
        }
    })
    showData(data)
}

function showData(items) {
    container.innerHTML = items.map((item, index) => {
        return `
        <a href="javascript:void(0)">
            <div class="sc-card ${theme === 'dark' ? 'ath-card' : 'tg-card'}">
                <div class="sc-card-serial">
                    <span class="sc-card-serial-span ${theme === 'dark' ? 'ath' : 'tg'}-card-serial-span">${index +1}</span>
                </div>
                <div class="sc-card-icon">
                    <img src="${item['coinLogo']}" alt="" class="should-be-updated">
                </div>
                <div class="sc-card-body">
                    <div class="sc-card-body-top">
                        <div class="sc-card-heading">
                            <span class="coin-shortname">${item['ticker']}</span>
                            <span class="coin-fullname opacity-${theme === 'dark' ? '6' : '8'}">${item['coinName']}</span>
                        </div>
                        <div class="sc-card-graph">
                            ${item['graphImg'] ? item['graphImg'] : '<img src="../images/graph-img.svg" alt="">'}
                        </div>
                    </div>
                    <div class="sc-card-body-bottom">
                        <div class="sc-card-info-col">
                            <div class="sc-info-heading opacity-${theme === 'dark' ? '6' : '8'}">Market Cap</div>
                            <div class="sc-info-data">${item['marketCap']}</div>
                        </div>
                        <div class="sc-card-info-col">
                            <div class="sc-info-heading opacity-${theme === 'dark' ? '6' : '8'}">
                                ${theme === 'dark' ? 'ATH Price' : 'Price'}
                            </div>
                            <div class="sc-info-data">${item['athPrice']}</div>
                        </div>
                        <div class="sc-card-info-col">
                            <div class="sc-info-heading opacity-${theme === 'dark' ? '6' : '8'}">
                                &percnt;${item['percentagePeriod']}
                            </div>
                            <div class="sc-info-data ${theme === 'dark' ? 'ath' : 'tg'}-info-data--24h_${item['direction']}">
                                ${item['percentage']}
                                <img src="./images/${item['direction']}-icon.svg" alt="">
                            </div>
                        </div>
                        <div class="sc-card-info-col">
                            <div class="sc-info-heading opacity-${theme === 'dark' ? '6' : '8'}">
                                ${theme === 'dark' ? 'Top Exchange' : 'Volume'}
                            </div>
                            <div class="sc-info-data sc-info-data--topexchange">
                                ${theme === 'dark' ?
            `
                                        <div class="topexchange-logo">
                                            <img src="${item['exchangeLogo']}" alt="" class="should-be-updated">
                                        </div>
                                        <div class="topexchange-name">${item['exchangeName']}</div>
                                    ` : `
                                        ${item.volume}
                                    `}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </a>
    `
    }).join("");

    updateImages();
}

function onShowPreloader() {
    document.querySelector('#screenshot').classList.add('hidden');
    container.innerHTML = `<div class="preloader"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>`
}

// Helpers
async function getCoins(currencies) {
    return await fetch(API_V0 + 'coins?locale=en', {method: 'GET'})
        .then(resp => resp.json())
        .then(resp => {
            return currencies ? resp.data.filter(item => !!(currencies.find(c => c === item.name))) : resp.data;
        })
        .catch((error) => {
            console.log(error)
        })
}

async function getCrowdSales() {
    return await fetch(API_V0 + 'coins/crowdsales', {method: 'GET'})
        .then(resp => resp.json())
        .then(resp => resp.data)
        .catch((error) => {
            console.log(error)
        })
}

async function getCurrencies(currencies, limit, sort) {
    const PARAMS = { api_key: API_KEY, limit: limit ? limit : '0', sort: sort ? sort : 'rank', optionalFields: 'images'}
    return await fetch(API_V1 + 'currencies?' + new URLSearchParams(PARAMS), {method: 'GET'})
        .then(resp => resp.json())
        .then(resp => {
            return currencies ? resp.data.filter(item => !!(currencies.find(c => c === item['name']))) : resp.data;
        })
        .catch((error) => {
            console.log(error)
        })
}

async function getExchanges(coins) {
    let promiseArray = [];
    for (let i = 0; i < coins.length; i++) {
        promiseArray.push(
            fetch(API_V0 + `coins/${coins[i]}/tickers`, {method: 'GET'})
                .then(resp => resp.json())
                .then(resp => {
                    const exchange = resp.data
                        .sort((a, b) => ((a && a['usdVolume']) > (b && b['usdVolume'])) ? 1 : -1)
                        .reverse()[0];
                    return {
                        coin: coins[i],
                        name: exchange['exchangeName'] ? exchange['exchangeName'] : 'N/A',
                        logo: exchange['exchangeIcon'] ? exchange['exchangeIcon'] : '',
                        percent: exchange['changePercent'] ? exchange['changePercent'] : ''
                    }
                })
                .catch((error) => {
                    console.log(error)
                })
        );
    }
    return Promise.all(promiseArray);
}

async function getHistory(coins) {
    const PARAMS = {
        fromTs: (graphPeriod === 'day' ? dayjs().subtract(1, 'day') : dayjs().subtract(7, 'day')).valueOf(),
        toTs: dayjs().valueOf(),
        interval: graphPeriod === 'day' ? '1h' : '1d'
    };

    let promiseArray = [];
    for (let i = 0; i < coins.length; i++) {
        promiseArray.push(
            fetch(API_V0 + `coins/${coins[i]}/chart/history?` + new URLSearchParams(PARAMS), {method: 'GET'})
                .then(resp => resp.json())
                .then(resp => {
                    const data = {
                        name: coins[i],
                        values: []
                    };
                    for(let j = 0; j < resp.data['dates'].length; j++) {
                        data['values'].push({
                            USD: resp.data['USD'][j],
                            marketCap: resp.data['marketCap'][j],
                            volumes: resp.data['volumes'][j]
                        });
                    }
                    return data;
                })
                .catch((error) => {
                    console.log(error)
                })
        )
    }
    return Promise.all(promiseArray);
}

function convertToCurrency(str) {
    return new Intl.NumberFormat( 'en-US', {style: 'currency', currency: 'USD', maximumFractionDigits: 5}).format(str)
}

function convertToAbbreviate(num) {
    return new Intl.NumberFormat( 'en-US', { maximumFractionDigits: 2,notation: "compact" , compactDisplay: "short" }).format(num)
}

function removeZeroFromTheEnd(num) {
    let localNum = num + '';

    for (let i = 0; i < 30; i++) {
        if(localNum[localNum.length - 1] === '0') {
            localNum = localNum.slice(0, -1)
        } else {
            break;
        }
    }

    return localNum;
}

function getFormattedTodayDate(layout) {
    let monthArray = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
    let d = new Date().toISOString();
    let month = '' + (layout ? monthArray[d.slice(5, 7) - 1] : d.slice(5, 7));
    let day = '' + d.slice(8, 10);
    let year = d.slice(0, 4);
    if (month.length < 2) { month = '0' + month }
    if (day.length < 2) { day = '0' + day }
    return layout ? [day, month, year].join(' ') : [year, month, day].join('-');
}

function takePageScreenshot() {
    const page = document.querySelector('#screen');
    const sizes = ['600', '1200', '1800'];
    sizes.forEach((size, index) => {
        page.classList.add('taking-screenshot')
        const options = {
            windowWidth: size,
            allowTaint: true,
            scale: 2,
            imageTimeout: 0
        };
        html2canvas(page, options)
            .then(canvas => {
                page.classList.remove('taking-screenshot');
                const imgName = `Satoshi Club ${getFormattedTodayDate()} x${index+1}.png`
                const downloadLink = document.createElement('a');
                downloadLink.setAttribute('download', imgName);
                canvas.toBlob(function(blob) {
                    const url = URL.createObjectURL(blob);
                    downloadLink.setAttribute('href', url);
                    downloadLink.click();
                    downloadLink.remove();
                });
            });
    })
}

function toDataURL(url, callback) {
    let canvas = document.createElement('CANVAS');
    let img = document.createElement('img');
    img.setAttribute('crossorigin', 'anonymous');
    // img.src = 'https://cors-anywhere.herokuapp.com/' + url;
    img.src = 'https://satoshi-cors.herokuapp.com/' + url;

    img.onload = () => {
        canvas.height = img.height;
        canvas.width = img.width;
        let context = canvas.getContext('2d');
        context.drawImage(img, 0, 0);
        let dataURL = canvas.toDataURL('image/png');
        canvas = null;
        callback(dataURL);
    };
}

function updateImages() {
    const images = document.getElementsByClassName("should-be-updated");
    for (let i = 0; i < images.length; i++) {
        toDataURL(images[i].src, dataUrl => {
            return images[i].src = dataUrl
        })
    }
    document.querySelector('#screenshot').classList.remove('hidden');
}

function generateSVG(values, isATH) {
    const data = values.map((val, index) => {
        return { x: index, y: val[graphType] }
    });

    if(isATH) {
        const maxNumber = Math.max.apply(null, data.map(i => i['y']));
        const maxIndex = data.map(i => i['y']).findIndex(i => i === maxNumber);
        data.splice(maxIndex + 1)
    }

    if(data.length === 1) {
        data[0]['x'] = 1;
        data.unshift({x: 0, y: data[0]['y'] / 100 * 90})
    }

    const SVG = {
        height: 38,
        width: 177,
        label: { x: 5, y: 5 },
        outerX: {
            min: data[0].x,
            max: data[data.length - 1].x
        },
        outerY: {
            min: data.reduce((min, p) => p.y < min ? p.y : min, data[0].y),
            max: data.reduce((max, p) => p.y > max ? p.y : max, data[0].y)
        }
    };

    function getX(x) {
        return SVG.label.y + (x / SVG.outerX.max * (SVG.width - SVG.label.y));
    }

    function getY(y) {
        return ((SVG.height - SVG.label.x) * SVG.outerY.max - (SVG.height - SVG.label.x) * y) / (SVG.outerY.max - SVG.outerY.min);
    }

    let path = "M " + getX(data[0].x) + " " + getY(data[0].y) + " ";
    path += data.map((point) =>  "L " + getX(point.x) + " " + getY(point.y) + " ").join("");

    return `
        <svg width="${SVG.width}" height="${SVG.height}" viewBox="0 0 ${SVG.width} ${SVG.height}" fill="none" xmlns="http://www.w3.org/2000/svg">
            <g filter="url(#filter0_d_199_1901)">
            <path d="${path}" stroke="#5DF4B8"/>
            </g>
            <defs>
            <filter id="filter0_d_199_1901" x="0" y="0.463989" width="176.197" height="37.036" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
            <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
            <feOffset dy="4"/>
            <feGaussianBlur stdDeviation="2"/>
            <feComposite in2="hardAlpha" operator="out"/>
            <feColorMatrix type="matrix" values="0 0 0 0 0.152941 0 0 0 0 0.192157 0 0 0 0 0.282353 0 0 0 0.4 0"/>
            <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_199_1901"/>
            <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_199_1901" result="shape"/>
            </filter>
            </defs>
        </svg>
    `
}

document.querySelector('#date') ? document.querySelector('#date').textContent = getFormattedTodayDate(true) : null; // Display today date


// Sorting logic
let athSort = 'rank';
let topGainersSort = 'percentChange24h'
let marketSort = '';

function onSortATH() {
    filterOptions.sortBy = document.querySelector('#ATHSort').value;
    getATH(filterOptions);
}

function onFilterATH() {
    graphPeriod = 'week';
    filterOptions.period = document.querySelector('#athFi').value;
    getATH(filterOptions);
}

function onSortGainers() {
    filterOptions.sortBy = document.querySelector('#topGainers').value;
    getTopGainers(filterOptions);

    let percentagePeriod = '24H';

    if(filterOptions.sortBy) {
        if(filterOptions.sortBy === 'percentChange24h') { percentagePeriod = '24H'}
        if(filterOptions.sortBy === 'percentChange7d') { percentagePeriod = '7D'}
        if(filterOptions.sortBy === 'percentChange30d') { percentagePeriod = '30D'}
        if(filterOptions.sortBy === 'percentChange3m') { percentagePeriod = '3M'}
    }
    document.querySelector('#period').textContent = percentagePeriod;
}

// Filtration logic
const filterOptions = {
    sortBy: activeFilter === 'ath' ? athSort : (activeFilter === 'gainers' ? topGainersSort : marketSort),
    filters: {
        marketCap: null,
        rank: null,
        volume: null
    }
}
const filterOverlay = document.querySelector('#overlay');
const filterMenu = document.querySelector('#filterMenu');
const filterMarketCap = document.querySelector('#marketCapFilter');
const filterRank = document.querySelector('#rankFilter');
const filterVolume = document.querySelector('#volume24Filter');
const filterReset = document.querySelector('#resetFilters');
const filterToggle = document.querySelector('#filtersToggle');
let isFiltersApplied = false;

function onShowFiltersModal() {
    filterOverlay.style.display = 'block';
    filterMenu.style.display = 'block';
}
function onHideFiltersModal() {
    if(!isFiltersApplied) {
        filterMarketCap.value = '';
        filterRank.value = '';
        filterVolume.value = '';
        filterReset.style.display = 'none';
    }
    filterOverlay.style.display = 'none';
    filterMenu.style.display = 'none';
}
function onFiltersApply() {
    const marketCap = Number(filterMarketCap.value);
    const rank = Number(filterRank.value);
    const volume = Number(filterVolume.value);

    if(marketCap || rank || volume) {
        isFiltersApplied = true;
        filterReset.style.display = 'block';
        filterToggle.classList.add('active');

        filterOptions.filters.marketCap = marketCap
        filterOptions.filters.rank = rank
        filterOptions.filters.volume = volume

        if(activeFilter === 'market') {
            getMarketCap(filterOptions);
        }
        if(activeFilter === 'ath') {
            filterOptions.sortBy = athSort;
            getATH(filterOptions);
        }
        if(activeFilter === 'gainers') {
            filterOptions.sortBy = topGainersSort;
            getTopGainers(filterOptions);
        }
    }

    onHideFiltersModal();
}
function filterInputUpdated() {
    const isInputHasValue = !!(Number(filterMarketCap.value) || Number(filterRank.value) || Number(filterVolume.value));
    filterReset.style.display = isInputHasValue ? 'block' : 'none';
}
function onFiltersReset() {
    filterMarketCap.value = '';
    filterRank.value = '';
    filterVolume.value = '';
    filterReset.style.display = 'none';
    filterToggle.classList.remove('active');
    onFilter();
}

function sortAndFilter(options, items) {
    let filteredResp = items;

    if(options && options.sortBy) {
        filteredResp = filteredResp.filter(i => options.sortBy === 'rank' ? i['athPrice'] : i['athPrice'] && i['athPrice']['marketCap'])
    }
    if(options && options.filters) {
        if(options.filters.marketCap) {
            const minValue = options.filters.marketCap;
            filteredResp = filteredResp.filter(i => i['marketCap'] && i['marketCap'] > minValue)
        }
        if(options.filters.rank) {
            const minValue = options.filters.rank;
            filteredResp = filteredResp.filter(i => i['rank'] && i['rank'] > minValue)
        }
        if(options.filters.volume) {
            const minValue = options.filters.volume;
            filteredResp = filteredResp.filter(i => i['volume24h'] && i['volume24h'] > minValue)
        }
    }

    return filteredResp;
}


