// Path: Frontend/src/components/assignment/student/assignment-review.data.ts

import { apiFetchJson } from "../../../lib/api";
import type { ApiAssignment, ApiAssignmentStudentQuestionDetail, ApiClassroom, ApiListResponse, ApiUser } from "../../../lib/api-types";
import { getAssignmentWorkHref } from "../../../lib/routes";
import type { AssignmentPageData } from "../shared/assignment-types";

const formatDateLabel = (value: string | null) => {
	if (!value) return "No due date";

	return new Intl.DateTimeFormat("en-GB", {
		weekday: "short",
		month: "short",
		day: "numeric",
	}).format(new Date(value));
};

const extractTopic = (assignment: ApiAssignment, questions: ApiAssignmentStudentQuestionDetail[]) => {
	const fromInstructions = assignment.instructions?.match(/^Topic:\s*(.+)$/i)?.[1]?.trim();
	if (fromInstructions) return fromInstructions;

	return questions[0]?.subject ?? "Assignment";
};

const deriveStudentStatus = (questions: ApiAssignmentStudentQuestionDetail[], assignmentStatus: ApiAssignment["status"]) => {
	const total = questions.length;
	const answered = questions.filter((question) => question.answer_id).length;
	const reviewed = questions.filter((question) => question.answer_status === "reviewed").length;

	if (answered === 0) return "NOT_STARTED" as const;
	if (reviewed === total || assignmentStatus === "closed") return "SUBMITTED" as const;
	return "IN_PROGRESS" as const;
};

const deriveStatusLabel = (status: AssignmentPageData["status"]) => {
	switch (status) {
		case "SUBMITTED":
			return "Reviewed";
		case "IN_PROGRESS":
			return "In progress";
		default:
			return "Not started";
	}
};

const deriveHeadline = (status: AssignmentPageData["status"], topic: string) => {
	switch (status) {
		case "SUBMITTED":
			return `Review how you did in ${topic}`;
		case "IN_PROGRESS":
			return "Keep going — you already have momentum here";
		default:
			return "Start this assignment with a steady first pass";
	}
};

const deriveDescription = (status: AssignmentPageData["status"], answered: number, reviewed: number, total: number, topic: string) => {
	switch (status) {
		case "SUBMITTED":
			return `${reviewed} of ${total} questions have teacher-reviewed answers. Use this review view to see what landed well and what still needs another pass in ${topic}.`;
		case "IN_PROGRESS":
			return `You have touched ${answered} of ${total} questions so far. Finish the remaining questions while ${topic.toLowerCase()} still feels familiar.`;
		default:
			return `This assignment has ${total} questions. Start with a calm first pass, then come back here for one shared review summary across the assignment.`;
	}
};

const derivePrimaryAction = (status: AssignmentPageData["status"]) => {
	switch (status) {
		case "SUBMITTED":
			return "Open workspace";
		case "IN_PROGRESS":
			return "Continue assignment";
		default:
			return "Start assignment";
	}
};

const mapQuestionStatus = (question: ApiAssignmentStudentQuestionDetail) => {
	if (question.is_correct === true) {
		return {
			statusLabel: "Correct",
			statusTone: "success" as const,
		};
	}

	if (question.answer_status === "reviewed") {
		return {
			statusLabel: "Reviewed",
			statusTone: "success" as const,
		};
	}

	if (question.answer_status === "submitted") {
		return {
			statusLabel: "Submitted",
			statusTone: "warning" as const,
		};
	}

	if (question.answer_status === "in_progress") {
		return {
			statusLabel: "In progress",
			statusTone: "warning" as const,
		};
	}

	return {
		statusLabel: "Not started",
		statusTone: "muted" as const,
	};
};

export const getAssignmentReviewPageData = async (assignmentId: number, studentId: number): Promise<AssignmentPageData | null> => {
	if (!Number.isFinite(assignmentId) || assignmentId <= 0) return null;

	try {
		const assignment = await apiFetchJson<ApiAssignment>(`/api/assignments/${assignmentId}`);

		const [student, teacher, classrooms, questionDetails] = await Promise.all([
			apiFetchJson<ApiUser>(`/api/users/${studentId}`),
			apiFetchJson<ApiUser>(`/api/users/${assignment.teacher_id}`),
			apiFetchJson<ApiListResponse<ApiClassroom>>(`/api/teachers/${assignment.teacher_id}/classrooms`),
			apiFetchJson<ApiListResponse<ApiAssignmentStudentQuestionDetail>>(`/api/assignments/${assignmentId}/students/${studentId}/questions`),
		]);

		const classroom = classrooms.data.find((entry) => entry.id === assignment.classroom_id);
		const questions = questionDetails.data;
		const topic = extractTopic(assignment, questions);
		const answeredCount = questions.filter((question) => question.answer_id).length;
		const reviewedCount = questions.filter((question) => question.answer_status === "reviewed").length;
		const assignmentAiFeedback = questions[0]?.assignment_ai_feedback?.trim() || "";
		const assignmentTeacherFeedback = questions[0]?.assignment_teacher_feedback?.trim() || "";
		const status = deriveStudentStatus(questions, assignment.status);
		const statusLabel = deriveStatusLabel(status);

		return {
			id: assignment.id,
			title: assignment.title,
			topic,
			status,
			statusLabel,
			dueLabel: formatDateLabel(assignment.due_at),
			studentName: student.full_name,
			classroomName: classroom?.name ?? "Classroom",
			tutorName: teacher.full_name,
			headline: deriveHeadline(status, topic),
			description: deriveDescription(status, answeredCount, reviewedCount, questions.length, topic),
			primaryAction: derivePrimaryAction(status),
			primaryHref: getAssignmentWorkHref(assignment.id),
			stats: [
				{ label: "Status", value: statusLabel },
				{ label: "Due", value: formatDateLabel(assignment.due_at) },
				{ label: "Questions", value: `${questions.length}` },
				{ label: status === "SUBMITTED" ? "Reviewed" : "Answered", value: `${status === "SUBMITTED" ? reviewedCount : answeredCount}/${questions.length}` },
			],
			coachCard: {
				title: "Review notes",
				description: `Use this review view to compare your latest answers with the shared AI and teacher feedback for ${topic.toLowerCase()}.`,
				items: [`${answeredCount} questions attempted`, `${reviewedCount} questions reviewed`, `${Math.max(questions.length - answeredCount, 0)} questions still untouched`],
			},
			assignmentAiFeedback: assignmentAiFeedback || undefined,
			assignmentTeacherFeedback: assignmentTeacherFeedback || undefined,
			questions: questions.map((question) => {
				const questionStatus = mapQuestionStatus(question);

				return {
					id: question.question_id,
					order: question.position,
					prompt: question.prompt,
					topic: question.subject,
					subTopic: null,
					difficulty: "Backend",
					marks: null,
					statusLabel: questionStatus.statusLabel,
					statusTone: questionStatus.statusTone,
					responseLabel: question.answer_id ? "Latest answer" : "Status",
					responseValue: question.answer_text?.trim() || "No attempt yet",
					feedback: "",
					workingSteps: question.working_steps?.trim() || "",
					solveModeLabel:
						question.solve_mode === "step_by_step"
							? "Step by step"
							: question.solve_mode === "solve_together"
								? "Solve together"
								: question.solve_mode === "handwritten"
									? "Handwritten"
									: question.solve_mode === "just_answer"
										? "Just answer"
										: undefined,
					showAnswerKey: Boolean(question.correct_answer && question.answer_id),
					correctAnswer: question.correct_answer?.trim() || null,
					isCorrect: typeof question.is_correct === "boolean" ? question.is_correct : null,
				};
			}),
		};
	} catch (error) {
		if (error instanceof Error && error.message === "not_found") {
			return null;
		}

		throw error;
	}
};
