'use client';

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '../../lib/utils';
import { motion, AnimatePresence } from 'framer-motion';
import { 
  Clock, 
  CheckCircle2, 
  XCircle, 
  AlertCircle, 
  ChevronRight, 
  ChevronLeft,
  Download,
  Share2,
  RotateCcw,
  Eye,
  EyeOff,
  HelpCircle,
  Star
} from 'lucide-react';

const quizFormVariants = cva(
  'relative w-full rounded-lg border bg-card text-card-foreground shadow-sm',
  {
    variants: {
      variant: {
        default: 'border-border',
        exam: 'border-primary/20 bg-primary/5',
        personality: 'border-secondary/20 bg-secondary/5',
      },
      size: {
        sm: 'p-4',
        md: 'p-6',
        lg: 'p-8',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'md',
    },
  }
);

// Soru tipleri
export type QuestionType = 
  | 'single-choice' 
  | 'multiple-choice' 
  | 'text' 
  | 'rating' 
  | 'true-false' 
  | 'matching';

// Soru interface'i
export interface Question {
  id: string;
  type: QuestionType;
  question: string;
  options?: string[];
  correctAnswer?: string | string[] | Record<string, string>;
  points?: number;
  hint?: string;
  explanation?: string;
  required?: boolean;
  // Matching için
  leftOptions?: string[];
  rightOptions?: string[];
  // Rating için
  maxRating?: number;
  ratingLabels?: string[];
}

// Quiz ayarları
export interface QuizSettings {
  shuffleQuestions?: boolean;
  shuffleOptions?: boolean;
  showInstantFeedback?: boolean;
  showHints?: boolean;
  allowReview?: boolean;
  timeLimit?: number; // dakika cinsinden
  passingScore?: number; // yüzde cinsinden
  maxAttempts?: number;
}

// Kullanıcı cevabı
export interface UserAnswer {
  questionId: string;
  answer: string | string[] | Record<string, string> | null;
  timeSpent?: number;
}

// Quiz sonucu
export interface QuizResult {
  score: number;
  totalScore: number;
  percentage: number;
  passed?: boolean;
  answers: Array<{
    questionId: string;
    userAnswer: any;
    correctAnswer: any;
    isCorrect: boolean;
    points: number;
  }>;
  timeSpent?: number;
  completedAt: Date;
}

export interface MoonUIQuizFormProProps
  extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onProgress'>,
    VariantProps<typeof quizFormVariants> {
  questions: Question[];
  settings?: QuizSettings;
  onComplete?: (result: QuizResult) => void;
  onProgress?: (current: number, total: number) => void;
  title?: string;
  description?: string;
}

export const MoonUIQuizFormPro = React.forwardRef<
  HTMLDivElement,
  MoonUIQuizFormProProps
>(({ 
  className, 
  variant, 
  size, 
  questions: initialQuestions,
  settings = {},
  onComplete,
  onProgress,
  title,
  description,
  ...props 
}, ref) => {
  // State'ler
  const [questions, setQuestions] = useState<Question[]>([]);
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const [userAnswers, setUserAnswers] = useState<Record<string, UserAnswer>>({});
  const [showResults, setShowResults] = useState(false);
  const [quizResult, setQuizResult] = useState<QuizResult | null>(null);
  const [timeLeft, setTimeLeft] = useState<number | null>(
    settings.timeLimit ? settings.timeLimit * 60 : null
  );
  const [questionStartTime, setQuestionStartTime] = useState<number>(Date.now());
  const [showHint, setShowHint] = useState(false);
  const [attempts, setAttempts] = useState(0);

  // Soruları hazırla (shuffle vs.)
  useEffect(() => {
    let processedQuestions = [...initialQuestions];
    
    // Soruları karıştır
    if (settings.shuffleQuestions) {
      processedQuestions = shuffleArray(processedQuestions);
    }
    
    // Seçenekleri karıştır
    if (settings.shuffleOptions) {
      processedQuestions = processedQuestions.map(q => {
        if (q.options) {
          return { ...q, options: shuffleArray([...q.options]) };
        }
        return q;
      });
    }
    
    setQuestions(processedQuestions);
  }, [initialQuestions, settings.shuffleQuestions, settings.shuffleOptions]);

  // Timer
  useEffect(() => {
    if (timeLeft === null || timeLeft <= 0 || showResults) return;

    const timer = setInterval(() => {
      setTimeLeft(prev => {
        if (prev === null || prev <= 1) {
          handleComplete();
          return 0;
        }
        return prev - 1;
      });
    }, 1000);

    return () => clearInterval(timer);
  }, [timeLeft, showResults]);

  // Progress callback
  useEffect(() => {
    if (onProgress) {
      onProgress(currentQuestionIndex + 1, questions.length);
    }
  }, [currentQuestionIndex, questions.length, onProgress]);

  // Mevcut soru
  const currentQuestion = questions[currentQuestionIndex];

  // Array'i karıştır
  const shuffleArray = <T,>(array: T[]): T[] => {
    const newArray = [...array];
    for (let i = newArray.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
    }
    return newArray;
  };

  // Cevabı kaydet
  const saveAnswer = (answer: any) => {
    const timeSpent = Date.now() - questionStartTime;
    setUserAnswers(prev => ({
      ...prev,
      [currentQuestion.id]: {
        questionId: currentQuestion.id,
        answer,
        timeSpent,
      },
    }));
  };

  // Sonraki soruya geç
  const handleNext = () => {
    if (currentQuestionIndex < questions.length - 1) {
      setCurrentQuestionIndex(prev => prev + 1);
      setQuestionStartTime(Date.now());
      setShowHint(false);
    } else {
      handleComplete();
    }
  };

  // Önceki soruya dön
  const handlePrevious = () => {
    if (currentQuestionIndex > 0) {
      setCurrentQuestionIndex(prev => prev - 1);
      setShowHint(false);
    }
  };

  // Quiz'i tamamla
  const handleComplete = () => {
    const result = calculateResult();
    setQuizResult(result);
    setShowResults(true);
    setAttempts(prev => prev + 1);
    
    if (onComplete) {
      onComplete(result);
    }
  };

  // Sonucu hesapla
  const calculateResult = (): QuizResult => {
    let totalScore = 0;
    let userScore = 0;
    const answers: QuizResult['answers'] = [];

    questions.forEach(question => {
      const userAnswer = userAnswers[question.id];
      const points = question.points || 1;
      totalScore += points;

      let isCorrect = false;
      
      if (userAnswer?.answer && question.correctAnswer !== undefined) {
        switch (question.type) {
          case 'single-choice':
          case 'true-false':
          case 'text':
            isCorrect = userAnswer.answer === question.correctAnswer;
            break;
          
          case 'multiple-choice':
            if (Array.isArray(userAnswer.answer) && Array.isArray(question.correctAnswer)) {
              isCorrect = 
                userAnswer.answer.length === question.correctAnswer.length &&
                userAnswer.answer.every(a => (question.correctAnswer as string[]).includes(a));
            }
            break;
          
          case 'matching':
            if (typeof userAnswer.answer === 'object' && typeof question.correctAnswer === 'object') {
              const correct = question.correctAnswer as Record<string, string>;
              const user = userAnswer.answer as Record<string, string>;
              isCorrect = Object.keys(correct).every(key => correct[key] === user[key]);
            }
            break;
          
          case 'rating':
            // Rating'de doğru/yanlış yok
            isCorrect = true;
            break;
        }
      }

      if (isCorrect) {
        userScore += points;
      }

      answers.push({
        questionId: question.id,
        userAnswer: userAnswer?.answer || null,
        correctAnswer: question.correctAnswer,
        isCorrect,
        points: isCorrect ? points : 0,
      });
    });

    const percentage = totalScore > 0 ? (userScore / totalScore) * 100 : 0;
    const totalTimeSpent = Object.values(userAnswers).reduce(
      (sum, answer) => sum + (answer.timeSpent || 0), 
      0
    );

    return {
      score: userScore,
      totalScore,
      percentage,
      passed: settings.passingScore ? percentage >= settings.passingScore : undefined,
      answers,
      timeSpent: totalTimeSpent,
      completedAt: new Date(),
    };
  };

  // Quiz'i yeniden başlat
  const handleRestart = () => {
    setCurrentQuestionIndex(0);
    setUserAnswers({});
    setShowResults(false);
    setQuizResult(null);
    setTimeLeft(settings.timeLimit ? settings.timeLimit * 60 : null);
    setQuestionStartTime(Date.now());
    setShowHint(false);
    
    // Soruları yeniden karıştır
    if (settings.shuffleQuestions) {
      setQuestions(shuffleArray([...initialQuestions]));
    }
  };

  // Sonuçları indir
  const handleDownloadResults = () => {
    if (!quizResult) return;

    const data = {
      title,
      completedAt: quizResult.completedAt,
      score: quizResult.score,
      totalScore: quizResult.totalScore,
      percentage: quizResult.percentage,
      passed: quizResult.passed,
      timeSpent: quizResult.timeSpent,
      answers: quizResult.answers.map(a => {
        const question = questions.find(q => q.id === a.questionId);
        return {
          question: question?.question,
          userAnswer: a.userAnswer,
          correctAnswer: a.correctAnswer,
          isCorrect: a.isCorrect,
          points: a.points,
        };
      }),
    };

    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `quiz-results-${Date.now()}.json`;
    link.click();
    URL.revokeObjectURL(url);
  };

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

  // Render question
  const renderQuestion = () => {
    if (!currentQuestion) return null;

    const userAnswer = userAnswers[currentQuestion.id]?.answer;

    switch (currentQuestion.type) {
      case 'single-choice':
      case 'true-false':
        return (
          <div className="space-y-3">
            {currentQuestion.options?.map((option, index) => (
              <motion.button
                key={index}
                initial={{ opacity: 0, x: -20 }}
                animate={{ opacity: 1, x: 0 }}
                transition={{ delay: index * 0.1 }}
                onClick={() => saveAnswer(option)}
                className={cn(
                  'w-full text-left p-4 rounded-lg border transition-colors',
                  userAnswer === option
                    ? 'border-primary bg-primary/10'
                    : 'border-border hover:border-primary/50'
                )}
              >
                {option}
              </motion.button>
            ))}
          </div>
        );

      case 'multiple-choice':
        return (
          <div className="space-y-3">
            {currentQuestion.options?.map((option, index) => {
              const selected = Array.isArray(userAnswer) && userAnswer.includes(option);
              return (
                <motion.button
                  key={index}
                  initial={{ opacity: 0, x: -20 }}
                  animate={{ opacity: 1, x: 0 }}
                  transition={{ delay: index * 0.1 }}
                  onClick={() => {
                    const current = (userAnswer || []) as string[];
                    const newAnswer = selected
                      ? current.filter(a => a !== option)
                      : [...current, option];
                    saveAnswer(newAnswer);
                  }}
                  className={cn(
                    'w-full text-left p-4 rounded-lg border transition-colors',
                    selected
                      ? 'border-primary bg-primary/10'
                      : 'border-border hover:border-primary/50'
                  )}
                >
                  <div className="flex items-center gap-3">
                    <div className={cn(
                      'w-5 h-5 rounded border-2 transition-colors',
                      selected ? 'bg-primary border-primary' : 'border-border'
                    )}>
                      {selected && (
                        <CheckCircle2 className="w-full h-full text-primary-foreground" />
                      )}
                    </div>
                    {option}
                  </div>
                </motion.button>
              );
            })}
          </div>
        );

      case 'text':
        return (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
          >
            <textarea
              className="w-full p-4 rounded-lg border border-input bg-background resize-none"
              rows={4}
              placeholder="Type your answer here..."
              value={(userAnswer as string) || ''}
              onChange={(e) => saveAnswer(e.target.value)}
            />
          </motion.div>
        );

      case 'rating':
        const maxRating = currentQuestion.maxRating || 5;
        const currentRating = (typeof userAnswer === 'number' ? userAnswer : 0);
        
        return (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            className="space-y-4"
          >
            <div className="flex justify-center gap-2">
              {Array.from({ length: maxRating }, (_, i) => i + 1).map((rating) => (
                <button
                  key={rating}
                  onClick={() => saveAnswer(rating)}
                  className="transition-transform hover:scale-110"
                >
                  <Star
                    className={cn(
                      'w-10 h-10 transition-colors',
                      rating <= currentRating
                        ? 'fill-yellow-500 text-yellow-500'
                        : 'text-muted-foreground'
                    )}
                  />
                </button>
              ))}
            </div>
            {currentQuestion.ratingLabels && (
              <div className="flex justify-between text-sm text-muted-foreground">
                <span>{currentQuestion.ratingLabels[0]}</span>
                <span>{currentQuestion.ratingLabels[1]}</span>
              </div>
            )}
          </motion.div>
        );

      case 'matching':
        const matches = (userAnswer || {}) as Record<string, string>;
        
        return (
          <div className="grid grid-cols-2 gap-6">
            <div className="space-y-3">
              <h4 className="font-medium mb-2">Match these items:</h4>
              {currentQuestion.leftOptions?.map((left, index) => (
                <motion.div
                  key={left}
                  initial={{ opacity: 0, x: -20 }}
                  animate={{ opacity: 1, x: 0 }}
                  transition={{ delay: index * 0.1 }}
                  className="p-3 rounded-lg border bg-muted/50"
                >
                  {left}
                </motion.div>
              ))}
            </div>
            
            <div className="space-y-3">
              <h4 className="font-medium mb-2">With these:</h4>
              {currentQuestion.leftOptions?.map((left) => (
                <motion.div
                  key={left}
                  initial={{ opacity: 0, x: 20 }}
                  animate={{ opacity: 1, x: 0 }}
                >
                  <select
                    className="w-full p-3 rounded-lg border bg-background"
                    value={matches[left] || ''}
                    onChange={(e) => saveAnswer({ ...matches, [left]: e.target.value })}
                  >
                    <option value="">Select...</option>
                    {currentQuestion.rightOptions?.map((right) => (
                      <option key={right} value={right}>
                        {right}
                      </option>
                    ))}
                  </select>
                </motion.div>
              ))}
            </div>
          </div>
        );

      default:
        return null;
    }
  };

  // Sonuçları göster
  if (showResults && quizResult) {
    return (
      <div ref={ref} className={cn(quizFormVariants({ variant, size }), className)} {...props}>
        <motion.div
          initial={{ opacity: 0, scale: 0.95 }}
          animate={{ opacity: 1, scale: 1 }}
          className="space-y-6"
        >
          <div className="text-center">
            <h2 className="text-2xl font-bold mb-2">Quiz Completed!</h2>
            <div className="text-5xl font-bold mb-4">
              {quizResult.percentage.toFixed(1)}%
            </div>
            <p className="text-muted-foreground">
              You scored {quizResult.score} out of {quizResult.totalScore} points
            </p>
            {quizResult.passed !== undefined && (
              <div className={cn(
                'mt-4 inline-flex items-center gap-2 px-4 py-2 rounded-full',
                quizResult.passed ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'
              )}>
                {quizResult.passed ? (
                  <>
                    <CheckCircle2 className="w-5 h-5" />
                    Passed
                  </>
                ) : (
                  <>
                    <XCircle className="w-5 h-5" />
                    Failed
                  </>
                )}
              </div>
            )}
          </div>

          {settings.allowReview && (
            <div className="space-y-4">
              <h3 className="font-semibold">Review Answers:</h3>
              {quizResult.answers.map((answer, index) => {
                const question = questions.find(q => q.id === answer.questionId);
                if (!question) return null;
                
                return (
                  <div key={answer.questionId} className="p-4 rounded-lg border bg-muted/50">
                    <div className="flex items-start gap-3">
                      {answer.isCorrect ? (
                        <CheckCircle2 className="w-5 h-5 text-green-600 mt-0.5" />
                      ) : (
                        <XCircle className="w-5 h-5 text-red-600 mt-0.5" />
                      )}
                      <div className="flex-1">
                        <p className="font-medium mb-2">
                          {index + 1}. {question.question}
                        </p>
                        <p className="text-sm text-muted-foreground">
                          Your answer: {JSON.stringify(answer.userAnswer)}
                        </p>
                        {!answer.isCorrect && question.correctAnswer !== undefined && (
                          <p className="text-sm text-green-600 mt-1">
                            Correct answer: {JSON.stringify(question.correctAnswer)}
                          </p>
                        )}
                        {question.explanation && (
                          <p className="text-sm text-muted-foreground mt-2">
                            {question.explanation}
                          </p>
                        )}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}

          <div className="flex gap-3 justify-center">
            {(!settings.maxAttempts || attempts < settings.maxAttempts) && (
              <button
                onClick={handleRestart}
                className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90"
              >
                <RotateCcw className="w-4 h-4" />
                Try Again
              </button>
            )}
            <button
              onClick={handleDownloadResults}
              className="inline-flex items-center gap-2 px-4 py-2 rounded-lg border hover:bg-muted"
            >
              <Download className="w-4 h-4" />
              Download Results
            </button>
          </div>
        </motion.div>
      </div>
    );
  }

  return (
    <div ref={ref} className={cn(quizFormVariants({ variant, size }), className)} {...props}>
      {/* Header */}
      {(title || timeLeft !== null) && (
        <div className="mb-6 flex items-center justify-between">
          <div>
            {title && <h2 className="text-2xl font-bold">{title}</h2>}
            {description && <p className="text-muted-foreground mt-1">{description}</p>}
          </div>
          {timeLeft !== null && (
            <div className={cn(
              'flex items-center gap-2 px-3 py-1 rounded-full text-sm font-medium',
              timeLeft < 60 ? 'bg-red-100 text-red-700' : 'bg-muted'
            )}>
              <Clock className="w-4 h-4" />
              {formatTime(timeLeft)}
            </div>
          )}
        </div>
      )}

      {/* Progress bar */}
      <div className="mb-6">
        <div className="flex items-center justify-between text-sm text-muted-foreground mb-2">
          <span>Question {currentQuestionIndex + 1} of {questions.length}</span>
          <span>{Math.round(((currentQuestionIndex + 1) / questions.length) * 100)}%</span>
        </div>
        <div className="h-2 bg-muted rounded-full overflow-hidden">
          <motion.div
            className="h-full bg-primary"
            initial={{ width: 0 }}
            animate={{ width: `${((currentQuestionIndex + 1) / questions.length) * 100}%` }}
            transition={{ duration: 0.3 }}
          />
        </div>
      </div>

      {/* Question */}
      <AnimatePresence mode="wait">
        {currentQuestion && (
          <motion.div
            key={currentQuestion.id}
            initial={{ opacity: 0, x: 20 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: -20 }}
            className="mb-6"
          >
            <h3 className="text-lg font-semibold mb-4">
              {currentQuestion.question}
              {currentQuestion.required && (
                <span className="text-red-500 ml-1">*</span>
              )}
            </h3>
            
            {renderQuestion()}

            {/* Hint */}
            {settings.showHints && currentQuestion.hint && (
              <div className="mt-4">
                <button
                  onClick={() => setShowHint(!showHint)}
                  className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
                >
                  <HelpCircle className="w-4 h-4" />
                  {showHint ? 'Hide' : 'Show'} Hint
                </button>
                {showHint && (
                  <motion.div
                    initial={{ opacity: 0, height: 0 }}
                    animate={{ opacity: 1, height: 'auto' }}
                    className="mt-2 p-3 rounded-lg bg-muted/50 text-sm"
                  >
                    {currentQuestion.hint}
                  </motion.div>
                )}
              </div>
            )}

            {/* Instant feedback */}
            {settings.showInstantFeedback && userAnswers[currentQuestion.id] && currentQuestion.correctAnswer !== undefined && (
              <motion.div
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                className="mt-4"
              >
                {(() => {
                  const userAnswer = userAnswers[currentQuestion.id].answer;
                  let isCorrect = false;
                  
                  // Doğruluğu kontrol et
                  switch (currentQuestion.type) {
                    case 'single-choice':
                    case 'true-false':
                      isCorrect = userAnswer === currentQuestion.correctAnswer;
                      break;
                    // Diğer tipler için kontrol eklenebilir
                  }
                  
                  return (
                    <div className={cn(
                      'p-3 rounded-lg flex items-start gap-2',
                      isCorrect ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'
                    )}>
                      {isCorrect ? (
                        <CheckCircle2 className="w-5 h-5 mt-0.5" />
                      ) : (
                        <XCircle className="w-5 h-5 mt-0.5" />
                      )}
                      <div>
                        <p className="font-medium">{isCorrect ? 'Correct!' : 'Incorrect'}</p>
                        {currentQuestion.explanation && (
                          <p className="text-sm mt-1">{currentQuestion.explanation}</p>
                        )}
                      </div>
                    </div>
                  );
                })()}
              </motion.div>
            )}
          </motion.div>
        )}
      </AnimatePresence>

      {/* Navigation */}
      <div className="flex items-center justify-between">
        <button
          onClick={handlePrevious}
          disabled={currentQuestionIndex === 0}
          className={cn(
            'inline-flex items-center gap-2 px-4 py-2 rounded-lg transition-colors',
            currentQuestionIndex === 0
              ? 'opacity-50 cursor-not-allowed bg-muted text-muted-foreground'
              : 'bg-muted hover:bg-muted/80'
          )}
        >
          <ChevronLeft className="w-4 h-4" />
          Previous
        </button>

        <button
          onClick={currentQuestionIndex === questions.length - 1 ? handleComplete : handleNext}
          disabled={currentQuestion?.required && !userAnswers[currentQuestion.id]}
          className={cn(
            'inline-flex items-center gap-2 px-4 py-2 rounded-lg transition-colors',
            currentQuestion?.required && !userAnswers[currentQuestion.id]
              ? 'opacity-50 cursor-not-allowed bg-muted text-muted-foreground'
              : 'bg-primary text-primary-foreground hover:bg-primary/90'
          )}
        >
          {currentQuestionIndex === questions.length - 1 ? 'Complete' : 'Next'}
          <ChevronRight className="w-4 h-4" />
        </button>
      </div>
    </div>
  );
});

MoonUIQuizFormPro.displayName = 'MoonUIQuizFormPro';

export default MoonUIQuizFormPro;