import { useEffect, useState } from "react";
import { api } from "../utils/api";
import { useAuthToken } from "../hooks/useAuthToken";
import {
  TrendingUp,
  BookOpen,
  Calculator,
  Loader2,
  ChevronDown,
  ChevronUp,
} from "lucide-react";

// ─── Types ────────────────────────────────────────────────────────────────────

interface SectionPrediction {
  score: number;
  range_min: number;
  range_max: number;
  confidence: string;
}

interface PredictedScoreResponse {
  total_score: number;
  math_prediction: SectionPrediction;
  rw_prediction: SectionPrediction;
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

const confidenceConfig: Record<
  string,
  { label: string; color: string; bg: string; border: string; dot: string }
> = {
  high: {
    label: "High confidence",
    color: "#16a34a",
    bg: "#f0fdf4",
    border: "#bbf7d0",
    dot: "#22c55e",
  },
  medium: {
    label: "Medium confidence",
    color: "#d97706",
    bg: "#fffbeb",
    border: "#fde68a",
    dot: "#f59e0b",
  },
  low: {
    label: "Low confidence",
    color: "#e11d48",
    bg: "#fff1f2",
    border: "#fecdd3",
    dot: "#f43f5e",
  },
};

const getConfidenceStyle = (confidence: string) =>
  confidenceConfig[confidence.toLowerCase()] ?? {
    label: confidence,
    color: "#6b7280",
    bg: "#f9fafb",
    border: "#f3f4f6",
    dot: "#9ca3af",
  };

const useCountUp = (target: number, duration = 900) => {
  const [value, setValue] = useState(0);
  useEffect(() => {
    if (!target) return;
    let start: number | null = null;
    const step = (ts: number) => {
      if (!start) start = ts;
      const progress = Math.min((ts - start) / duration, 1);
      const eased = 1 - Math.pow(1 - progress, 3);
      setValue(Math.floor(eased * target));
      if (progress < 1) requestAnimationFrame(step);
    };
    requestAnimationFrame(step);
  }, [target, duration]);
  return value;
};

// ─── Styles ───────────────────────────────────────────────────────────────────

const STYLES = `
  @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@700;800;900&family=Nunito+Sans:wght@400;600;700&display=swap');

  .psc-card {
    background: white;
    border: 2.5px solid #f3f4f6;
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0,0,0,0.05);
    font-family: 'Nunito', sans-serif;
    width: 100%;
  }

  /* Header */
  .psc-header {
    padding: 1.1rem 1.25rem 0.75rem;
    display: flex; align-items: center; justify-content: space-between;
    border-bottom: 2px solid #f9fafb;
  }
  .psc-header-left { display:flex;flex-direction:column;gap:0.15rem; }
  .psc-header-title {
    font-size: 0.88rem; font-weight: 900; color: #1e1b4b;
    letter-spacing: -0.01em;
  }
  .psc-header-sub {
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.7rem; font-weight: 600; color: #9ca3af;
  }
  .psc-header-icon {
    width: 36px; height: 36px; border-radius: 12px;
    background: linear-gradient(135deg, #a855f7, #7c3aed);
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 4px 0 #5b21b644;
    flex-shrink: 0;
  }

  /* Body */
  .psc-body { padding: 1.1rem 1.25rem; display:flex;flex-direction:column;gap:0.85rem; }

  /* Scores row */
  .psc-scores-row {
    display: flex; align-items: stretch; gap: 0;
    background: #fafaf9; border: 2px solid #f3f4f6;
    border-radius: 18px; overflow: hidden;
  }

  .psc-score-cell {
    flex: 1; display:flex;flex-direction:column;align-items:center;
    padding: 1rem 0.5rem;
    position: relative;
  }
  .psc-score-cell + .psc-score-cell::before {
    content:''; position:absolute; left:0; top:20%; bottom:20%;
    width:2px; background:#f3f4f6; border-radius:2px;
  }

  /* Total cell — slightly different bg */
  .psc-score-cell.total {
    background: white;
    border-right: 2px solid #f3f4f6;
    flex: 1.2;
  }

  .psc-cell-label {
    display: flex; align-items: center; gap: 0.3rem;
    font-size: 0.58rem; font-weight: 800; letter-spacing: 0.12em;
    text-transform: uppercase; color: #9ca3af; margin-bottom: 0.3rem;
  }
  .psc-cell-score {
    font-weight: 900; color: #1e1b4b; line-height: 1;
  }
  .psc-cell-score.large { font-size: 2.8rem; }
  .psc-cell-score.medium { font-size: 1.7rem; }
  .psc-cell-out {
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.62rem; font-weight: 600; color: #d1d5db;
    margin-top: 0.2rem;
  }

  /* Toggle button */
  .psc-toggle-btn {
    width: 100%; display:flex;align-items:center;justify-content:center;gap:0.4rem;
    padding: 0.55rem; border-radius: 12px; border: 2px solid #f3f4f6;
    background: white; cursor: pointer;
    font-family: 'Nunito', sans-serif;
    font-size: 0.72rem; font-weight: 800; color: #9ca3af;
    transition: all 0.15s ease;
  }
  .psc-toggle-btn:hover { border-color: #e9d5ff; color: #a855f7; background: #fdf4ff; }

  /* Section detail cards */
  .psc-detail-card {
    background: #fafaf9; border: 2.5px solid #f3f4f6; border-radius: 18px;
    padding: 0.9rem 1rem;
    display: flex; flex-direction: column; gap: 0.65rem;
  }

  .psc-detail-top {
    display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  }
  .psc-detail-icon-wrap {
    width: 30px; height: 30px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
  }
  .psc-detail-label {
    font-size: 0.8rem; font-weight: 900; color: #1e1b4b; flex: 1;
  }
  .psc-conf-badge {
    display: flex; align-items: center; gap: 0.3rem;
    padding: 0.2rem 0.6rem; border-radius: 100px; border: 2px solid;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.6rem; font-weight: 700; flex-shrink: 0;
  }
  .psc-conf-dot { width:6px;height:6px;border-radius:50%;flex-shrink:0; }

  .psc-score-range-row {
    display: flex; align-items: flex-end; justify-content: space-between;
  }
  .psc-detail-score {
    font-size: 1.6rem; font-weight: 900; color: #1e1b4b; line-height: 1;
  }
  .psc-range-text {
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.68rem; font-weight: 600; color: #9ca3af;
    text-align: right; line-height: 1.4;
  }
  .psc-range-text span { font-weight: 800; color: #6b7280; }

  /* Range bar */
  .psc-bar-wrap {
    height: 8px; border-radius: 100px; background: #f3f4f6;
    position: relative; overflow: visible;
  }
  .psc-bar-fill {
    position: absolute; height: 100%; border-radius: 100px; opacity: 0.4;
  }
  .psc-bar-dot {
    position: absolute; width: 14px; height: 14px;
    border-radius: 50%; border: 2.5px solid white;
    top: 50%; transform: translate(-50%, -50%);
    box-shadow: 0 2px 6px rgba(0,0,0,0.12);
  }
  .psc-bar-labels {
    display: flex; justify-content: space-between;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.58rem; font-weight: 600; color: #d1d5db;
    margin-top: 0.3rem;
  }

  /* Expanded animation */
  .psc-expanded-wrap {
    display: flex; flex-direction: column; gap: 0.6rem;
    animation: pscFadeIn 0.3s cubic-bezier(0.34,1.56,0.64,1) both;
  }
  @keyframes pscFadeIn {
    from { opacity:0; transform:translateY(-8px); }
    to   { opacity:1; transform:translateY(0); }
  }

  /* Loading */
  .psc-loading {
    display: flex; align-items: center; justify-content: center;
    gap: 0.5rem; padding: 2rem;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.82rem; font-weight: 600; color: #9ca3af;
  }
  .psc-spinner { animation: pscSpin 0.8s linear infinite; }
  @keyframes pscSpin { to { transform: rotate(360deg); } }

  .psc-error {
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.82rem; font-weight: 700; color: #e11d48;
    text-align: center; padding: 1.5rem;
    background: #fff1f2; border-radius: 14px; border: 2px solid #fecdd3;
  }
`;

// ─── Section detail ───────────────────────────────────────────────────────────

const SectionDetail = ({
  label,
  icon: Icon,
  prediction,
  iconBg,
  barColor,
}: {
  label: string;
  icon: React.ElementType;
  prediction: SectionPrediction;
  iconBg: string;
  barColor: string;
}) => {
  const conf = getConfidenceStyle(prediction.confidence);
  const pct = (v: number) => ((v - 200) / (800 - 200)) * 100;

  return (
    <div className="psc-detail-card">
      <div className="psc-detail-top">
        <div className="psc-detail-icon-wrap" style={{ background: iconBg }}>
          {/* @ts-ignore */}
          <Icon size={15} color={barColor} />
        </div>
        <span className="psc-detail-label">{label}</span>
        <div
          className="psc-conf-badge"
          style={{
            background: conf.bg,
            borderColor: conf.border,
            color: conf.color,
          }}
        >
          <div className="psc-conf-dot" style={{ background: conf.dot }} />
          {conf.label}
        </div>
      </div>

      <div className="psc-score-range-row">
        <span className="psc-detail-score">{prediction.score}</span>
        <div className="psc-range-text">
          <span>Range</span>
          <br />
          <span>
            {prediction.range_min}–{prediction.range_max}
          </span>
        </div>
      </div>

      <div>
        <div className="psc-bar-wrap">
          <div
            className="psc-bar-fill"
            style={{
              left: `${pct(prediction.range_min)}%`,
              right: `${100 - pct(prediction.range_max)}%`,
              background: barColor,
            }}
          />
          <div
            className="psc-bar-dot"
            style={{
              left: `${pct(prediction.score)}%`,
              background: barColor,
            }}
          />
        </div>
        <div className="psc-bar-labels">
          <span>200</span>
          <span>800</span>
        </div>
      </div>
    </div>
  );
};

// ─── Main component ───────────────────────────────────────────────────────────

let stylesInjected = false;

export const PredictedScoreCard = () => {
  const token = useAuthToken();
  const [data, setData] = useState<PredictedScoreResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expanded, setExpanded] = useState(false);

  useEffect(() => {
    if (!token) return;
    (async () => {
      try {
        setLoading(true);
        const result = await api.fetchPredictedScore(token);
        setData(result);
      } catch (err) {
        setError("Couldn't load your predicted score.");
        console.error(err);
      } finally {
        setLoading(false);
      }
    })();
  }, [token]);

  if (!stylesInjected) {
    const tag = document.createElement("style");
    tag.textContent = STYLES;
    document.head.appendChild(tag);
    stylesInjected = true;
  }

  const animatedTotal = useCountUp(data?.total_score ?? 0, 1000);

  return (
    <div className="psc-card">
      {/* Header */}
      <div className="psc-header">
        <div className="psc-header-left">
          <p className="psc-header-title">Predicted SAT Score</p>
          <p className="psc-header-sub">Based on your practice performance</p>
        </div>
        <div className="psc-header-icon">
          <TrendingUp size={17} color="white" />
        </div>
      </div>

      {/* Body */}
      <div className="psc-body">
        {loading && (
          <div className="psc-loading">
            <Loader2 size={20} color="#a855f7" className="psc-spinner" />
            Calculating your score...
          </div>
        )}

        {error && !loading && <div className="psc-error">⚠️ {error}</div>}

        {data && !loading && (
          <>
            {/* Score cells */}
            <div className="psc-scores-row">
              {/* Total */}
              <div className="psc-score-cell total">
                <div className="psc-cell-label">
                  <TrendingUp size={10} color="#a855f7" /> Total
                </div>
                <span className="psc-cell-score large">{animatedTotal}</span>
                <span className="psc-cell-out">/ 1600</span>
              </div>

              {/* Math */}
              <div className="psc-score-cell">
                <div className="psc-cell-label">
                  <Calculator size={10} color="#7c3aed" /> Math
                </div>
                <span className="psc-cell-score medium">
                  {data.math_prediction.score}
                </span>
                <span className="psc-cell-out">/ 800</span>
              </div>

              {/* R&W */}
              <div className="psc-score-cell">
                <div className="psc-cell-label">
                  <BookOpen size={10} color="#0891b2" /> R&amp;W
                </div>
                <span className="psc-cell-score medium">
                  {data.rw_prediction.score}
                </span>
                <span className="psc-cell-out">/ 800</span>
              </div>
            </div>

            {/* Toggle */}
            <button
              className="psc-toggle-btn"
              onClick={() => setExpanded((p) => !p)}
            >
              {expanded ? (
                <>
                  <ChevronUp size={13} /> Less detail
                </>
              ) : (
                <>
                  <ChevronDown size={13} /> Score breakdown
                </>
              )}
            </button>

            {/* Expanded */}
            {expanded && (
              <div className="psc-expanded-wrap">
                <SectionDetail
                  label="Mathematics"
                  icon={Calculator}
                  prediction={data.math_prediction}
                  iconBg="#fdf4ff"
                  barColor="#a855f7"
                />
                <SectionDetail
                  label="Reading & Writing"
                  icon={BookOpen}
                  prediction={data.rw_prediction}
                  iconBg="#ecfeff"
                  barColor="#0891b2"
                />
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
};
