'use client';

import { useState, useRef, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
import { Skeleton } from '@/components/ui/skeleton';
import { MathBlock, validateFormula, escapeHtml } from '@/components/math/MathFormula';
import { Exercise } from './ExerciseCard';
import { AnswerInput } from './AnswerInput';
import { ExerciseFeedback, FeedbackData } from './ExerciseFeedback';
import { HintSystem, Hint } from './HintSystem';
import { StepByStepSolution, Solution } from './StepByStepSolution';
import { CheckCircle2, XCircle, Clock, Target, BookOpen } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useToast } from '@/hooks/use-toast';
import { api } from '@/lib/api';

/**
 * Exercise attempt result
 */
export interface ExerciseAttempt {
  id: string;
  exerciseId: string;
  answer: string;
  isCorrect: boolean;
  points: number;
  timestamp: Date;
  hintsUsed: number;
  timeSpent: number;
}

/**
 * ExerciseSolver component props
 */
export interface ExerciseSolverProps {
  /**
   * Exercise to solve
   */
  exercise: Exercise;

  /**
   * On complete callback (when exercise is solved correctly)
   */
  onComplete?: (attempt: ExerciseAttempt) => void;

  /**
   * On skip callback
   */
  onSkip?: () => void;

  /**
   * Show solution button
   */
  showSolutionButton?: boolean;

  /**
   * Enable hints
   */
  enableHints?: boolean;

  /**
   * Enable timer
   */
  enableTimer?: boolean;

  /**
   * Additional CSS classes
   */
  className?: string;

  /**
   * Auto-focus input on mount
   */
  autoFocus?: boolean;
}

/**
 * ExerciseSolver component - main solver interface
 */
export function ExerciseSolver({
  exercise,
  onComplete,
  onSkip,
  showSolutionButton = true,
  enableHints = true,
  enableTimer = true,
  className,
  autoFocus = true,
}: ExerciseSolverProps) {
  const { toast } = useToast();
  // State
  const [answer, setAnswer] = useState('');
  const [feedback, setFeedback] = useState<FeedbackData | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [showSolution, setShowSolution] = useState(false);
  const [revealedHints, setRevealedHints] = useState<Set<number>>(new Set());
  // L-04: Use points from API instead of local counter
  const [earnedPoints, setEarnedPoints] = useState(0);
  const [attempts, setAttempts] = useState<ExerciseAttempt[]>([]);
  const [startTime] = useState(new Date());
  const [elapsedTime, setElapsedTime] = useState(0);
  // L-06: State for fetched solution
  const [solution, setSolution] = useState<Solution | null>(null);
  const [isLoadingSolution, setIsLoadingSolution] = useState(false);

  // Refs
  const inputRef = useRef<HTMLInputElement>(null);
  const timerIntervalRef = useRef<NodeJS.Timeout | null>(null);

  // Auto-focus input
  useEffect(() => {
    if (autoFocus && inputRef.current) {
      inputRef.current.focus();
    }
  }, [autoFocus]);

  // Timer
  useEffect(() => {
    if (enableTimer && feedback?.type !== 'correct' && !showSolution) {
      timerIntervalRef.current = setInterval(() => {
        setElapsedTime(Math.floor((Date.now() - startTime.getTime()) / 1000));
      }, 1000);
    }

    return () => {
      if (timerIntervalRef.current) {
        clearInterval(timerIntervalRef.current);
      }
    };
  }, [enableTimer, feedback, showSolution, startTime]);

  // Format time
  const formatTime = (seconds: number): string => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  // Handle answer submission
  const handleSubmit = async () => {
    if (!answer.trim() || isSubmitting) return;

    setIsSubmitting(true);

    try {
      // Call API to check answer
      const result = await api.post<{
        isCorrect: boolean;
        points: number;
        message?: string;
        explanation?: string;
      }>(`/api/exercises/${exercise.id}/attempt`, {
        answer: answer.trim(),
        hintsUsed: revealedHints.size,
        timeSpent: elapsedTime,
      });

      const attempt: ExerciseAttempt = {
        id: `${exercise.id}-${Date.now()}`,
        exerciseId: exercise.id,
        answer: answer.trim(),
        isCorrect: result.isCorrect,
        points: result.points,
        timestamp: new Date(),
        hintsUsed: revealedHints.size,
        timeSpent: elapsedTime,
      };

      setAttempts((prev) => [...prev, attempt]);

      // Update feedback
      setFeedback({
        type: result.isCorrect ? 'correct' : 'incorrect',
        message: result.message ?? (result.isCorrect ? 'Great job!' : 'Not quite right.'),
        points: result.points,
        ...(result.explanation && { explanation: result.explanation }),
      });

      // Update points from API response (L-04)
      if (result.isCorrect) {
        setEarnedPoints((prev) => prev + result.points);
        if (onComplete) {
          onComplete(attempt);
        }
      }
    } catch (error) {
      toast({
        title: 'Error al enviar respuesta',
        description: error instanceof Error ? error.message : 'Error desconocido',
        variant: 'destructive',
      });
      setFeedback({
        type: 'error',
        message: 'Failed to submit answer. Please try again.',
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  // Handle try again
  const handleTryAgain = () => {
    setFeedback(null);
    setAnswer('');
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  // Handle hint reveal - use exercise max points as hint budget
  const handleRevealHint = (index: number, cost: number) => {
    const remainingPoints = exercise.points - revealedHints.size * cost;
    if (remainingPoints >= cost && !revealedHints.has(index)) {
      setRevealedHints((prev) => new Set(prev).add(index));
    }
  };

  // Fetch solution from API (L-06) - SECURITY: Validar y sanitizar
  const fetchSolution = async () => {
    if (solution) return; // Already fetched
    setIsLoadingSolution(true);
    try {
      const data = await api.get<{
        correctAnswer: string;
        solutionSteps: Array<{
          step: string;
          explanation?: string;
          latexFormula?: string;
        }>;
        hasCompleted: boolean;
      }>(`/api/exercises/${exercise.id}/solution`);

      // SECURITY: Validar cada paso de la solución
      const validatedSteps = data.solutionSteps.map((step, index) => {
        // Validar latexFormula si existe
        if (step.latexFormula) {
          const validation = validateFormula(step.latexFormula);
          if (!validation.isValid) {
            console.warn(`SECURITY: Paso ${index + 1} contiene fórmula inválida`, validation.error);
            return {
              id: `step-${index + 1}`,
              title: step.step,
              content: `⚠️ Fórmula bloqueada por seguridad: ${validation.error}`,
              isMath: false,
              ...(step.explanation && { explanation: escapeHtml(step.explanation) }),
            };
          }
        }

        return {
          id: `step-${index + 1}`,
          title: escapeHtml(step.step),
          content: step.latexFormula ?? escapeHtml(step.explanation ?? ''),
          isMath: !!step.latexFormula,
          ...(step.explanation && { explanation: escapeHtml(step.explanation) }),
        };
      });

      const fetchedSolution: Solution = {
        id: `${exercise.id}-solution`,
        title: `Solution to ${escapeHtml(exercise.title)}`,
        steps: validatedSteps,
        finalAnswer: escapeHtml(data.correctAnswer),
        summary: 'This solution walks through the process step by step.',
      };
      setSolution(fetchedSolution);
    } catch (error) {
      toast({
        title: 'Error al cargar solución',
        description: error instanceof Error ? error.message : 'No se pudo cargar la solución',
        variant: 'destructive',
      });
    } finally {
      setIsLoadingSolution(false);
    }
  };

  // Handle show solution click
  const handleShowSolution = () => {
    void fetchSolution();
    setShowSolution(true);
  };

  // Convert hints to Hint format
  const hints: Hint[] = exercise.hints.map((content, index) => ({
    id: `${exercise.id}-hint-${index}`,
    content,
    isMath: content.includes('\\') || content.includes('$'),
  }));

  const isDisabled = !!feedback && (feedback.type === 'correct' || showSolution);

  return (
    <div className={cn('space-y-6', className)}>
      {/* Exercise Header */}
      <div className="animate-in fade-in slide-in-from-top-4 duration-300">
        <Card>
          <CardHeader>
            <div className="flex items-start justify-between gap-4">
              <div className="flex-1">
                <CardTitle className="text-2xl">{exercise.title}</CardTitle>
                <CardDescription className="mt-1">{exercise.description}</CardDescription>
              </div>

              {/* Points and Timer */}
              <div className="flex items-center gap-4">
                {enableTimer && !isDisabled && (
                  <div className="flex items-center gap-2 text-sm">
                    <Clock className="h-4 w-4 text-muted-foreground" />
                    <span className="font-mono font-medium">{formatTime(elapsedTime)}</span>
                  </div>
                )}

                <div className="flex items-center gap-2 text-sm">
                  <Target className="h-4 w-4 text-muted-foreground" />
                  <span className="font-medium">{earnedPoints > 0 ? `${earnedPoints} pts` : `${exercise.points} pts max`}</span>
                </div>
              </div>
            </div>
          </CardHeader>

          <CardContent className="space-y-4">
            {/* Question */}
            <div className="bg-muted/50 rounded-lg p-6 border">
              <p className="text-sm text-muted-foreground mb-3">Solve:</p>
              <MathBlock formula={exercise.question} />
            </div>

            {/* Progress Bar (for attempts) */}
            {attempts.length > 0 && (
              <div className="space-y-2">
                <div className="flex items-center justify-between text-sm text-muted-foreground">
                  <span>Attempts: {attempts.length}</span>
                  <span className="flex items-center gap-1">
                    {attempts.filter((a) => a.isCorrect).length > 0 ? (
                      <CheckCircle2 className="h-4 w-4 text-green-600" />
                    ) : (
                      <XCircle className="h-4 w-4 text-red-600" />
                    )}
                    {attempts.filter((a) => a.isCorrect).length > 0 ? 'Solved!' : 'Keep trying!'}
                  </span>
                </div>
                <Progress
                  value={(attempts.filter((a) => a.isCorrect).length / Math.max(attempts.length, 1)) * 100}
                  className="h-2"
                />
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Main Solver Interface */}
      {!showSolution ? (
        <div className="grid gap-6 lg:grid-cols-2 animate-in fade-in duration-300">
            {/* Left Column - Input and Feedback */}
            <div className="space-y-6">
              {/* Answer Input */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">Your Answer</CardTitle>
                </CardHeader>
                <CardContent>
                  <AnswerInput
                    ref={inputRef}
                    value={answer}
                    onChange={setAnswer}
                    onSubmit={() => void handleSubmit()}
                    disabled={isDisabled || isSubmitting}
                    isCorrect={feedback?.type === 'correct'}
                    isIncorrect={feedback?.type === 'incorrect'}
                    showValidation={!!feedback}
                  />
                </CardContent>
              </Card>

              {/* Feedback */}
              <ExerciseFeedback
                feedback={feedback}
                onTryAgain={handleTryAgain}
                {...(showSolutionButton && { onShowSolution: handleShowSolution })}
              />

              {/* Actions */}
              {onSkip && !feedback && (
                <div className="flex justify-center">
                  <Button variant="outline" onClick={onSkip} className="gap-2">
                    Skip Exercise
                  </Button>
                </div>
              )}
            </div>

            {/* Right Column - Hints and Info */}
            <div className="space-y-6">
              {/* Hints */}
              {enableHints && hints.length > 0 && (
                <HintSystem
                  hints={hints}
                  currentPoints={exercise.points}
                  pointsPerHint={5}
                  revealedHints={revealedHints}
                  onRevealHint={handleRevealHint}
                />
              )}

              {/* Exercise Info */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">Exercise Info</CardTitle>
                </CardHeader>
                <CardContent className="space-y-3 text-sm">
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Difficulty:</span>
                    <span className="font-medium capitalize">{exercise.difficulty}</span>
                  </div>
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Max Points:</span>
                    <span className="font-medium">{exercise.points} pts</span>
                  </div>
                  {exercise.timeLimit && (
                    <div className="flex justify-between">
                      <span className="text-muted-foreground">Time Limit:</span>
                      <span className="font-medium">{formatTime(exercise.timeLimit)}</span>
                    </div>
                  )}
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Hints Available:</span>
                    <span className="font-medium">{hints.length}</span>
                  </div>
                  {revealedHints.size > 0 && (
                    <div className="flex justify-between">
                      <span className="text-muted-foreground">Hints Used:</span>
                      <span className="font-medium">{revealedHints.size}</span>
                    </div>
                  )}
                </CardContent>
              </Card>
            </div>
          </div>
        ) : (
          /* Solution View */
          <div className="animate-in fade-in duration-300">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2 text-lg font-semibold">
                <BookOpen className="h-5 w-5" />
                <span>Solution</span>
              </div>
              <Button variant="outline" onClick={() => setShowSolution(false)}>
                Back to Exercise
              </Button>
            </div>

            {isLoadingSolution ? (
              <Card>
                <CardContent className="space-y-4 py-6">
                  <Skeleton className="h-6 w-1/4" />
                  <Skeleton className="h-4 w-full" />
                  <Skeleton className="h-4 w-3/4" />
                  <Skeleton className="h-20 w-full" />
                  <Skeleton className="h-4 w-full" />
                  <Skeleton className="h-4 w-2/3" />
                </CardContent>
              </Card>
            ) : solution ? (
              <StepByStepSolution solution={solution} />
            ) : (
              <div className="text-center py-12 text-muted-foreground">
                <p>Unable to load solution. Please try again.</p>
              </div>
            )}
          </div>
        )}
    </div>
  );
}

/**
 * ExerciseSolver wrapper for completing exercises
 */
export interface ExerciseSolverWrapperProps {
  exerciseId: string;
  onComplete?: (attempt: ExerciseAttempt) => void;
  onSkip?: () => void;
  className?: string;
}

export function ExerciseSolverWrapper({
  exerciseId,
  onComplete,
  onSkip,
  className,
}: ExerciseSolverWrapperProps) {
  const [exercise, setExercise] = useState<Exercise | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const { toast } = useToast();

  useEffect(() => {
    const fetchExercise = async () => {
      try {
        setLoading(true);
        const data = await api.get<Exercise>(`/api/exercises/${exerciseId}`);
        setExercise(data);
      } catch (err) {
        toast({
          title: 'Error al cargar ejercicio',
          description: err instanceof Error ? err.message : 'No se pudo cargar el ejercicio',
          variant: 'destructive',
        });
        setError('Failed to load exercise');
      } finally {
        setLoading(false);
      }
    };

    void fetchExercise();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [exerciseId]);

  if (loading) {
    return (
      <div className={cn('space-y-6', className)}>
        {/* Exercise Header Skeleton */}
        <Card>
          <CardHeader>
            <div className="flex items-start justify-between gap-4">
              <div className="flex-1 space-y-3">
                <Skeleton className="h-7 w-3/4" />
                <Skeleton className="h-4 w-full" />
              </div>
              <div className="flex items-center gap-4">
                <Skeleton className="h-4 w-16" />
                <Skeleton className="h-4 w-20" />
              </div>
            </div>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* Question Skeleton */}
            <div className="bg-muted/50 rounded-lg p-6 border">
              <Skeleton className="h-4 w-16 mb-3" />
              <Skeleton className="h-6 w-full mb-2" />
              <Skeleton className="h-6 w-3/4" />
            </div>
          </CardContent>
        </Card>

        {/* Main Solver Interface Skeleton */}
        <div className="grid gap-6 lg:grid-cols-2">
          {/* Left Column - Input Skeleton */}
          <div className="space-y-6">
            <Card>
              <CardHeader>
                <Skeleton className="h-5 w-24" />
              </CardHeader>
              <CardContent>
                <Skeleton className="h-12 w-full" />
                <Skeleton className="h-10 w-full mt-4" />
              </CardContent>
            </Card>

            <Card>
              <CardHeader>
                <Skeleton className="h-5 w-24" />
              </CardHeader>
              <CardContent className="space-y-2">
                <Skeleton className="h-4 w-full" />
                <Skeleton className="h-10 w-32" />
              </CardContent>
            </Card>
          </div>

          {/* Right Column - Hints and Info Skeleton */}
          <div className="space-y-6">
            <Card>
              <CardHeader>
                <Skeleton className="h-5 w-20" />
              </CardHeader>
              <CardContent className="space-y-3">
                <Skeleton className="h-4 w-full" />
                <Skeleton className="h-4 w-full" />
                <Skeleton className="h-4 w-3/4" />
              </CardContent>
            </Card>

            <Card>
              <CardHeader>
                <Skeleton className="h-5 w-24" />
              </CardHeader>
              <CardContent className="space-y-3">
                <div className="flex justify-between">
                  <Skeleton className="h-4 w-16" />
                  <Skeleton className="h-4 w-20" />
                </div>
                <div className="flex justify-between">
                  <Skeleton className="h-4 w-16" />
                  <Skeleton className="h-4 w-12" />
                </div>
                <div className="flex justify-between">
                  <Skeleton className="h-4 w-20" />
                  <Skeleton className="h-4 w-8" />
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      </div>
    );
  }

  if (error || !exercise) {
    return (
      <Card className={className}>
        <CardContent className="flex items-center justify-center py-12">
          <div className="text-center text-destructive">
            <XCircle className="h-12 w-12 mx-auto mb-4" />
            <p className="font-medium">{error ?? 'Exercise not found'}</p>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <ExerciseSolver
      exercise={exercise}
      {...(onComplete && { onComplete })}
      {...(onSkip && { onSkip })}
      {...(className && { className })}
    />
  );
}
