import type { SafetyQuiz } from '@/shared/types/app';
import type {
  SafetyQuizCompletionSummary,
  SafetyQuizComplianceRow,
} from '@/business/safety-quiz/types';

export function getCurrentSafetyQuizWeek(date: Date): string {
  const weekStart = new Date(date);
  weekStart.setHours(0, 0, 0, 0);
  weekStart.setDate(weekStart.getDate() - weekStart.getDay());

  return weekStart.toISOString().slice(0, 10);
}

export function calculateSafetyQuizScore(
  quiz: SafetyQuiz,
  answers: readonly number[],
): number {
  return answers.filter((answer, index) => answer === quiz.questions[index]?.correctIndex).length;
}

export function calculateSafetyQuizProgress(
  currentQuestionIndex: number,
  questionCount: number,
): number {
  if (questionCount <= 0) {
    return 0;
  }

  return Math.round(((currentQuestionIndex + 1) / questionCount) * 100);
}

export function getSafetyQuizFeedback(
  score: number,
  totalQuestions: number,
): string {
  if (score === totalQuestions) {
    return 'Perfect score! Outstanding safety knowledge.';
  }

  if (score >= 3) {
    return 'Great job! Review the explanations for any missed questions.';
  }

  return 'Please review the material and retake when ready.';
}

export function calculateSafetyQuizCompletionSummary(
  complianceRows: readonly SafetyQuizComplianceRow[],
): SafetyQuizCompletionSummary {
  const completedCount = complianceRows.filter((row) => row.status === 'complete').length;
  const totalStaff = complianceRows.length;

  return {
    completedCount,
    totalStaff,
    completionRate: totalStaff > 0 ? Math.round((completedCount / totalStaff) * 100) : 0,
  };
}

export function serializeSafetyQuizPayload(payload: SafetyQuiz): string {
  return JSON.stringify(payload, null, 2);
}

export function parseSafetyQuizPayload(draft: string): SafetyQuiz | string {
  try {
    const parsed: unknown = JSON.parse(draft);
    return validateSafetyQuizPayload(parsed);
  } catch (error) {
    return error instanceof Error && error.message ? error.message : 'Safety quiz JSON is invalid.';
  }
}

function validateSafetyQuizPayload(value: unknown): SafetyQuiz | string {
  if (!isRecord(value)) {
    return 'Safety quiz payload must be a JSON object.';
  }

  if (!isNonEmptyString(value.id) || !isNonEmptyString(value.title)) {
    return 'Safety quiz payload must include id and title.';
  }

  if (!isSafetyQuizFocus(value.focus)) {
    return 'Safety quiz focus must be physical-management, de-escalation, or safety-reminders.';
  }

  if (!isRecord(value.weeklyFocus)
    || !isNonEmptyString(value.weeklyFocus.title)
    || !isNonEmptyString(value.weeklyFocus.description)) {
    return 'Weekly focus must include title and description.';
  }

  const keyReminders = value.keyReminders;
  if (!Array.isArray(keyReminders) || !keyReminders.every(isNonEmptyString)) {
    return 'Key reminders must be an array of non-empty strings.';
  }

  const questions = value.questions;
  if (!Array.isArray(questions) || questions.length === 0) {
    return 'Questions must be a non-empty array.';
  }

  for (const question of questions) {
    if (!isValidSafetyQuizQuestion(question)) {
      return 'Each question must include id, question, options, correctIndex, and explanation.';
    }
  }

  return {
    id: value.id,
    title: value.title,
    focus: value.focus,
    weeklyFocus: {
      title: value.weeklyFocus.title,
      description: value.weeklyFocus.description,
    },
    keyReminders,
    questions,
  };
}

function isValidSafetyQuizQuestion(value: unknown): value is SafetyQuiz['questions'][number] {
  if (!isRecord(value)) {
    return false;
  }

  const correctIndex = value.correctIndex;

  return isNonEmptyString(value.id)
    && isNonEmptyString(value.question)
    && Array.isArray(value.options)
    && value.options.length > 0
    && value.options.every(isNonEmptyString)
    && typeof correctIndex === 'number'
    && Number.isInteger(correctIndex)
    && correctIndex >= 0
    && correctIndex < value.options.length
    && isNonEmptyString(value.explanation);
}

function isSafetyQuizFocus(value: unknown): value is SafetyQuiz['focus'] {
  return value === 'physical-management'
    || value === 'de-escalation'
    || value === 'safety-reminders';
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function isNonEmptyString(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0;
}
