import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async function main() {
    console.log("Starting migration: PracticeTest questions -> Test table...\n");

    // Reset testId for practice tests whose linked Test was deleted
    const missingTestsInPractice = await prisma.practiceTest.findMany({
        where: { testId: { not: null } },
        select: { id: true, testId: true }
    });

    for (const item of missingTestsInPractice) {
        const checkTestExists = await prisma.test.findUnique({ where: { id: item.testId! } });
        if (!checkTestExists) {
            await prisma.practiceTest.update({
                where: { id: item.id },
                data: { testId: null }
            });
            console.log(`Reset testId for PracticeTest [${item.id}] — linked Test was deleted.`);
        }
    }

    // Fetch only practice tests that haven't been migrated yet (testId is null)
    const unmigratedPracticeTests = await prisma.practiceTest.findMany({
        where: { testId: null },
        include: {
            questions: {
                select: { id: true, subjectId: true, topic: true }
            }
        }
    });

    let totalMigratedCount = 0;

    for (const currentPracticeTest of unmigratedPracticeTests) {
        // Skip if no questions
        if (currentPracticeTest.questions.length === 0) continue;

        // Find the subjectId from the questions
        const subjectCountMap: Record<string, number> = {};
        const topicCountMap: Record<string, number> = {};

        for (const singleQuestion of currentPracticeTest.questions) {
            if (singleQuestion.subjectId) {
                subjectCountMap[singleQuestion.subjectId] = (subjectCountMap[singleQuestion.subjectId] || 0) + 1;
            }
            if (singleQuestion.topic) {
                topicCountMap[singleQuestion.topic] = (topicCountMap[singleQuestion.topic] || 0) + 1;
            }
        }

        const topSubjectId = Object.entries(subjectCountMap).sort((a, b) => b[1] - a[1])[0]?.[0];
        const topTopic = Object.entries(topicCountMap).sort((a, b) => b[1] - a[1])[0]?.[0] ?? null;

        if (!topSubjectId) {
            console.log(`Skipped "${currentPracticeTest.title}" — questions have no subjectId`);
            continue;
        }

        const uniqueQuestionIds = [...new Set(currentPracticeTest.questions.map((q) => q.id))];

        // Create Test and link questions, then update PracticeTest.testId
        await prisma.$transaction(async (tx) => {
            const newCreatedTest = await tx.test.create({
                data: {
                    title: currentPracticeTest.title || "Untitled",
                    subjectId: topSubjectId,
                    topic: topTopic,
                    language: currentPracticeTest.language || "English",
                    duration: currentPracticeTest.duration ?? 30,
                    marks: Math.round(currentPracticeTest.marks),
                    difficulty: currentPracticeTest.difficulty,
                    publish: currentPracticeTest.publish,
                    institutionId: currentPracticeTest.institutionId,
                    createdById: currentPracticeTest.createdById,
                    testQuestions: {
                        create: uniqueQuestionIds.map((qid) => ({ questionId: qid }))
                    }
                }
            });

            await tx.practiceTest.update({
                where: { id: currentPracticeTest.id },
                data: { testId: newCreatedTest.id }
            });
        });

        totalMigratedCount++;
    }

    console.log(`\nDone! ${totalMigratedCount} practice tests migrated.`);
}

main()
    .catch(console.error)
    .finally(() => prisma.$disconnect());