import { prismaClient } from '../database/prismaClient.js';
import { isChainType } from '../utils/typeChecks.js';
import { getAccountByAddress } from './accountRepository.js';
export async function getQuest(id) {
    return prismaClient.quest.findUnique({
        where: { id },
    });
}
export async function listQuests() {
    return prismaClient.quest.findMany();
}
export async function getUncompletedQuestsByUserId(userId) {
    const allQuests = await prismaClient.quest.findMany();
    const userQuestLogs = await prismaClient.questLog.findMany({
        where: { userId },
        orderBy: { completedAt: 'desc' },
    });
    // Group quest logs by questId to easily find the most recent completion
    const questLogsMap = new Map();
    for (const log of userQuestLogs) {
        if (!questLogsMap.has(log.questId)) {
            questLogsMap.set(log.questId, log);
        }
        if (questLogsMap.size >= allQuests.length) {
            // We only need one quest log per quest
            break;
        }
    }
    // Filter quests based on completion status
    const now = new Date();
    const uncompletedQuests = allQuests.filter((quest) => {
        const lastCompletion = questLogsMap.get(quest.id);
        // If no completion record exists, the quest is uncompleted
        if (!lastCompletion) {
            return true;
        }
        switch (quest.type) {
            case 'ONE_TIME': {
                return false;
            }
            case 'DAY': {
                const lastCompletionDate = new Date(lastCompletion.completedAt);
                const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
                const completionDate = new Date(lastCompletionDate.getFullYear(), lastCompletionDate.getMonth(), lastCompletionDate.getDate());
                return completionDate < today;
            }
            case 'WEEK': {
                const oneWeekAgo = new Date(now);
                oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
                return lastCompletion.completedAt < oneWeekAgo;
            }
            case 'MONTH': {
                const oneMonthAgo = new Date(now);
                oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
                return lastCompletion.completedAt < oneMonthAgo;
            }
            default: {
                // Quest type defaults to UNLIMITED
                return true;
            }
        }
    });
    return uncompletedQuests;
}
export async function getUncompletedQuestsByAddress(address, chainType) {
    const parsedChainType = chainType.toLowerCase();
    if (!isChainType(parsedChainType)) {
        throw new Error(`Invalid chain type: ${chainType}`);
    }
    const user = await getAccountByAddress(address, parsedChainType);
    if (!user) {
        // No user, no quests
        return [];
    }
    return getUncompletedQuestsByUserId(user.id);
}
