/**
 * GradeBadge — small reusable pill that shows "XX% (1 / A*)" for a given
 * percentage + scale. Used in the student Grades page, the admin Reports
 * page, and the teacher mark-entry forms.
 *
 * Pass a `scaleKey` / `gradingScale` (e.g. "zimsec_olevel"); if absent, we
 * fall back to the school default from useSchoolSettingsStore. This keeps
 * the badge working on data that hasn't been decorated server-side (e.g.
 * mid-edit in the form) while still using the live school default.
 *
 * Older callers (e.g. parent/student dashboards) pass a pre-resolved
 * `band` object — we honour it as the source of truth and skip the
 * resolver. New code should pass the raw percentage + scale key instead.
 */

import React from 'react';
import { letterFor, type LetterResult } from '../lib/gradeScales';
import { useSchoolSettingsStore } from '../store/schoolSettings';

export interface PreResolvedBand {
  letter: string;
  descriptor?: string | null;
  scale: { key: string; label?: string };
}

export interface GradeBadgeProps {
  percentage: number | null | undefined;
  /** Modern prop name. */
  scaleKey?: string | null;
  /** Alias of `scaleKey` — accepts the same values. */
  gradingScale?: string | null;
  /** When true, render a compact pill sized for table cells. */
  size?: 'sm' | 'md';
  /** Show the human-readable scale label (e.g. "ZIMSEC O-Level") below. */
  showScaleLabel?: boolean;
  /** Override the resolved letter (e.g. when the server already provided one). */
  overrideLetter?: string | null;
  /** Override the resolved descriptor. */
  overrideDescriptor?: string | null;
  /**
   * Pre-resolved band from the server. When provided, the badge uses the
   * letter/descriptor/scale inside it directly without re-running the
   * resolver. Useful when the server already decorated the row and we
   * just want to render the same shape.
   */
  band?: PreResolvedBand | null;
  /**
   * Backward-compat shim: hide the percentage and show only the letter.
   * The spec says no page shows only the letter, so prefer omitting this
   * prop. Older call sites in the previous-attempt branches still set it
   * to `true` for compact cells — keep the prop but render a tooltip so
   * the percentage is still reachable.
   */
  hidePercentage?: boolean;
  className?: string;
}

const paletteFor = (pct: number | null | undefined) => {
  if (pct == null) {
    return {
      text: 'text-text-muted',
      bg: 'bg-muted/40',
      border: 'border-border',
    };
  }
  if (pct >= 80) {
    return {
      text: 'text-emerald-700 dark:text-emerald-300',
      bg: 'bg-emerald-50 dark:bg-emerald-900/20',
      border: 'border-emerald-100 dark:border-emerald-800',
    };
  }
  if (pct >= 65) {
    return {
      text: 'text-blue-700 dark:text-blue-300',
      bg: 'bg-blue-50 dark:bg-blue-900/20',
      border: 'border-blue-100 dark:border-blue-800',
    };
  }
  if (pct >= 50) {
    return {
      text: 'text-amber-700 dark:text-amber-300',
      bg: 'bg-amber-50 dark:bg-amber-900/20',
      border: 'border-amber-100 dark:border-amber-800',
    };
  }
  return {
    text: 'text-rose-700 dark:text-rose-300',
    bg: 'bg-rose-50 dark:bg-rose-900/20',
    border: 'border-rose-100 dark:border-rose-800',
  };
};

const formatLetter = (result: LetterResult) => {
  if (result.descriptor && result.descriptor !== result.letter) {
    return `${result.letter} / ${result.descriptor}`;
  }
  return result.letter;
};

export const GradeBadge: React.FC<GradeBadgeProps> = ({
  percentage,
  scaleKey,
  gradingScale,
  size = 'md',
  showScaleLabel = false,
  overrideLetter,
  overrideDescriptor,
  band,
  hidePercentage = false,
  className = '',
}) => {
  const defaultScale = useSchoolSettingsStore((s) => s.defaultGradingScale);
  const resolvedScale = scaleKey ?? gradingScale ?? band?.scale?.key ?? defaultScale;
  const result = letterFor(percentage ?? 0, resolvedScale);
  const letter = band?.letter ?? overrideLetter ?? result.letter;
  const descriptor = band?.descriptor ?? overrideDescriptor ?? result.descriptor;
  const colors = paletteFor(percentage);
  const isSmall = size === 'sm';
  const containerSize = isSmall ? 'px-2 py-0.5' : 'px-3 py-1.5';
  const pctTextSize = isSmall ? 'text-[0.7rem]' : 'text-sm';

  if (percentage == null || Number.isNaN(percentage)) {
    return (
      <span
        className={`inline-flex items-center gap-1.5 rounded-full border ${colors.bg} ${colors.border} ${colors.text} ${containerSize} font-bold tracking-wide ${className}`}
      >
        <span>—</span>
      </span>
    );
  }

  const pctText = `${Math.round(percentage * 100) / 100}%`;
  const letterText = descriptor && descriptor !== letter ? `${letter} / ${descriptor}` : letter;
  const scaleLabel = band?.scale?.label || result.label;

  return (
    <span
      title={hidePercentage ? `${pctText} (${letterText})` : undefined}
      className={`inline-flex flex-col items-start gap-0.5 rounded-2xl border ${colors.bg} ${colors.border} ${containerSize} font-bold ${className}`}
    >
      <span className={`${colors.text} ${pctTextSize} font-black tracking-tight`}>
        {hidePercentage ? letterText : (
          <>
            {pctText}{' '}
            <span className="opacity-60 font-bold">({letterText})</span>
          </>
        )}
      </span>
      {showScaleLabel && !isSmall && (
        <span className={`${colors.text} opacity-70 text-[0.6rem] uppercase tracking-widest font-black`}>
          {scaleLabel}
        </span>
      )}
    </span>
  );
};

export default GradeBadge;
