import * as d3 from 'd3';
import { ChartConfiguration } from "../chart-base/chart-configuration";
import { MultiLineChart } from "../charts/multi-line-chart";

export class MultiLineChartHelper {

    private container: any;
    private containerId: string = 'multi-line-chart-container';
    private svgId: string = 'multi-line-chart';

    private config: ChartConfiguration = new ChartConfiguration(`#${this.svgId}`);
    private chart: MultiLineChart;

    private data: any[] = [];

    private currentIndex: number = 0;
    private pageSize: number = 5;

    private prevBtnId: string = 'multi-line-chart-prev-btn'
    private prevBtn: any;
    private nextBtnId: string = 'multi-line-chart-next-btn'
    private nextBtn: any;
    private rankingTextId: string = 'multi-line-chart-ranking-text';
    private rankingText: any;

    public setData(data: any[]) {
        this.data = data;

        const medalCounts = d3.rollup(
            this.data.filter(d => d.Medal && d.Medal !== ""),
            v => v.length,
            d => d.Country,
            d => d.Year
        );

        let result: any[] = [];

        medalCounts.forEach((yearMap, country) => {
            const entries: Array<{ key: number; value: number }> = [];

            yearMap.forEach((count, year) => {
                entries.push({ key: year, value: count });
            });

            result.push({ id: country, entries });
        });

        result.sort((a, b) => {
            const totalA = d3.sum(a.entries, (d: any) => d.value);
            const totalB = d3.sum(b.entries, (d: any) => d.value);
            return totalB - totalA;
        });

        this.data = result.filter(d => d.entries.length >= 8);
    }

    public appendChart() {
        // Add div container
        this.container = d3.select('#medalDistributionByTimeChart')
            .append('div')
            .attr('class', 'container')
            .attr('style', 'width: fit-content;')
            .attr('id', `${this.containerId}`);

        // Add ranking selection
        this.container
            .append('div')
            .attr('class', 'text-center mt-4 mx-auto navigation-controls')
            .html(`
                    <p style='text-align:center; font-weight:700;'>Select ranking:</p>
                    <button id="${this.prevBtnId}" class="btn btn-outline-secondary">
                        <i class="bi bi-arrow-left"></i>
                    </button>
                    <span id="${this.rankingTextId}"></span>
                    <button id="${this.nextBtnId}" class="btn btn-outline-secondary">
                        <i class="bi bi-arrow-right"></i>
                    </button>
                `);
        this.prevBtn = d3.select(`#${this.prevBtnId}`);
        this.nextBtn = d3.select(`#${this.nextBtnId}`);
        this.rankingText = d3.select(`#${this.rankingTextId}`)

        this.prevBtn.on('click', () => {
            if (this.currentIndex > 0) {
                this.currentIndex -= this.pageSize;
            }
            this.updateChart();
        });

        this.nextBtn.on('click', () => {
            if (this.currentIndex + this.pageSize < this.data.length) {
                this.currentIndex += this.pageSize;
            }
            this.updateChart();
        });

        // add svg for chart
        this.container
            .append('svg')
            .attr('id', `${this.svgId}`);

        // initilize new chart
        this.chart = new MultiLineChart(this.config, 'Year', 'Total Medals', this.data);

        // set tooltip placeholders
        d3.select('#multi-line-chart-tooltip').select('#id-title').text("Country: ");
        d3.select('#multi-line-chart-tooltip').select('#key-title').text("Year: ");
        d3.select('#multi-line-chart-tooltip').select('#value-title').text("Medals: ");

        this.updateChart();
    }

    private updateChart() {
        // Update navigation
        this.prevBtn.attr('disabled', this.currentIndex === 0 ? true : null);
        this.nextBtn.attr('disabled', this.currentIndex >= this.data.length - this.pageSize ? true : null);
        this.rankingText.text(`${this.currentIndex + 1} - ${Math.min(this.currentIndex + this.pageSize, this.data.length)}`)

        this.chart.data = this.data.slice(this.currentIndex, this.currentIndex + this.pageSize);
        this.chart.updateVis();
    }

}