'use server'

import { cookies } from "next/headers";

import { APIError} from "@/util/api/error"
import { UserAuth, parseBasicAuth, getAssociatedUser } from "@/util/api/user"
import { Attachment, Auth, Bucket, DBState, Post, PostTag, Project, Tag, User, UserPerms,dbSync,sequelize} from "@/models";
import Sequelize, { CreationAttributes, DataTypes } from "@sequelize/core";
import { SqliteColumnsDescription, SqliteDialect, SqliteQueryInterface } from "@sequelize/sqlite3";
import { hashpassword } from "@/util/auth";
import { copyFile, readFileSync } from "fs";
import path from "path";
import { Attributes } from '@sequelize/core';
import { DeepPartial } from "@/util/DeepPartial";
import { UUID } from "crypto";

async function seedUsers(qif: SqliteQueryInterface<SqliteDialect>){
    const fp = path.resolve('./db/seed/users.json');
    const json: {users: CreationAttributes<User>[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());

    const users = json.users.map(async user=>{
        user.password = await hashpassword(user.password);
        return user;
    })
    
    const dbUsers = await User.bulkCreate(await Promise.all(users), {include: User.associations.perms})
}

async function seedPosts(qif: SqliteQueryInterface<SqliteDialect>){
    const fp = path.resolve('./db/seed/posts.json');
    const json: {users: CreationAttributes<User>[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());
    const projects =[
    {
        "name": "Blog",
        "readableIdentifier": "blog",
        "posts": [
            {
                "title": "Test Post",
                "content": "# Hello <ExampleComponent />\nthis is some **test** markdown and we make some edits\n![](/attachment/788dfc19-55ba-482c-8124-277702296dfb/FB_IMG_1716665756868.jpg)",
                "description": "A new post to test the blog system",
                "project_id": 1,
                "user_id": 1,
                "buckets": [
                    {
                        "id": "788dfc19-55ba-482c-8124-277702296dfb",
                        "attachments": [
                            {
                                "filename": "FB_IMG_1716665756868.jpg"
                            }
                        ]
                    }
                ]
            }
        ]
    }]
    projects.map(project=>{
        Project.create({name: project.name, readableIdentifier: project.readableIdentifier});
        project.posts.map(async post=>{
            const pst = await Post.create({title:post.title, content:post.content, description:post.description, project_id: post.project_id, user_id: post.user_id});
            post.buckets.map(async bucket=>{
                pst.createBucket({id:bucket.id as UUID});
                bucket.attachments.map(attachment=>{
                    Attachment.create({bucket_id:bucket.id as UUID, filename: attachment.filename}).then((a)=>{
                        copyFile(
                            path.resolve('.','db','seed','post',a.filename),
                            path.resolve('.','bucket',bucket.id,a.filename),
                            ()=>{

                            }
                        )
                    })
                })
            })
        })
    })
        
    


    const project = await Project.findOne({where: {
        readableIdentifier: 'blog'
    }}).then(e=> e ? e : Project.create({name:'General Blog',readableIdentifier:'blog'}));
}





async function seedDatabase(qif:SqliteQueryInterface<SqliteDialect>){
    await seedUsers(qif);
    await seedPosts(qif)
    
    // await Post.create({
    //     title: 'Test Post',
    //     content: `
    //     # Hello <ExampleComponent />
    //     this is some **test** markdown
    //     `,
    //     project_id: project.id,
    //     user_id: user.id
    // })
    // await Post.create({
    //     title: 'Test Post 2',
    //     content: `
    //     # Hello <ExampleComponent />
    //     this is amother post with some **test** markdown
    //     `,
    //     project_id: project.id,
    //     user_id: user.id
    // })
}

async function trySetup(request:Request){
    await dbSync;

    const queryInterface = sequelize.queryInterface
    

    const version = (await DBState.findAll()).sort((a,b)=> ((a.version > b.version) ? 1 : -1)).map(a=>a.version)[0];

    

    switch(version){
        case 1:
            break;
        default:
            seedDatabase(queryInterface);
            const postsRows:SqliteColumnsDescription = await queryInterface.describeTable(Post.table.tableName).then(t=>t);
            if (!postsRows['project_id']) queryInterface.addColumn('Posts','project_id',{type: DataTypes.INTEGER, acceptsNull:()=>false,defaultValue:1})
            break;
    }

    return new Response(
        JSON.stringify(
        {
            test: await queryInterface.describeTable('Posts').then(t=>t)
        }),
        { 
            status: 200, 
            headers:{
                "Content-Type": "text/JSON" 
            } 
        }
    ); 
}

export async function GET(request:Request){
    try{
        return await trySetup(request);      
    }
    catch(e){
        if (e instanceof APIError){
            return new Response(e.info.responseText,{status:e.info.status});
        }
        else{
            throw e;
        }
    }
}
