import type { TeacherReviewDraftFields, TeacherReviewQuestion } from "./assignment-teacher-review.types";
import { assignmentUiCopy } from "~/content/ui-copy";

export type QuestionReviewDraft = TeacherReviewDraftFields & {
	answerId: number;
};

export type StudentReviewDraft = {
	questionReviews?: Record<string, QuestionReviewDraft>;
};

export type AssignmentReviewDraftStore = {
	students: Record<string, StudentReviewDraft>;
};

export const EMPTY_DRAFT_STORE: AssignmentReviewDraftStore = {
	students: {},
};

export const draftStorageKeyForAssignment = (assignmentId: number) => `teacher-review-draft:${assignmentId}`;

export const readDraftStore = (assignmentId: number): AssignmentReviewDraftStore => {
	if (typeof window === "undefined") return EMPTY_DRAFT_STORE;

	try {
		const raw = window.localStorage.getItem(draftStorageKeyForAssignment(assignmentId));
		if (!raw) return EMPTY_DRAFT_STORE;
		const parsed = JSON.parse(raw);
		if (!parsed || typeof parsed !== "object" || typeof parsed.students !== "object" || parsed.students === null) {
			return EMPTY_DRAFT_STORE;
		}

		return {
			students: parsed.students as AssignmentReviewDraftStore["students"],
		};
	} catch {
		return EMPTY_DRAFT_STORE;
	}
};

export const writeDraftStore = (assignmentId: number, draftStore: AssignmentReviewDraftStore) => {
	if (typeof window === "undefined") return;
	const key = draftStorageKeyForAssignment(assignmentId);
	if (Object.keys(draftStore.students).length === 0) {
		window.localStorage.removeItem(key);
		return;
	}

	window.localStorage.setItem(key, JSON.stringify(draftStore));
};

export const reviewFieldsFromQuestion = (question: TeacherReviewQuestion): TeacherReviewDraftFields => ({
	reviewNeedsAttention: question.reviewNeedsAttention,
	reviewIssueReason: question.reviewIssueReason,
	reviewCorrectnessScore: question.reviewCorrectnessScore,
	reviewUnderstandingScore: question.reviewUnderstandingScore,
	reviewQuestionScore: question.reviewQuestionScore,
	reviewConfidence: question.reviewConfidence,
});

const normalizeOptionalScore = (value: number | null) => (typeof value === "number" && Number.isFinite(value) ? Math.min(1, Math.max(0, Number(value.toFixed(3)))) : null);

export const sanitizeReviewFields = (fields: TeacherReviewDraftFields): TeacherReviewDraftFields => ({
	reviewNeedsAttention: Boolean(fields.reviewNeedsAttention),
	reviewIssueReason: fields.reviewIssueReason.trim(),
	reviewCorrectnessScore: 1,
	reviewUnderstandingScore: normalizeOptionalScore(fields.reviewUnderstandingScore),
	reviewQuestionScore: 1,
	reviewConfidence: normalizeOptionalScore(fields.reviewConfidence),
});

export const reviewFieldsEqual = (left: TeacherReviewDraftFields, right: TeacherReviewDraftFields) =>
	left.reviewNeedsAttention === right.reviewNeedsAttention &&
	left.reviewIssueReason === right.reviewIssueReason &&
	left.reviewCorrectnessScore === right.reviewCorrectnessScore &&
	left.reviewUnderstandingScore === right.reviewUnderstandingScore &&
	left.reviewQuestionScore === right.reviewQuestionScore &&
	left.reviewConfidence === right.reviewConfidence;

const questionStatusMeta = (status: TeacherReviewQuestion["answerStatus"]) => {
	if (status === "reviewed") {
		return { statusLabel: assignmentUiCopy.teacherReview.status.reviewed, statusTone: "success" as const };
	}
	if (status === "submitted") {
		return { statusLabel: assignmentUiCopy.teacherReview.status.submitted, statusTone: "review" as const };
	}
	if (status === "in_progress") {
		return { statusLabel: assignmentUiCopy.teacherReview.status.inProgress, statusTone: "progress" as const };
	}
	return { statusLabel: assignmentUiCopy.teacherReview.status.noAnswerYet, statusTone: "muted" as const };
};

export const applyReviewDrafts = (questions: TeacherReviewQuestion[], studentDraft: StudentReviewDraft | null) =>
	questions.map((question) => {
		const draftReview = studentDraft?.questionReviews?.[String(question.id)] ?? null;
		if (!draftReview) return question;

		const effectiveReview = sanitizeReviewFields({
			...reviewFieldsFromQuestion(question),
			...draftReview,
		});
		const nextStatus = effectiveReview.reviewNeedsAttention ? "submitted" : question.answerStatus;
		const statusMeta = questionStatusMeta(nextStatus);

		return {
			...question,
			...effectiveReview,
			answerStatus: nextStatus,
			statusLabel: effectiveReview.reviewNeedsAttention ? assignmentUiCopy.teacherReview.status.needsAttention : statusMeta.statusLabel,
			statusTone: statusMeta.statusTone,
			reviewedLabel: effectiveReview.reviewNeedsAttention ? assignmentUiCopy.teacherReview.status.needsAttentionDraft : question.reviewedLabel,
		};
	});

export const countPendingQuestionDrafts = (draftStore: AssignmentReviewDraftStore) =>
	Object.values(draftStore.students).reduce((count, studentDraft) => count + Object.keys(studentDraft.questionReviews ?? {}).length, 0);
