"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

interface Card {
  id: string;
  front: string;
  back: string;
}

interface ProgressData {
  mode: "SEQUENTIAL" | "SHUFFLED";
  currentIndex: number;
  orderJson: string;
  cardResultsJson: string | null;
}

interface FlashcardViewerProps {
  cards: Card[];
  deckId: string;
  isShared?: boolean;
  initialProgress?: ProgressData | null;
}

type CardResult = "correct" | "missed";

export function FlashcardViewer({ cards, deckId, isShared = false, initialProgress }: FlashcardViewerProps) {
  const [order, setOrder] = useState<string[]>(
    initialProgress ? JSON.parse(initialProgress.orderJson) : cards.map((c) => c.id)
  );
  const [currentIndex, setCurrentIndex] = useState(
    initialProgress ? initialProgress.currentIndex : 0
  );
  const [isFlipped, setIsFlipped] = useState(false);
  const [hasFlippedOnce, setHasFlippedOnce] = useState(false);
  const [results, setResults] = useState<Record<string, CardResult>>(
    initialProgress && initialProgress.cardResultsJson 
      ? JSON.parse(initialProgress.cardResultsJson) 
      : {}
  );
  const [isShuffled, setIsShuffled] = useState<boolean>(
    initialProgress ? initialProgress.mode === "SHUFFLED" : false
  );
  const [toastMessage, setToastMessage] = useState<string | null>(null);
  
  // If progress is provided and index is already at or past the end, it means completed
  const [completed, setCompleted] = useState(
    initialProgress 
      ? initialProgress.currentIndex >= JSON.parse(initialProgress.orderJson).length 
      : false
  );
  const [swipeClass, setSwipeClass] = useState("");
  const cardRef = useRef<HTMLDivElement>(null);

  // Touch/drag state
  const dragRef = useRef({ startX: 0, currentX: 0, isDragging: false });

  const currentCard = order.length > 0 ? cards.find((c) => c.id === order[currentIndex]) : null;
  const correctCount = Object.values(results).filter((r) => r === "correct").length;
  const missedCount = Object.values(results).filter((r) => r === "missed").length;
  const totalGraded = correctCount + missedCount;

  // Auto-hide toast
  useEffect(() => {
    if (toastMessage) {
      const timer = setTimeout(() => setToastMessage(null), 3000);
      return () => clearTimeout(timer);
    }
  }, [toastMessage]);

  function toggleShuffle() {
    const newShuffled = !isShuffled;
    setIsShuffled(newShuffled);
    
    const remainingIds = order.slice(currentIndex);
    let newRemaining: string[];
    
    if (newShuffled) {
      newRemaining = [...remainingIds].sort(() => Math.random() - 0.5);
      setToastMessage("Card shuffle on");
    } else {
      const originalIndices = new Map(cards.map((c, i) => [c.id, i]));
      newRemaining = [...remainingIds].sort((a, b) => (originalIndices.get(a) || 0) - (originalIndices.get(b) || 0));
      setToastMessage("Card shuffle off");
    }
    
    const newOrder = [...order.slice(0, currentIndex), ...newRemaining];
    setOrder(newOrder);
    saveProgress(newOrder, currentIndex, results, newShuffled ? "SHUFFLED" : "SEQUENTIAL");
  }

  // Grade the current card
  const gradeCard = useCallback(
    (grade: CardResult) => {
      if (!currentCard || !hasFlippedOnce) return;

      setToastMessage(null);
      const newResults = { ...results, [currentCard.id]: grade };
      setResults(newResults);

      // Animate
      setSwipeClass(grade === "correct" ? "animate-swipe-right" : "animate-swipe-left");

      setTimeout(() => {
        setSwipeClass("");
        setIsFlipped(false);
        setHasFlippedOnce(false);

        if (currentIndex + 1 >= order.length) {
          setCompleted(true);
          saveProgress(order, currentIndex, newResults, isShuffled ? "SHUFFLED" : "SEQUENTIAL");
        } else {
          const nextIndex = currentIndex + 1;
          setCurrentIndex(nextIndex);
          saveProgress(order, nextIndex, newResults, isShuffled ? "SHUFFLED" : "SEQUENTIAL");
        }
      }, 350);
    },
    [currentCard, hasFlippedOnce, results, currentIndex, order, isShuffled]
  );

  // Keyboard shortcuts
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (completed) return;

      if (e.key === " " || e.key === "Enter" || e.key === "ArrowUp" || e.key === "ArrowDown") {
        e.preventDefault();
        setToastMessage(null);
        setIsFlipped((prev) => {
          if (!prev) setHasFlippedOnce(true);
          return !prev;
        });
      } else if (e.key === "ArrowRight" && hasFlippedOnce) {
        gradeCard("correct");
      } else if (e.key === "ArrowLeft" && hasFlippedOnce) {
        gradeCard("missed");
      }
    }

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [completed, isFlipped, gradeCard]);

  // Touch handlers for swipe
  function handleTouchStart(e: React.TouchEvent) {
    if (!hasFlippedOnce) return;
    dragRef.current = {
      startX: e.touches[0].clientX,
      currentX: e.touches[0].clientX,
      isDragging: true,
    };
  }

  function handleTouchMove(e: React.TouchEvent) {
    if (!dragRef.current.isDragging) return;
    dragRef.current.currentX = e.touches[0].clientX;
    const dx = dragRef.current.currentX - dragRef.current.startX;
    if (cardRef.current) {
      cardRef.current.style.transform = `translateX(${dx}px) rotate(${dx * 0.05}deg)`;
    }
  }

  function handleTouchEnd() {
    if (!dragRef.current.isDragging) return;
    dragRef.current.isDragging = false;
    const dx = dragRef.current.currentX - dragRef.current.startX;

    if (cardRef.current) {
      cardRef.current.style.transform = "";
    }

    if (Math.abs(dx) > 80) {
      gradeCard(dx > 0 ? "correct" : "missed");
    }
  }

  // Save progress (debounced / fire-and-forget)
  function saveProgress(
    orderArr: string[],
    index: number,
    cardResults: Record<string, CardResult>,
    m: "SEQUENTIAL" | "SHUFFLED"
  ) {
    if (isShared) return;
    
    fetch("/api/progress", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        contentType: "DECK",
        contentId: deckId,
        mode: m,
        currentIndex: index,
        orderJson: JSON.stringify(orderArr),
        cardResultsJson: JSON.stringify(cardResults),
      }),
    }).catch(() => {}); // fire-and-forget
  }

  // Restart handlers
  function restartFullSet() {
    let newOrder: string[];
    if (isShuffled) {
      newOrder = [...cards.map((c) => c.id)].sort(() => Math.random() - 0.5);
    } else {
      newOrder = cards.map((c) => c.id);
    }
    setOrder(newOrder);
    setCurrentIndex(0);
    setResults({});
    setIsFlipped(false);
    setHasFlippedOnce(false);
    setCompleted(false);
    saveProgress(newOrder, 0, {}, isShuffled ? "SHUFFLED" : "SEQUENTIAL");
  }

  function redoMissed() {
    const missedIds = Object.entries(results)
      .filter(([, r]) => r === "missed")
      .map(([id]) => id);

    if (missedIds.length === 0) return;

    const newOrder = isShuffled
      ? [...missedIds].sort(() => Math.random() - 0.5)
      : missedIds;

    setOrder(newOrder);
    setCurrentIndex(0);
    setResults({});
    setIsFlipped(false);
    setHasFlippedOnce(false);
    setCompleted(false);
    saveProgress(newOrder, 0, {}, isShuffled ? "SHUFFLED" : "SEQUENTIAL");
  }

  // Completed summary
  if (completed) {
    return (
      <div className="flex flex-col items-center justify-center py-16">
        <div className="bg-bg-surface rounded-2xl border border-border-light shadow-[var(--shadow-card)] p-8 max-w-md w-full text-center">
          <div className="inline-flex items-center justify-center w-14 h-14 rounded-xl bg-success-bg mb-4">
            <svg className="w-7 h-7 text-success" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
            </svg>
          </div>
          <h3 className="text-lg font-semibold text-text-heading mb-2">Set Complete!</h3>

          <div className="flex justify-center gap-6 mb-6">
            <div className="text-center">
              <div className="text-2xl font-bold text-success">{correctCount}</div>
              <div className="text-xs text-text-muted">Correct</div>
            </div>
            <div className="text-center">
              <div className="text-2xl font-bold text-error">{missedCount}</div>
              <div className="text-xs text-text-muted">Missed</div>
            </div>
            <div className="text-center">
              <div className="text-2xl font-bold text-text-heading">{order.length}</div>
              <div className="text-xs text-text-muted">Total</div>
            </div>
          </div>

          {correctCount > 0 && (
            <div className="w-full bg-bg-surface-alt rounded-full h-2 mb-6">
              <div
                className="h-2 rounded-full bg-success transition-all duration-500"
                style={{ width: `${(correctCount / order.length) * 100}%` }}
              />
            </div>
          )}

          <div className="flex flex-col gap-3">
            <button
              onClick={restartFullSet}
              className="w-full py-3 px-4 rounded-lg bg-primary text-white font-medium hover:bg-primary-hover transition-all duration-200 cursor-pointer"
            >
              Restart Full Set
            </button>
            {missedCount > 0 && (
              <button
                onClick={redoMissed}
                className="w-full py-3 px-4 rounded-lg border border-border text-text-heading font-medium hover:bg-bg-surface-alt transition-all duration-200 cursor-pointer"
              >
                Redo Missed Only ({missedCount} {missedCount === 1 ? "card" : "cards"})
              </button>
            )}
          </div>
        </div>
      </div>
    );
  }

  // Study view
  return (
    <div className="flex flex-col items-center">
      {/* Running tally */}
      <div className="w-full max-w-4xl mb-6">
        <div className="flex items-center justify-between text-sm">
          <div className="flex items-center gap-3">
            <span className="text-success font-medium">{correctCount} ✓</span>
            <span className="text-error font-medium">{missedCount} ✗</span>
          </div>
          <span className="text-text-muted">
            {currentIndex + 1} of {order.length}
          </span>
        </div>
        {/* Progress bar */}
        <div className="w-full bg-bg-surface rounded-full h-2 mt-2 border border-border-light/50 overflow-hidden">
          <div
            className="h-full bg-primary transition-all duration-300"
            style={{ width: `${((currentIndex + 1) / order.length) * 100}%` }}
          />
        </div>
      </div>

      {/* Card */}
      {currentCard && (
        <div className="w-full max-w-4xl">
          <div
            ref={cardRef}
            className={`perspective-1000 cursor-pointer select-none relative ${swipeClass}`}
            onClick={() => {
              setToastMessage(null);
              setIsFlipped(!isFlipped);
              if (!isFlipped) setHasFlippedOnce(true);
            }}
            onTouchStart={handleTouchStart}
            onTouchMove={handleTouchMove}
            onTouchEnd={handleTouchEnd}
            style={{ transition: swipeClass ? "none" : "transform 0.15s ease-out" }}
          >
            <div
              key={currentCard.id}
              className={`relative w-full min-h-[450px] md:min-h-[550px] preserve-3d ${!swipeClass ? "transition-transform duration-300" : ""} ${
                isFlipped ? "rotate-x-180" : ""
              }`}
            >
              {/* Front */}
              <div className="absolute inset-0 backface-hidden bg-bg-surface rounded-2xl border border-border-light shadow-[var(--shadow-card)] p-8 md:p-12 flex flex-col items-center justify-center">
                <span className="absolute top-3 right-4 text-xs font-medium text-text-muted uppercase tracking-wider">
                  Front
                </span>
                <div className="markdown-content text-center text-xl md:text-3xl text-text-heading leading-relaxed w-full">
                  <ReactMarkdown remarkPlugins={[remarkGfm]}>
                    {currentCard.front}
                  </ReactMarkdown>
                </div>
                <p className="mt-6 text-xs text-text-muted">
                  Tap <span className="hidden md:inline">or press Space </span>to flip
                </p>
              </div>

              {/* Back */}
              <div className="absolute inset-0 backface-hidden rotate-x-180 bg-bg-surface rounded-2xl border border-border-light shadow-[var(--shadow-card)] p-8 md:p-12 flex flex-col items-center justify-center">
                <span className="absolute top-3 right-4 text-xs font-medium text-text-muted uppercase tracking-wider">
                  Back
                </span>
                <div className="markdown-content text-center text-lg md:text-xl text-text-body leading-relaxed max-h-[400px] md:max-h-[450px] overflow-y-auto w-full">
                  <ReactMarkdown remarkPlugins={[remarkGfm]}>
                    {currentCard.back}
                  </ReactMarkdown>
                </div>
              </div>
            </div>

            {/* Grading Overlay */}
            {swipeClass && (
              <div
                className={`absolute inset-0 z-20 flex items-center justify-center rounded-2xl border-2 md:border-4 transition-colors duration-150 ${
                  swipeClass === "animate-swipe-left"
                    ? "border-error bg-bg-surface/40 backdrop-blur-[2px]"
                    : "border-success bg-bg-surface/40 backdrop-blur-[2px]"
                }`}
              >
                <span
                  className={`text-3xl md:text-5xl font-bold px-8 py-4 rounded-3xl -rotate-12 uppercase tracking-wider shadow-lg ${
                    swipeClass === "animate-swipe-left"
                      ? "text-error bg-error-bg/90"
                      : "text-success bg-success-bg/90"
                  }`}
                >
                  {swipeClass === "animate-swipe-left" ? "Still learning" : "Know"}
                </span>
              </div>
            )}

            {/* Toast Notification */}
            {toastMessage && (
              <div className="absolute bottom-6 left-1/2 -translate-x-1/2 z-30 animate-fade-in pointer-events-none">
                <div className="bg-bg-surface-alt/95 backdrop-blur shadow-[var(--shadow-card)] text-text-heading text-sm font-semibold px-6 py-2.5 rounded-full whitespace-nowrap">
                  {toastMessage}
                </div>
              </div>
            )}
          </div>

          <div className="w-full mt-6">
            
            {/* Primary Action Row (Grading) */}
            <div className={`flex items-center justify-center gap-4 min-h-[52px] mb-4 relative z-10 ${!hasFlippedOnce ? 'pointer-events-none' : ''}`}>
              {hasFlippedOnce && (
                <div className="flex items-center gap-2 md:gap-4 animate-fade-in pointer-events-auto">
                  <button
                    onClick={() => gradeCard("missed")}
                    className="flex items-center gap-2 px-6 py-3 rounded-xl border-2 border-error/30 text-error font-medium hover:bg-error-bg transition-all duration-200 cursor-pointer bg-bg-base/80 backdrop-blur"
                  >
                    <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                    </svg>
                    Missed
                  </button>
                  <button
                    onClick={() => gradeCard("correct")}
                    className="flex items-center gap-2 px-6 py-3 rounded-xl border-2 border-success/30 text-success font-medium hover:bg-success-bg transition-all duration-200 cursor-pointer bg-bg-base/80 backdrop-blur"
                  >
                    <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                    </svg>
                    Got It
                  </button>
                </div>
              )}
            </div>

            {/* Secondary Action Row (Navigation/Settings) */}
            <div className={`flex items-center justify-between w-full px-2 transition-all duration-300 relative z-20 ${!hasFlippedOnce ? '-mt-[68px]' : ''}`}>
              {currentIndex > 0 ? (
                <button
                  onClick={() => {
                    const prevIndex = currentIndex - 1;
                    setCurrentIndex(prevIndex);
                    setIsFlipped(false);
                    setHasFlippedOnce(false);
                    
                    const prevId = order[prevIndex];
                    const newResults = { ...results };
                    delete newResults[prevId];
                    setResults(newResults);
                    saveProgress(order, prevIndex, newResults, isShuffled ? "SHUFFLED" : "SEQUENTIAL");
                  }}
                  className="p-2 rounded-full text-text-muted hover:bg-bg-surface-alt hover:text-text-heading transition-all duration-200 cursor-pointer bg-bg-base/50"
                  title="Previous Card"
                >
                  <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
                  </svg>
                </button>
              ) : <div className="w-9 h-9" />}

              <button
                onClick={toggleShuffle}
                className={`p-2 rounded-full transition-all duration-200 cursor-pointer bg-bg-base/50 ${
                  isShuffled 
                    ? "text-primary hover:bg-primary/10" 
                    : "text-text-muted hover:bg-bg-surface-alt hover:text-text-heading"
                }`}
                title={isShuffled ? "Turn off shuffle" : "Shuffle remaining"}
              >
                <svg className={`w-5 h-5 ${isShuffled ? "stroke-[2.5]" : "stroke-2"}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M16 3h5v5M4 20L21 3M21 16v5h-5M15 15l6 6M4 4l5 5" />
                </svg>
              </button>
            </div>
          </div>

            <div className="text-center mt-4 text-xs text-text-muted">
              {hasFlippedOnce
                ? "← Missed · Got It →"
                : "Space to flip"}
            </div>
        </div>
      )}
    </div>
  );
}
