
import pdfkit from 'pdfkit';

import { PassThrough } from 'node:stream';
import fs from 'fs';

import { ProjectModel, TProject } from "@schema/ProjectSchema";
import { UserSettingsModel } from "@schema/UserSettings";
import { VisitModel } from '@schema/metrics/VisitSchema';
import { EventModel } from '@schema/metrics/EventSchema';


type PDF_Data = {
    pageVisits: number, customEvents: number,
    visitsDay: number, eventsDay: number, visitsSessions: number,
    visitsSessionsDay: number
}

function formatNumberK(value: string | number, decimals: number = 1) {
    const num = parseInt(value.toString());

    if (num > 1_000_000) return (num / 1_000_000).toFixed(decimals) + ' M';
    if (num > 1_000) return (num / 1_000).toFixed(decimals) + ' K';
    return num.toFixed();

}

function createPdf(projectName: string, data: PDF_Data) {
    const pdf = new pdfkit({
        size: 'A4',
        margins: { top: 50, bottom: 50, left: 50, right: 50 },
    });

    pdf.pipe(fs.createWriteStream('out.pdf'));

    // Set up fonts and colors
    pdf
        .fillColor('#ffffff')
        .rect(0, 0, pdf.page.width, pdf.page.height)
        .fill('#000000');

    // Title
    pdf
        .font('pdf_fonts/Poppins-Bold.ttf')
        .fontSize(26)
        .fillColor('#ffffff')
        .text(`Report of: ${projectName}`, 50, 50);

    // Section 1
    pdf
        .font('pdf_fonts/Poppins-SemiBold.ttf')
        .fontSize(20)
        .fillColor('#ffffff')
        .text('-> This month has seen a lot of visits!', 50, 120);

    pdf
        .image('pdf_images/d.png', 50, 160, { width: 300 })
        .font('pdf_fonts/Poppins-Bold.ttf')
        .fontSize(28)
        .fillColor('#ffffff')
        .text(`${formatNumberK(data.pageVisits, 2)}`, 400, 180)
        .text('WOW!', 400, 210);

    // Section 2
    pdf
        .font('pdf_fonts/Poppins-SemiBold.ttf')
        .fontSize(20)
        .fillColor('#ffffff')
        .text('-> There are also many recorded events!', 50, 350);

    pdf
        .image('pdf_images/c.png', 50, 390, { width: 300 })
        .font('pdf_fonts/Poppins-Bold.ttf')
        .fontSize(28)
        .fillColor('#ffffff')
        .text(`${formatNumberK(data.customEvents, 2)}`, 400, 420)
        .text('Let\'s go!', 400, 450);

    // Final section
    pdf
        .font('pdf_fonts/Poppins-SemiBold.ttf')
        .fontSize(20)
        .fillColor('#ffffff')
        .text('This report is not final, it only serves to demonstrate the potential of this tool. LitLyx will improve soon! Stay tuned!', 50, 600);

    pdf
        .font('pdf_fonts/Poppins-Regular.ttf')
        .fontSize(14)
        .fillColor('#ffffff')
        .text('Generated on litlyx.com', 50, 760);
    pdf
        .image('pdf_images/logo.png', 460, 700, { width: 100 }) // replace with the correct path to your Unsplash image

    // End PDF creation and save to file
    pdf.end();
    return pdf;
}






export default defineEventHandler(async event => {

    const userData = getRequestUser(event);
    if (!userData?.logged) return setResponseStatus(event, 400, 'NotLogged');

    const currentActiveProject = await UserSettingsModel.findOne({ user_id: userData.id });
    if (!currentActiveProject) return setResponseStatus(event, 400, 'You need to select a project');

    const project_id = currentActiveProject.active_project_id;

    const project = await ProjectModel.findById(project_id);
    if (!project) return setResponseStatus(event, 400, 'Project not found');




    const eventsCount = await EventModel.countDocuments({ project_id: project._id });
    const visitsCount = await VisitModel.countDocuments({ project_id: project._id });

    const sessionsVisitsCount: any[] = await VisitModel.aggregate([
        { $match: { project_id: project._id } },
        { $group: { _id: "$session" } },
        { $count: "count" }
    ]);

    const firstEventDate = await EventModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } });
    const firstViewDate = await VisitModel.findOne({ project_id: project._id }, { created_at: 1 }, { sort: { created_at: 1 } });

    if (!firstEventDate || !firstViewDate) {
        return setResponseStatus(event, 400, 'Not enough data to generate report');
    }

    const avgEventsDay = () => {
        const days = (Date.now() - (firstEventDate?.created_at.getTime() || 0)) / 1000 / 60 / 60 / 24;
        const avg = eventsCount / Math.max(days, 1);
        return avg;
    };

    const avgVisitDay = () => {
        const days = (Date.now() - (firstViewDate?.created_at.getTime() || 0)) / 1000 / 60 / 60 / 24;
        const avg = visitsCount / Math.max(days, 1);
        return avg;
    };

    const avgVisitsSessionsDay = () => {
        const days = (Date.now() - (firstViewDate?.created_at.getTime() || 0)) / 1000 / 60 / 60 / 24;
        const avg = sessionsVisitsCount[0].count / Math.max(days, 1);
        return avg;
    };

    const pdf = createPdf(
        project.name, {
        customEvents: eventsCount,
        eventsDay: avgEventsDay(),
        pageVisits: visitsCount,
        visitsDay: avgVisitDay(),
        visitsSessions: sessionsVisitsCount[0].count,
        visitsSessionsDay: avgVisitsSessionsDay()
    });

    const passThrough = new PassThrough();
    pdf.pipe(passThrough);
    await sendStream(event, passThrough);
});