'use server'


/** =================================================================================================
 *
 *  @author Andreas Schaafsma
 *  @description Handle API requests that fetch or permute User data
 * 
 * ================================================================================================= */

import { APIError } from "@/util/api/error";
import { UserAuth } from "@/util/api/user";
import { Attachment, Auth, Bucket, DBState, Post, PostTag, Project, Tag, User, UserPerms, addUserScopes, dbSync,sequelize} from "@/models";
import { hashpassword } from "@/util/auth";


/** Attempt to register a new User */
async function attemptRegister(request:Request){    
    //** Sync db
    await dbSync;
    
    // Get request body
    const requestBody:Partial<UserAuth> = await request.json();
    // Handle edgecases
    if(!requestBody) throw new APIError({status:500,responseText: "Request Body is Empty"})
    if(!requestBody.username) throw new APIError({status:500,responseText: "No username specified"})
    if(!requestBody.password) throw new APIError({status:500,responseText: "No password specified"})
    // Try to get user from database
    const dbUser = await User.findOne({where:{username:requestBody.username}});
    // If it exists we throw an error
    if(dbUser) throw new APIError({status:500,responseText: "Username unavailable, try another"});
    // Hash the password and create a new user in the database
    const user = await User.create({
        username: requestBody.username,
        password: await hashpassword(requestBody.password),
        perms:{
            isAdmin: false
        }
    },
    {
        include: [{
            association: User.associations.perms
        }]
    }).then(user=>user.reload());
    // Return the HTTP response
    return new Response(
        JSON.stringify(
        {
            user: user
        }),
        { 
            status: 200, 
            headers:{
                "Content-Type": "text/JSON" 
            } 
        }
    ); 
}

export async function POST(request:Request){
    try{
        return await attemptRegister(request);      
    }
    catch(e){
        if (e instanceof APIError){
            return new Response(e.info.responseText,{status:e.info.status});
            console.log("responded")
        }
        else{
            throw e;
        }
    }
}

async function attemptGetUsers(request:Request){
    await dbSync;
    // Get users with scopes applied
    const users = await User.withScope(['defaultScope','withPerms','withAuthtokens']).findAll();
    return new Response(
        JSON.stringify(
        {
            users: users
        }),
        { 
            status: 200, 
            headers:{
                "Content-Type": "text/JSON" 
            } 
        }
    ); 
}

export async function GET(request:Request): Promise<Response>{
    try{
        return await attemptGetUsers(request);      
    }
    catch(e){
        if (e instanceof APIError){
            return new Response(e.info.responseText,{status:e.info.status});
            console.log("responded")
        }
        else{
            throw e;
        }
    }
}
