import { prismaClient } from '../database/prismaClient.js';
import { isChainType } from '../utils/typeChecks.js';
export async function getAddress(address, chainType) {
    const parsedChainType = chainType.toLowerCase();
    if (!isChainType(parsedChainType)) {
        throw new Error(`Invalid chain type: ${chainType}`);
    }
    return prismaClient.address.findUnique({
        where: { address_chainType: { address, chainType: parsedChainType } },
    });
}
export async function listAddressesByAccount(accountId) {
    return prismaClient.address.findMany({
        where: { accountId },
    });
}
export async function addAddressToAccount(address, chainType, accountId) {
    const parsedChainType = chainType.toLowerCase();
    if (!isChainType(parsedChainType)) {
        throw new Error(`Invalid chain type: ${chainType}`);
    }
    let returnValue;
    // Check if the account exists
    const existingAccount = await prismaClient.account.findUnique({
        where: { id: accountId },
        include: { addresses: true },
    });
    if (!existingAccount) {
        throw new Error(`Account "${accountId}" not found`);
    }
    // Check if the address already exists
    const existingAddress = await prismaClient.address.findUnique({
        where: { address_chainType: { address, chainType: parsedChainType } },
        include: { account: true },
    });
    // If the address already exists we must move it to the new account and delete the old one
    if (existingAddress) {
        const oldAccount = await prismaClient.account.findUnique({
            where: { id: existingAddress.accountId },
            include: { addresses: true },
        });
        if (!oldAccount) {
            throw new Error(`Old account "${existingAddress.accountId}" not found`);
        }
        // Delete the old account and all its addresses
        await prismaClient.address.deleteMany({
            where: { accountId: oldAccount.id },
        });
        await prismaClient.account.delete({
            where: { id: oldAccount.id },
        });
        // Add the old addresses to the new account
        await prismaClient.address.createMany({
            data: oldAccount.addresses.map((address) => ({
                ...address,
                accountId,
            })),
        });
        returnValue = {
            account: existingAccount,
            addresses: [...oldAccount.addresses, ...existingAccount.addresses],
        };
    }
    else {
        // If the address does not exist we create it
        const newAddress = await prismaClient.address.create({
            data: {
                address,
                chainType: parsedChainType,
                account: { connect: { id: accountId } },
            },
        });
        returnValue = {
            account: existingAccount,
            addresses: [...existingAccount.addresses, newAddress],
        };
    }
    // Track connection
    prismaClient.connection.create({
        data: {
            address: address,
            chain: parsedChainType,
        },
    });
    return returnValue;
}
