import { MaterialIcon } from "@/components/ui/MaterialIcon";

import { MCQ_FORMATS } from "@/lib/question-formats";

interface McqOptionItem {
  key: string;
  text: string;
}

interface MatchingOptionItem {
  left: string;
  right?: string;
}

interface OptionDisplayProps {
  format: string;
  options: unknown;
  correctAnswer: string;
  userAnswer: string;
}

export function OptionDisplay({ format, options, correctAnswer, userAnswer }: OptionDisplayProps) {
  if (!Array.isArray(options) || options.length === 0) return null;

  if (format === "matching_pairs") {
    return <MatchingPairsOptions options={options as MatchingOptionItem[]} correctAnswer={correctAnswer} userAnswer={userAnswer} />;
  }

  if (format === "true_false_not_given") {
    return <TriStateOptions choices={["TRUE", "FALSE", "NOT_GIVEN"]} labels={{ TRUE: "True", FALSE: "False", NOT_GIVEN: "Not Given" }} correctAnswer={correctAnswer} userAnswer={userAnswer} />;
  }

  if (format === "author_view") {
    return <TriStateOptions choices={["YES", "NO", "NOT_GIVEN"]} labels={{ YES: "Yes", NO: "No", NOT_GIVEN: "Not Given" }} correctAnswer={correctAnswer} userAnswer={userAnswer} />;
  }

  if ((MCQ_FORMATS as readonly string[]).includes(format)) {
    return <McqOptions options={options as McqOptionItem[]} correctAnswer={correctAnswer} userAnswer={userAnswer} />;
  }

  return null;
}

function McqOptions({ options, correctAnswer, userAnswer }: { options: { key: string; text: string }[]; correctAnswer: string; userAnswer: string }) {
  const normUser = userAnswer?.trim().toUpperCase() || "";
  const normCorrect = correctAnswer?.trim().toUpperCase() || "";
  const hasAnswer = !!userAnswer && userAnswer !== "Tidak dijawab";

  return (
    <div className="space-y-2">
      {options.map((opt) => {
        const key = opt.key.trim().toUpperCase();
        const isCorrectOption = key === normCorrect;
        const isChosen = key === normUser && hasAnswer;
        const isWrongChoice = isChosen && !isCorrectOption;

        let bg = "bg-[var(--oat-light)]";
        let keyBg = "bg-[var(--oat-light)] text-[var(--clay-black)]";
        let border = "border-[var(--oat-border)]";
        let icon = null;

        if (isWrongChoice) {
          bg = "bg-[var(--pomegranate-100)]";
          keyBg = "bg-[var(--pomegranate-400)] text-[var(--pure-white)]";
          border = "border-[var(--pomegranate-400)]";
          icon = <MaterialIcon name="cancel" className="text-sm text-[var(--pomegranate-400)] shrink-0" />;
        } else if (isCorrectOption) {
          bg = "bg-[var(--matcha-300)]/20";
          keyBg = "bg-[var(--matcha-600)] text-[var(--pure-white)]";
          border = "border-[var(--matcha-400)]";
          icon = <MaterialIcon name="check_circle" className="text-sm text-[var(--matcha-600)] shrink-0" />;
        }

        return (
          <div key={opt.key} className={`flex items-center gap-3 p-3 rounded-[var(--radius-lg)] border-2 ${border} ${bg}`}>
            <span className={`w-8 h-8 min-w-[2rem] min-h-[2rem] rounded-full text-sm font-bold flex items-center justify-center shrink-0 ${keyBg}`}>
              {key || "?"}
            </span>
            <span className="flex-1 text-sm text-[var(--clay-black)]">{opt.text}</span>
            {icon}
          </div>
        );
      })}
    </div>
  );
}

function TriStateOptions({ choices, labels, correctAnswer, userAnswer }: { choices: string[]; labels: Record<string, string>; correctAnswer: string; userAnswer: string }) {
  const normUser = userAnswer?.trim().toUpperCase().replace(/\s+/g, "_") || "";
  const normCorrect = correctAnswer?.trim().toUpperCase() || "";
  const hasAnswer = !!userAnswer && userAnswer !== "Tidak dijawab";

  return (
    <div className="space-y-2">
      {choices.map((c) => {
        const isCorrectOption = c === normCorrect;
        const isChosen = c === normUser && hasAnswer;
        const isWrongChoice = isChosen && !isCorrectOption;

        let bg = "bg-[var(--oat-light)]";
        let dot = "border-[var(--oat-border)]";
        let textColor = "text-[var(--warm-charcoal)]";

        if (isWrongChoice) {
          bg = "bg-[var(--pomegranate-100)]";
          dot = "border-[var(--pomegranate-400)] bg-[var(--pomegranate-400)]";
          textColor = "text-[var(--pomegranate-600)]";
        } else if (isCorrectOption) {
          bg = "bg-[var(--matcha-300)]/20";
          dot = "border-[var(--matcha-600)] bg-[var(--matcha-600)]";
          textColor = "text-[var(--matcha-800)]";
        }

        return (
          <div key={c} className={`flex items-center gap-3 p-3 rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] ${bg}`}>
            <span className={`w-5 h-5 rounded-full border-2 ${dot} flex items-center justify-center shrink-0`}>
              {isChosen || isCorrectOption ? <span className="w-2 h-2 rounded-full bg-white" /> : null}
            </span>
            <span className={`text-sm font-semibold ${textColor}`}>{labels[c]}</span>
          </div>
        );
      })}
    </div>
  );
}

function MatchingPairsOptions({ options, correctAnswer, userAnswer }: { options: MatchingOptionItem[]; correctAnswer: string; userAnswer: string }) {
  const parseMapping = (s: string): Map<string, string> => {
    const map = new Map();
    if (!s) return map;
    s.split(",").forEach((pair) => {
      const [k, v] = pair.split(":").map((x) => x.trim());
      if (k && v) map.set(k, v);
    });
    return map;
  };

  const correctMap = parseMapping(correctAnswer);
  const userMap = parseMapping(userAnswer);

  return (
    <div className="space-y-2">
      {options.map((opt) => {
        const matchedCorrect = correctMap.get(opt.left) || "";
        const matchedUser = userMap.get(opt.left) || "";
        const isMatchCorrect = matchedUser === matchedCorrect;
        const hasUserAnswer = !!matchedUser;

        return (
          <div key={opt.left} className="flex items-center gap-3 p-3 rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--oat-light)]">
            <span className="w-8 h-8 rounded-full text-sm font-bold flex items-center justify-center shrink-0 bg-[var(--oat-light)] text-[var(--clay-black)] border-2 border-[var(--oat-border)]">
              {opt.left.charAt(0).toUpperCase()}
            </span>
            <span className="flex-1 text-sm text-[var(--clay-black)]">{opt.left}</span>
            <span className="text-[var(--warm-silver)]">→</span>
            {hasUserAnswer && (
              <span className={`text-sm font-medium px-3 py-1.5 rounded-[var(--radius-md)] ${isMatchCorrect ? "bg-[var(--matcha-300)]/20 text-[var(--matcha-700)]" : "bg-[var(--pomegranate-100)] text-[var(--pomegranate-600)] line-through"}`}>
                {matchedUser}
              </span>
            )}
            {!isMatchCorrect && matchedCorrect && (
              <span className="text-sm font-medium px-3 py-1.5 rounded-[var(--radius-md)] bg-[var(--matcha-300)]/20 text-[var(--matcha-700)]">
                {matchedCorrect}
              </span>
            )}
          </div>
        );
      })}
    </div>
  );
}
