import type { HttpContext } from '@adonisjs/core/http';
import db from '@adonisjs/lucid/services/db';
import { StatusCodes } from 'http-status-codes';

export default class HomeController {
    public async findDocumentsPerYear({ response, params }: HttpContext) {
        const year = params.year;
        const from = parseInt(year);
        const serverState = 'published';
        try {
            // Database.raw(`date_part('year', server_date_published) as pub_year`)
            // const datasets = await Dataset.query()
            //     .select(['id', 'publish_id', 'server_date_published', ])
            //     .where('server_state', serverState)
            //     .andWhereRaw(`date_part('year', server_date_published) = ?`, [from])
            //     .preload('titles')
            //     .preload('authors')
            //     .orderBy('server_date_published');

            const datasets = await db.from('documents as doc')
                .select(['publish_id', 'server_date_published', db.raw(`date_part('year', server_date_published) as pub_year`)])
                .where('server_state', serverState)
                .innerJoin('link_documents_persons as ba', 'doc.id', 'ba.document_id')
                .andWhereRaw(`date_part('year', server_date_published) = ?`, [from])
                .orderBy('server_date_published');

            return response.json(datasets);
        } catch (error) {
            return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
                message: error.message || 'Some error occurred while retrieving datasets.',
            });
        }
    }

    public async findYears({ response }: HttpContext) {
        const serverState = 'published';
        // Use raw SQL queries to select all cars which belongs to the user
        try {
            const datasets = await db.rawQuery(
                'SELECT distinct EXTRACT(YEAR FROM server_date_published) as published_date FROM gba.documents WHERE server_state = ?',
                [serverState],
            );

            // Pluck the ids of the cars
            const years = datasets.rows.map((dataset: any) => dataset.published_date);
            // check if the cars is returned
            // if (years.length > 0) {
            return response.status(StatusCodes.OK).json(years);
            // }
        } catch (error) {
            return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
                message: 'An error occurred while retrieving the list of publication years from the Tethys repository.',
            });
        }
    }

    public async findPublicationsPerMonth({ response }: HttpContext) {
        const serverState = 'published';
        // const year = params.year;
        // const from = parseInt(year);
        try {

            // const datasets = await Database.from('documents as doc')
            //     .select([Database.raw(`date_part('month', server_date_published) as pub_month`), Database.raw('COUNT(*) as count')])
            //     .where('server_state', serverState)
            //     .innerJoin('link_documents_persons as ba', 'doc.id', 'ba.document_id')
            //     .andWhereRaw(`date_part('year', server_date_published) = ?`, [from])
            //     .groupBy('pub_month');
            //     // .orderBy('server_date_published');

            const years = [2021, 2022, 2023]; // Add the second year

            const result = await db.from('documents as doc')
                .select([
                    db.raw(`date_part('year', server_date_published) as pub_year`),
                    db.raw(`date_part('month', server_date_published) as pub_month`),
                    db.raw('COUNT(*) as count'),
                ])
                .where('server_state', serverState)
                // .innerJoin('link_documents_persons as ba', 'doc.id', 'ba.document_id')
                // .whereIn('pub_year', years) // Filter by both years
                .whereRaw(`date_part('year', server_date_published) IN (${years.join(',')})`) // Filter by both years
                .groupBy('pub_year', 'pub_month')
                .orderBy('pub_year', 'asc')
                .orderBy('pub_month', 'asc');
                            
            const labels = Array.from({ length: 12 }, (_, i) => i + 1); // Assuming 12 months

            const inputDatasets: Map<string, ChartDataset> = result.reduce((acc, item) => {
                const { pub_year, pub_month, count } = item;

                if (!acc[pub_year]) {
                    acc[pub_year] = {
                        data: Array.from({ length: 12 }).fill(0),
                        label: pub_year.toString(),
                        borderColor: this.getRandomHexColor, // pub_year === 2022 ? '#3e95cd' : '#8e5ea2',
                        fill: false,
                    };
                }

                acc[pub_year].data[pub_month - 1] = parseInt(count);

                return acc ;
            }, {});

            const outputDatasets = Object.entries(inputDatasets).map(([year, data]) => ({
                data: data.data,
                label: year,
                borderColor: data.borderColor,
                fill: data.fill
              }));

            const data = {
                labels: labels,
                datasets: outputDatasets,
            };

            return response.json(data);
        } catch (error) {
            return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
                message: error.message || 'Some error occurred while retrieving datasets.',
            });
        }
    }

    private getRandomHexColor() {
        const letters = '0123456789ABCDEF';
        let color = '#';
    
        for (let i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
    
        return color;
    }
}
interface ChartDataset {
    data: Array<number>;
    label: string;
    borderColor: string;
    fill: boolean;

}
