import { createTeacherAssignment, generateTeacherQuestions } from "../../dashboard/teacher/dashboard-teacher-assignments.data";
import type { TeacherRedoPlanData, TeacherRedoPlanQuestion } from "./assignment-teacher-review.types";
import type { RedoPlanGenerationResult, RedoPlanGroupedItem } from "./assignment-teacher-redo-plan.types";

const compareGroupedItems = (left: RedoPlanGroupedItem, right: RedoPlanGroupedItem) => {
	if (left.topic !== right.topic) return left.topic.localeCompare(right.topic);
	return left.difficulty.localeCompare(right.difficulty);
};

export const groupRedoPlanQuestions = (questionSet: TeacherRedoPlanQuestion[]): RedoPlanGroupedItem[] => {
	const groupedItems = new Map<
		string,
		{
			topic: string;
			difficulty: "easy" | "medium" | "hard";
			count: number;
			tags: Set<string>;
			reasons: string[];
		}
	>();

	for (const item of questionSet) {
		const key = `${item.topicKey}::${item.difficultyKey}`;
		const existing = groupedItems.get(key);
		if (existing) {
			existing.count += 1;
			item.tags.forEach((tag) => existing.tags.add(tag));
			existing.reasons.push(item.reason);
			continue;
		}

		groupedItems.set(key, {
			topic: item.topicKey,
			difficulty: item.difficultyKey,
			count: 1,
			tags: new Set(item.tags),
			reasons: [item.reason],
		});
	}

	return Array.from(groupedItems.values())
		.map((item) => ({
			topic: item.topic,
			difficulty: item.difficulty,
			count: item.count,
			tags: Array.from(item.tags),
			reasons: item.reasons,
		}))
		.sort(compareGroupedItems);
};

export const buildPlannedAreasMarkdown = (groupedItems: RedoPlanGroupedItem[]) =>
	groupedItems
		.map(
			(item, index) =>
				`- ${index + 1}. ${item.topic.replace(/_/g, " ")} (${item.difficulty}) x${item.count}${item.reasons.length > 0 ? ` — ${item.reasons.join("; ")}` : ""}`,
		)
		.join("\n");

export const createRedoAssignmentForStudent = async (input: {
	data: TeacherRedoPlanData;
	teacherId: number;
}): Promise<RedoPlanGenerationResult> => {
	const groupedItems = groupRedoPlanQuestions(input.data.plan?.questionSet ?? []);
	const plannedAreas = buildPlannedAreasMarkdown(groupedItems);
	const generatedQuestionIds: number[] = [];
	const generatedDescriptions: string[] = [];

	for (const item of groupedItems) {
		const result = await generateTeacherQuestions({
			topic: item.topic,
			difficulty: item.difficulty,
			count: item.count,
			source: "redo_plan_generated",
		});

		generatedQuestionIds.push(...result.generatedQuestionIds);
		generatedDescriptions.push(`${item.topic.replace(/_/g, " ")} ${item.difficulty} ×${result.count} (seed ${result.seed})`);
	}

	const assignment = await createTeacherAssignment({
		teacherId: input.teacherId,
		classroomId: input.data.classroomId,
		title: `${input.data.selectedStudentName} redo • ${input.data.title}`,
		instructions: [
			`Student-specific redo follow-up for ${input.data.selectedStudentName}.`,
			`Source assignment: ${input.data.title}`,
			"",
			`Plan rationale: ${input.data.plan?.rationale ?? ""}`,
			input.data.teacherFeedback ? `Teacher feedback: ${input.data.teacherFeedback}` : "",
			input.data.weaknessSummary.weakTags.length > 0 ? `Weak tags: ${input.data.weaknessSummary.weakTags.join(", ")}` : "",
			"",
			"Planned focus areas:",
			plannedAreas,
		]
			.filter(Boolean)
			.join("\n"),
		dueAt: "",
		selectedQuestionIds: Array.from(new Set(generatedQuestionIds)),
		assignedStudentIds: [input.data.selectedStudentId],
	});

	return {
		assignmentId: assignment.id,
		successMessage: `Created a redo assignment for ${input.data.selectedStudentName}. ${generatedDescriptions.join("; ")}.`,
	};
};
