"use server";

import {AppwriteException, Databases, ID} from "node-appwrite";
import {cookies} from "next/headers";
import {SESSION_KEY} from "@/lib/constants";
import {createAdminClient, createSessionClient} from "@/lib/backend/server-appwrite";
import {
    LoginReturnStatus,
    LoginWithEmailProps,
    SignUpReturnStatus,
    SignWithEmailUpProps, UserType
} from "@/lib/backend/appwrite_types";


// logic to register a user/patient with an email
export async function signUpWithEmail(props: SignWithEmailUpProps): SignUpReturnStatus {

    try {
        const fullName = `${props.firstName} ${props.lastName}`
        const email = props.email
        const password = props.password

        const {client, account} = await createAdminClient();
        const databases = new Databases(client);

        const user = await account.create(ID.unique(), email, password, fullName);

        // mark user as a patient in the users-profile table
        await databases.createDocument(
            process.env.NEXT_APPWRITE_DATABASE_ID!,
            process.env.NEXT_APPWRITE_USERS_COLLECTION_ID!,
            user.$id,
            {
                userId: user.$id,
                fullName: fullName,
                userType: UserType.PATIENT
            }
        )

        // creat a patient profile for the user
        await databases.createDocument(
            process.env.NEXT_APPWRITE_DATABASE_ID!,
            process.env.NEXT_APPWRITE_PATIENTS_COLLECTION_ID!,
            user.$id, //ID.unique(),
            {
                userId: user.$id,
                firstName: props.firstName,
                lastName: props.lastName
            }
        );

        const session = await account.createEmailPasswordSession(email, password);

        cookies().set(SESSION_KEY, session.secret, {
            path: "/",
            httpOnly: true,
            sameSite: "strict",
            secure: true,
            maxAge: new Date(session.expire)
        });

        return {
            message: "success",
            code: 200
        };

    } catch (e) {

        if (e instanceof AppwriteException) {
            let _type: string = ""
            if (e.type === "user_already_exists") _type = "email";

            return {
                message: e.message,
                code: e.code,
                error: e.response,
                type: _type
            }
        } else {
            return {
                message: "Server error. Try again later.",
                code: 500,
                error: "Failed to signup",
            }
        }
    }
}


export async function loginWithEmail(props: LoginWithEmailProps): LoginReturnStatus {
    try {
        const email = props.email
        const password = props.password

        const {account} = await createAdminClient();
        const session = await account.createEmailPasswordSession(email, password);

        cookies().set(SESSION_KEY, session.secret, {
            path: "/",
            httpOnly: true,
            sameSite: "strict",
            secure: true,
            maxAge: 259200
        });

        return {
            message: "success", code: 200
        }

    } catch (e) {
        if (e instanceof AppwriteException) {
            return {
                message: e.message,
                code: e.code,
                error: e.response
            }
        } else {
            return {
                message: "Server error. Try again later.",
                code: 500
            }
        }
    }
}


export async function signOut() {
    try {
        const {account} = await createSessionClient();
        cookies().delete(SESSION_KEY);
        await account.deleteSession("current");

        return {
            code: 200
        }
    } catch (e) {
        return {
            error: "failed",
            code: 500
        }
    }
}