import * as d3 from 'd3';
import { ChartConfiguration } from '../chart-base/chart-configuration';
import { StackedBarChart } from '../charts/stacked-bar-chart';

export class StackedBarChartHelper {
    private stacks: any[] = [
        { stackName: 'Bronze', stackColor: '#A77044' },
        { stackName: 'Silver', stackColor: '#A7A7AD' },
        { stackName: 'Gold', stackColor: '#FEE101' },
    ];

    private container: any;
    private containerId: string = 'stacked-bar-chart-container';
    private svgId: string = 'stacked-bar-chart';

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

    private data: any[] = [];

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

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

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

        // Process data (aggregating by country)
        const medalCounts = d3.rollup(this.data,
            (entries) => ({
                Bronze: entries.filter(e => e.Medal === 'Bronze').length,
                Silver: entries.filter(e => e.Medal === 'Silver').length,
                Gold: entries.filter(e => e.Medal === 'Gold').length,
                total: entries.length
            }),
            d => d.Country
        );

        this.data = Array.from(medalCounts, ([country, counts]) => ({
            id: country, // We'll consider country name as id sice its unique
            ...counts
        }))
            .sort((a, b) => b.total - a.total);  // Sort descening
    }

    public appendChart() {
        // Add div container
        this.container = d3.select('#medalDistributionByCountryChart')
            .append('div')
            .attr('class', 'container') // bootstrap
            .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', () => {
            this.currentIndex = Math.max(0, this.currentIndex - this.pageSize);
            this.updateChart();
        });

        this.nextBtn.on('click', () => {
            this.currentIndex = Math.min(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 StackedBarChart(this.config, this.stacks, 'Countries', 'Total Medals', this.data);

        this.updateChart();
    }

    private updateChart() {
        this.prevBtn.attr('disabled', this.currentIndex === 0 ? true : null);  // Disable at start
        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)}`)

        const pageData = this.data.slice(this.currentIndex, this.currentIndex + this.pageSize);
        this.chart.data = pageData;
        this.chart.updateVis();  // Trigger vis update
    }
}