// Path: Frontend/src/components/dashboard/dashboard-teacher-home.data.ts

import {
	getAssignmentReviewHref,
	getDashboardAssignmentsHref,
	getDashboardClassroomsHref,
	getDashboardHomeHref,
	getDashboardMessagesHref,
	getDashboardSettingsHref,
} from "../../../lib/routes";
import { apiFetchJson } from "../../../lib/api";
import { teacherDashboardLabels } from "../../../content/dashboard-labels";
import type {
	ApiAssignment,
	ApiClassroom,
	ApiListResponse,
	ApiReviewQueueItem,
	ApiReviewSummary,
	ApiStudent,
} from "../../../lib/api-types";
import type { DashboardHomeShellData, TopbarMessageItem } from "../shared/dashboard-types";

type TeacherOverviewStat = {
	label: string;
	value: string;
	note: string;
};

type TeacherOverviewAction = {
	label: string;
	description: string;
	href: string;
	tone: "primary" | "secondary";
};

type TeacherReviewQueueItem = {
	studentName: string;
	assignmentTitle: string;
	classroomName: string;
	progressLabel: string;
	statusLabel: string;
	timestampLabel: string;
	href: string;
	initials: string;
};

type TeacherAssignmentCard = {
	id: number;
	title: string;
	classroomName: string;
	statusLabel: string;
	dueLabel: string;
	queueLabel: string;
	completionLabel: string;
	href: string;
};

type TeacherClassroomCard = {
	id: number;
	name: string;
	codeLabel: string;
	studentCountLabel: string;
	assignmentCountLabel: string;
	reviewLabel: string;
	liveLabel: string;
	note: string;
};

export type TeacherDashboardHomeData = {
	shell: DashboardHomeShellData;
	overview: {
		eyebrow: string;
		title: string;
		description: string;
		stats: TeacherOverviewStat[];
		actions: TeacherOverviewAction[];
	};
	reviewQueue: {
		title: string;
		description: string;
		items: TeacherReviewQueueItem[];
	};
	assignmentFocus: {
		title: string;
		description: string;
		items: TeacherAssignmentCard[];
	};
	classrooms: {
		title: string;
		description: string;
		items: TeacherClassroomCard[];
	};
};

const initialsFor = (name: string) =>
	name
		.split(/\s+/)
		.filter(Boolean)
		.slice(0, 2)
		.map((part) => part[0])
		.join("")
		.toUpperCase();

const compact = (value: number) => new Intl.NumberFormat("en-GB", { notation: "compact", maximumFractionDigits: 1 }).format(value);

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

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

const formatRelativeTime = (value: string | null | undefined) => {
	if (!value) return "No recent updates";

	const deltaMs = Date.now() - new Date(value).getTime();
	const deltaMinutes = Math.max(0, Math.round(deltaMs / (1000 * 60)));
	if (deltaMinutes < 60) return `${deltaMinutes || 1}m ago`;
	const deltaHours = Math.round(deltaMinutes / 60);
	if (deltaHours < 24) return `${deltaHours}h ago`;
	const deltaDays = Math.round(deltaHours / 24);
	if (deltaDays < 7) return `${deltaDays}d ago`;
	return formatShortDate(value);
};

const statusLabelForAssignment = (assignment: ApiAssignment, summary?: ApiReviewSummary) => {
	if (assignment.status === "draft") return "Draft";
	if (assignment.status === "closed") return "Closed";
	if ((summary?.submitted ?? 0) > 0) return "Needs review";
	if ((summary?.in_progress ?? 0) > 0) return "In progress";
	return "Assigned";
};

const statusPriorityForAssignment = (assignment: ApiAssignment, summary?: ApiReviewSummary) => {
	if ((summary?.submitted ?? 0) > 0) return 0;
	if ((summary?.in_progress ?? 0) > 0) return 1;
	if (assignment.status === "assigned") return 2;
	if (assignment.status === "draft") return 3;
	return 4;
};

const sortByDueSoonest = (left: ApiAssignment, right: ApiAssignment) => {
	const leftTime = left.due_at ? new Date(left.due_at).getTime() : Number.POSITIVE_INFINITY;
	const rightTime = right.due_at ? new Date(right.due_at).getTime() : Number.POSITIVE_INFINITY;
	return leftTime - rightTime;
};

export const getTeacherDashboardHomeData = async (teacherId: number): Promise<TeacherDashboardHomeData> => {
	const [assignmentResponse, classroomResponse] = await Promise.all([
		apiFetchJson<ApiListResponse<ApiAssignment>>(`/api/teachers/${teacherId}/assignments`),
		apiFetchJson<ApiListResponse<ApiClassroom>>(`/api/teachers/${teacherId}/classrooms`),
	]);

	const assignments = assignmentResponse.data;
	const classrooms = classroomResponse.data;

	const [studentsByClassroomEntries, reviewSummaryEntries, reviewQueueEntries] = await Promise.all([
		Promise.all(classrooms.map(async (classroom) => [classroom.id, (await apiFetchJson<ApiListResponse<ApiStudent>>(`/api/classrooms/${classroom.id}/students`)).data] as const)),
		Promise.all(assignments.map(async (assignment) => [assignment.id, await apiFetchJson<ApiReviewSummary>(`/api/assignments/${assignment.id}/review-summary`)] as const)),
		Promise.all(assignments.map(async (assignment) => [assignment.id, (await apiFetchJson<ApiListResponse<ApiReviewQueueItem>>(`/api/assignments/${assignment.id}/review?status=submitted`)).data] as const)),
	]);

	const studentsByClassroom = new Map(studentsByClassroomEntries);
	const reviewSummaryByAssignment = new Map(reviewSummaryEntries);
	const reviewQueueByAssignment = new Map(reviewQueueEntries);
	const classroomById = new Map(classrooms.map((classroom) => [classroom.id, classroom]));

	const uniqueStudentIds = new Set<number>();
	for (const students of studentsByClassroom.values()) {
		for (const student of students) uniqueStudentIds.add(student.id);
	}

	const liveAssignments = assignments.filter((assignment) => assignment.status === "assigned");
	const activeAssignments = assignments.filter((assignment) => assignment.status !== "closed");
	const draftAssignments = assignments.filter((assignment) => assignment.status === "draft");
	const needsReviewCount = assignments.reduce((total, assignment) => total + (reviewSummaryByAssignment.get(assignment.id)?.submitted ?? 0), 0);
	const reviewedCount = assignments.reduce((total, assignment) => total + (reviewSummaryByAssignment.get(assignment.id)?.reviewed ?? 0), 0);
	const assignedCount = assignments.reduce((total, assignment) => total + (reviewSummaryByAssignment.get(assignment.id)?.total_assigned ?? 0), 0);
	const reviewCoverage = assignedCount > 0 ? Math.round((reviewedCount / assignedCount) * 100) : 0;

	const nextDueAssignment = liveAssignments
		.slice()
		.sort(sortByDueSoonest)
		.find((assignment) => assignment.due_at);

	const reviewQueueItems = assignments
		.flatMap((assignment) => {
			const classroom = classroomById.get(assignment.classroom_id);
			return (reviewQueueByAssignment.get(assignment.id) ?? []).map((item) => ({
				studentName: item.student_name,
				assignmentTitle: assignment.title,
				classroomName: classroom?.name ?? "Classroom",
				progressLabel: `${item.reviewed_questions}/${item.total_questions} reviewed`,
				statusLabel: item.review_status.replaceAll("_", " "),
				timestampLabel: formatRelativeTime(item.latest_submitted_at ?? item.latest_reviewed_at),
				sortTimestamp: item.latest_submitted_at ?? item.latest_reviewed_at ?? "",
				href: getAssignmentReviewHref("teacher", assignment.id),
				initials: initialsFor(item.student_name),
			}));
		})
		.sort((left, right) => {
			const leftWeight = left.sortTimestamp ? new Date(left.sortTimestamp).getTime() : 0;
			const rightWeight = right.sortTimestamp ? new Date(right.sortTimestamp).getTime() : 0;
			return rightWeight - leftWeight;
		})
		.map(({ sortTimestamp: _sortTimestamp, ...item }) => item)
		.slice(0, 6);

	const assignmentHealthItems = (activeAssignments.length > 0 ? activeAssignments : assignments)
		.slice()
		.sort((left, right) => {
			const leftSummary = reviewSummaryByAssignment.get(left.id);
			const rightSummary = reviewSummaryByAssignment.get(right.id);
			return statusPriorityForAssignment(left, leftSummary) - statusPriorityForAssignment(right, rightSummary) || sortByDueSoonest(left, right);
		})
		.slice(0, 6)
		.map((assignment) => {
			const summary = reviewSummaryByAssignment.get(assignment.id);
			const classroom = classroomById.get(assignment.classroom_id);
			const totalAssigned = summary?.total_assigned ?? 0;
			const reviewed = summary?.reviewed ?? 0;
			const submitted = summary?.submitted ?? 0;
			const inProgress = summary?.in_progress ?? 0;
			const completion = totalAssigned > 0 ? Math.round((reviewed / totalAssigned) * 100) : 0;

			return {
				id: assignment.id,
				title: assignment.title,
				classroomName: classroom?.name ?? "Classroom",
				statusLabel: statusLabelForAssignment(assignment, summary),
				dueLabel: assignment.status === "draft" ? "Publish when ready" : formatShortDate(assignment.due_at),
				queueLabel:
					assignment.status === "draft"
						? "Not published yet"
						: submitted > 0
							? `${submitted} submission${submitted === 1 ? "" : "s"} waiting`
							: `${inProgress} in progress`,
				completionLabel: totalAssigned > 0 ? `${completion}% reviewed` : "No student attempts yet",
				href: submitted > 0 ? getAssignmentReviewHref("teacher", assignment.id) : getDashboardAssignmentsHref("teacher"),
			};
		});

	const classroomCards = classrooms.map((classroom) => {
		const students = studentsByClassroom.get(classroom.id) ?? [];
		const classroomAssignments = assignments.filter((assignment) => assignment.classroom_id === classroom.id);
		const liveCount = classroomAssignments.filter((assignment) => assignment.status === "assigned").length;
		const classroomReviewCount = classroomAssignments.reduce((total, assignment) => total + (reviewSummaryByAssignment.get(assignment.id)?.submitted ?? 0), 0);
		const nextDue = classroomAssignments
			.filter((assignment) => assignment.status === "assigned")
			.slice()
			.sort(sortByDueSoonest)
			.find((assignment) => assignment.due_at);

		return {
			id: classroom.id,
			name: classroom.name,
			codeLabel: classroom.code ? `Invite code ${classroom.code}` : "Invite code not set",
			studentCountLabel: `${students.length} student${students.length === 1 ? "" : "s"}`,
			assignmentCountLabel: `${classroomAssignments.length} assignment${classroomAssignments.length === 1 ? "" : "s"}`,
			reviewLabel: classroomReviewCount > 0 ? `${classroomReviewCount} waiting for review` : "Nothing waiting for review",
			liveLabel: `${liveCount} live assignment${liveCount === 1 ? "" : "s"}`,
			note: nextDue ? `${teacherDashboardLabels.common.nextDue} ${formatShortDate(nextDue.due_at)}` : "No due dates scheduled yet",
		};
	});

	const shell: DashboardHomeShellData = {
		classroomSummary: {
			name: classrooms.length > 0 ? `${classrooms.length} classroom${classrooms.length === 1 ? "" : "s"}` : "Teacher workspace",
			tutorName: "Teacher workspace",
			tutorRole: "Teaching dashboard",
			tutorInitials: "TA",
		},
		sidebarLinks: [
			{ label: "Home", detail: "Teaching overview", icon: "OV", href: getDashboardHomeHref("teacher"), active: true },
			{ label: "Assignments", detail: "Homework setup", icon: "AS", href: getDashboardAssignmentsHref("teacher") },
			{ label: "Classrooms", detail: "Roster & codes", icon: "CL", href: getDashboardClassroomsHref("teacher") },
			{ label: "Messages", detail: "Inbox & follow-up", icon: "MS", href: getDashboardMessagesHref("teacher") },
			{ label: "Settings", detail: "Profile & preferences", icon: "ST", href: getDashboardSettingsHref("teacher") },
		],
		sidebarSupport: {
			avatars: ["RQ", "AS", "CL"],
			title: "Review queue",
			description: needsReviewCount > 0 ? `${needsReviewCount} submission${needsReviewCount === 1 ? " is" : "s are"} ready for review.` : "Everything is caught up right now.",
			buttonLabel: "Open assignments",
			buttonHref: getDashboardAssignmentsHref("teacher"),
		},
		topbarSummary: {
			searchPlaceholder: "Search classes, assignments, or students",
			profileName: "Teacher",
			profileRole: "Teaching dashboard",
			profileBadge: "TA",
			notificationCount: 0,
			messageCount: 0,
		},
		topbarNotifications: [],
		topbarMessages: [] as TopbarMessageItem[],
	};

	return {
		shell,
			overview: {
				eyebrow: "Teacher dashboard",
				title: needsReviewCount > 0 ? "Start with student work that needs feedback" : "Your teaching dashboard is ready for the next move",
				description:
					needsReviewCount > 0
						? `You have ${needsReviewCount} submission${needsReviewCount === 1 ? "" : "s"} waiting. Clear the review queue first, then head into assignments to publish or adjust homework.`
						: nextDueAssignment != null
						? `${teacherDashboardLabels.common.nextDue}: ${nextDueAssignment.title} on ${formatShortDate(nextDueAssignment.due_at)}. Use this page to decide whether to review work, publish drafts, or check classrooms.`
						: draftAssignments.length > 0
							? `You have ${draftAssignments.length} draft assignment${draftAssignments.length === 1 ? "" : "s"} ready for the next publishing pass.`
							: "Use this page to jump into reviews, homework setup, and classroom organisation without scanning extra noise.",
				stats: [
					{ label: teacherDashboardLabels.home.needsReview, value: compact(needsReviewCount), note: needsReviewCount > 0 ? "Students waiting for feedback" : "No submissions waiting" },
					{ label: teacherDashboardLabels.home.draftsToPublish, value: compact(draftAssignments.length), note: liveAssignments.length > 0 ? `${compact(liveAssignments.length)} live right now` : "No live homework yet" },
					{ label: teacherDashboardLabels.common.students, value: compact(uniqueStudentIds.size), note: `${classrooms.length} classroom${classrooms.length === 1 ? "" : "s"} in rotation` },
					{ label: teacherDashboardLabels.home.reviewCoverage, value: `${reviewCoverage}%`, note: `${compact(reviewedCount)} of ${compact(assignedCount)} assigned reviews completed` },
				],
				actions: [
					{ label: needsReviewCount > 0 ? "Review submissions" : "Open assignments", description: needsReviewCount > 0 ? "Jump straight into student work waiting for feedback." : "Manage drafts and live homework from one place.", href: getDashboardAssignmentsHref("teacher"), tone: "primary" },
					{ label: "View classrooms", description: "Check rosters, invite codes, and classroom load.", href: getDashboardClassroomsHref("teacher"), tone: "secondary" },
				],
			},
			reviewQueue: {
				title: "Review queue",
				description: "These are the freshest student submissions waiting for your attention right now.",
				items: reviewQueueItems,
			},
			assignmentFocus: {
				title: "Assignments to watch next",
				description: "Keep homework setup and live teaching work visible without turning the home page into a full management board.",
				items: assignmentHealthItems,
			},
			classrooms: {
				title: "Classrooms",
				description: "See each class at a glance with roster size, invite code, and workload signals.",
				items: classroomCards,
			},
		};
};
