import useDatabase from "~/composables/useDatabase";
import { extname, basename } from 'node:path';
import type { CanvasColor, CanvasContent } from "~/types/canvas";
import type { FileType, ProjectContent } from "#shared/content.util";
import { getID, ID_SIZE } from "#shared/general.util";
import { projectContentTable, projectFilesTable } from "~/db/schema";

const typeMapping: Record<string, FileType> = {
    ".md": "markdown",
    ".canvas": "canvas"
};

export default defineTask({
    meta: {
        name: 'pull',
        description: 'Pull the data from Git',
    },
    async run(event) {
        try {
            //@ts-ignore
            const tree = await $fetch('https://git.peaceultime.com/api/v1/repos/peaceultime/system-aspect/git/trees/master', {
                method: 'get',
                headers: {
                    accept: 'application/json',
                },
                params: {
                    recursive: true,
                    per_page: 1000,
                }
            }) as { tree: any[] } & Record<string, any>;

            const files: ProjectContent[] = await Promise.all(tree.tree.filter((e: any) => !e.path.startsWith(".")).map(async (e, i) => { 
                if(e.type === 'tree')
                {
                    const title = basename(e.path);
                    const order = /(\d+)\. ?(.+)/gsmi.exec(title);
                    const path = (e.path as string).split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/');
                    return { 
                        id: getID(ID_SIZE),
                        path: path.toLowerCase().replaceAll(" ", "-").normalize("NFD").replace(/[\u0300-\u036f]/g, ""), 
                        order: i,
                        title: order && order[2] ? order[2] : title,
                        type: 'folder',
                        content: null,
                        owner: 1,
                        navigable: true,
                        private: e.path.startsWith('98.Privé'),
                        timestamp: new Date(),
                    }
                }

                const extension = extname(e.path);
                const title = basename(e.path, extension);
                const order = /(\d+)\. ?(.+)/gsmi.exec(title);
                const path = (e.path as string).split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/');
                const content = (await $fetch(`https://git.peaceultime.com/api/v1/repos/peaceultime/system-aspect/raw/${encodeURIComponent(e.path)}`));

                return { 
                    id: getID(ID_SIZE),
                    path: (extension === '.md' ? path.replace(extension, '') : path).toLowerCase().replaceAll(" ", "-").normalize("NFD").replace(/[\u0300-\u036f]/g, ""), 
                    order: i,
                    title: order && order[2] ? order[2] : title,
                    type: (typeMapping[extension] ?? 'file'), 
                    content: reshapeContent(content as string, typeMapping[extension] ?? 'File'),
                    owner: 1,
                    navigable: true,
                    private: e.path.startsWith('98.Privé'),
                    timestamp: new Date(),
                }
            }));

            const db = useDatabase();
            db.transaction(tx => {
                db.delete(projectFilesTable).run();
                db.insert(projectFilesTable).values(files.map(e => {const { content, ...rest } = e; return rest; })).run();
                db.delete(projectContentTable).run();
                db.insert(projectContentTable).values(files.map(e => ({ content: e.content ? Buffer.from(e.content as string) : null, id: e.id }))).run();
            });
            
            return { result: true };
        }
        catch(e)
        {
            console.error(e);

            return { result: false, error: e };
        }
    },
})

function reshapeContent(content: string, type: FileType): string | null
{
    switch(type)
    {
        case "markdown":
            return content.replaceAll(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/g, (e: string, a1?: string, a2?: string , a3?: string) => {
                return `[[${a1?.split('/').map(f => { const check = /(\d+)\. ?(.+)/gsmi.exec(f); return check && check[2] ? check[2] : f }).join('/') ?? ''}${a2 ?? ''}${a3 ?? ''}]]`;
            });
        case "file":
            return content;
        case "canvas":
            const data = JSON.parse(content) as CanvasContent;
            data.edges?.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined);
            data.nodes?.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined);
            return JSON.stringify(data);
        default:
        case 'folder': 
            return null;
    }
}
function getColor(color: string): CanvasColor
{
    const colors: Record<string, string> = {
        '1': 'red',
        '2': 'orange',
        '3': 'yellow',
        '4': 'green',
        '5': 'cyan',
        '6': 'purple',
    };
    if(colors.hasOwnProperty(color))
        return { class: colors[color] };
    else
        return { hex: color };
}