
"use client";

import type { ChangeEvent } from 'react';
import { useState, useEffect, useRef, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Skeleton } from '@/components/ui/skeleton';
import { generateMCQ, type GenerateMCQOutput } from '@/ai/flows/generate-mcq';
import { explainIncorrectAnswer } from '@/ai/flows/explain-incorrect-answer-flow';
import { explainCorrectAnswer } from '@/ai/flows/explain-correct-answer-flow';
import type { ChatMessage as ChatMessageType, ActiveMCQ } from '@/types';
import { ChatMessage } from './chat-message';
import { useToast } from '@/hooks/use-toast';
import { Send, FileText, Loader2 } from 'lucide-react';

const MAX_QUESTIONS = 5;

interface ChatbotProps {
  imageDataUri: string | null;
  journeyTitle: string;
  journeyId: string;
}

export function Chatbot({ imageDataUri, journeyTitle, journeyId }: ChatbotProps) {
  const router = useRouter();
  const [messages, setMessages] = useState<ChatMessageType[]>([]);
  const [currentMCQ, setCurrentMCQ] = useState<ActiveMCQ | null>(null);
  const [isLoading, setIsLoading] = useState(false); // General loading for AI responses
  const [isAwaitingAnswer, setIsAwaitingAnswer] = useState(false);
  const [hasAnsweredCorrectly, setHasAnsweredCorrectly] = useState(false);
  const [incorrectAttempts, setIncorrectAttempts] = useState<string[]>([]);
  const [questionCount, setQuestionCount] = useState(0);
  const scrollAreaRef = useRef<HTMLDivElement>(null);
  const { toast } = useToast();
  const messageIdCounter = useRef(0);
  const isInitialQuestionRef = useRef(true);

  const addMessage = useCallback((message: Omit<ChatMessageType, 'id' | 'timestamp'>) => {
    messageIdCounter.current += 1;
    const newId = `${Date.now()}-${messageIdCounter.current}`;
    setMessages(prev => [...prev, { ...message, id: newId, timestamp: new Date() }]);
  }, []);


  useEffect(() => {
    let ignore = false;

    // Comprehensive reset for new journey/image
    setMessages([]);
    setCurrentMCQ(null);
    setIsLoading(false);
    setIsAwaitingAnswer(false);
    setHasAnsweredCorrectly(false);
    setIncorrectAttempts([]);
    setQuestionCount(0);
    isInitialQuestionRef.current = true;
    messageIdCounter.current = 0;

    const performInitialFetch = async () => {
      if (!imageDataUri) {
        // This case should ideally be handled by parent not rendering Chatbot,
        // or showing a "waiting for image" state if Chatbot is rendered before URI is ready.
        if (!ignore && messages.length === 0) {
          // Add a temporary "preparing" message if no URI yet, but this will be cleared.
          addMessage({ sender: 'ai', type: 'text', text: "Preparing your journey..." });
        }
        return;
      }

      if (!ignore) setIsLoading(true);

      try {
        // Clear any "Preparing..." message before fetching the actual question
        if (messages.length === 1 && messages[0].text === "Preparing your journey...") {
            setMessages([]);
        }

        const mcqResult = await generateMCQ({ imageDataUri });

        if (ignore) return;

        let activeMcqData: ActiveMCQ = {
          ...mcqResult,
          originalQuestionTextForFlow: mcqResult.mcq,
        };
        
        if (isInitialQuestionRef.current) {
          activeMcqData.mcq = `Okay, let's start with ${journeyTitle}! ${mcqResult.mcq}`;
          isInitialQuestionRef.current = false;
        }
        
        if (ignore) return;

        setCurrentMCQ(activeMcqData);
        addMessage({ sender: 'ai', type: 'mcq', mcq: activeMcqData });
        setIsAwaitingAnswer(true);

      } catch (error) {
        if (ignore) return;
        console.error("Error generating initial MCQ:", error);
        const errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
        addMessage({ sender: 'ai', type: 'error', text: `Failed to generate initial question: ${errorMessage}` });
        toast({
          title: "Error",
          description: `Could not generate the first question. ${errorMessage}`,
          variant: "destructive",
        });
      } finally {
        if (!ignore) setIsLoading(false);
      }
    };
    
    // Trigger initial fetch if imageDataUri is present.
    // If imageDataUri is not present initially, this effect will re-run when it becomes available.
    if (imageDataUri) {
        performInitialFetch();
    } else if (messages.length === 0) { 
        // If there's no image URI and no messages, show "Preparing..."
        // This typically means the parent component is still loading the image.
        addMessage({ sender: 'ai', type: 'text', text: "Preparing your journey..." });
    }


    return () => {
      ignore = true; // Cleanup to prevent state updates on unmounted component
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [imageDataUri, journeyTitle]); // addMessage is memoized


  useEffect(() => {
    if (scrollAreaRef.current) {
      scrollAreaRef.current.scrollTo({ top: scrollAreaRef.current.scrollHeight, behavior: 'smooth' });
    }
  }, [messages]);

  const handleOptionSelect = async (option: string, isCorrect: boolean) => {
    if (!currentMCQ) return;

    setIsAwaitingAnswer(false); // User has made a selection

    addMessage({
      sender: 'user',
      type: 'user', // This type indicates it's the user's selected option text
      text: option,
    });

    setIsLoading(true);
    const questionForAI = currentMCQ.originalQuestionTextForFlow || currentMCQ.mcq;

    if (isCorrect) {
      let combinedMessage = "That's correct! Well done.";
      try {
        const explanationResult = await explainCorrectAnswer({
          question: questionForAI,
          options: currentMCQ.options,
          correctAnswer: currentMCQ.correctAnswer,
        });
        combinedMessage += ` ${explanationResult.explanation}`;
      } catch (error) {
        console.error("Error fetching correct answer explanation:", error);
        const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
        combinedMessage += ` (Sorry, I couldn't provide an explanation for that: ${errorMsg})`;
      }

      addMessage({ sender: 'ai', type: 'feedback', text: combinedMessage, isCorrect: true });
      setHasAnsweredCorrectly(true);
      setIncorrectAttempts([]);
      const newQuestionCount = questionCount + 1;
      setQuestionCount(newQuestionCount);
       if (newQuestionCount >= MAX_QUESTIONS) {
        addMessage({ sender: 'ai', type: 'text', text: "You've completed all 5 questions! Please proceed to the summary report." });
      }

    } else { // Incorrect answer
      const updatedIncorrectAttempts = [...incorrectAttempts, option];
      setIncorrectAttempts(updatedIncorrectAttempts);

      // Check if all incorrect options have been exhausted
      if (updatedIncorrectAttempts.length >= currentMCQ.options.length - 1) {
        let combinedText = "";
        try {
          // Explain why the *last chosen* option was incorrect
          const incorrectExplanationResult = await explainIncorrectAnswer({
            question: questionForAI,
            options: currentMCQ.options,
            selectedAnswer: option, 
            correctAnswer: currentMCQ.correctAnswer,
          });
          combinedText += `That's not quite right. ${incorrectExplanationResult.explanation} `;
        } catch (error) {
          console.error("Error fetching explanation for the last incorrect answer:", error);
           const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
           combinedText += `That's not quite right. (Failed to get explanation for your choice: ${errorMsg}) `;
        }
        
        combinedText += `The correct answer is "${currentMCQ.correctAnswer}". `;

        try {
          // Explain why the actual correct answer is correct
          const correctExplanationResult = await explainCorrectAnswer({
            question: questionForAI,
            options: currentMCQ.options,
            correctAnswer: currentMCQ.correctAnswer,
          });
          combinedText += correctExplanationResult.explanation;
        } catch (error) {
          console.error("Error fetching correct answer explanation after exhausting options:", error);
           const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
           combinedText += `(Failed to get explanation for the correct answer: ${errorMsg})`;
        }

        addMessage({
          sender: 'ai',
          type: 'feedback', // This will be handled by ChatMessage to not show options
          text: combinedText.trim(),
          isCorrect: true, // Mark as 'correct' flow-wise to enable next question/summary
        });
        setHasAnsweredCorrectly(true); // Allows "Next Question" or "Summary"
        setIncorrectAttempts([]);
        const newQuestionCount = questionCount + 1;
        setQuestionCount(newQuestionCount);
        if (newQuestionCount >= MAX_QUESTIONS) {
            addMessage({ sender: 'ai', type: 'text', text: "You've completed all 5 questions! Please proceed to the summary report." });
        }

      } else { // Still other options left to try
        try {
          const explanationResult = await explainIncorrectAnswer({
            question: questionForAI,
            options: currentMCQ.options,
            selectedAnswer: option,
            correctAnswer: currentMCQ.correctAnswer,
          });
          
          const repromptText = `That's not quite right. ${explanationResult.explanation} Would you like to try again?`;
          const repromptMCQData: ActiveMCQ = {
            ...currentMCQ, // carries over originalQuestionTextForFlow, options, correctAnswer
            mcq: repromptText, // This is the new display text for the question part of the message
          };
          
          addMessage({ sender: 'ai', type: 'mcq', mcq: repromptMCQData });
          setCurrentMCQ(repromptMCQData); // Update currentMCQ to this new re-prompt
          setIsAwaitingAnswer(true);

        } catch (error) {
          console.error("Error fetching explanation for incorrect answer:", error);
          const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
          const fallbackRepromptText = `That's not quite right. (Sorry, I couldn't explain that: ${errorMsg}) Please try another option from the question above.`;
          const fallbackMCQData: ActiveMCQ = {
            ...currentMCQ,
            mcq: fallbackRepromptText,
          };
          addMessage({ sender: 'ai', type: 'mcq', mcq: fallbackMCQData });
          setCurrentMCQ(fallbackMCQData);
          setIsAwaitingAnswer(true);
        }
      }
    }
    setIsLoading(false);
  };

  const handleNextQuestionClick = async () => {
    if (questionCount >= MAX_QUESTIONS) {
      addMessage({ sender: 'ai', type: 'text', text: "You've completed all the questions! Please proceed to the summary." });
      setIsLoading(false);
      setHasAnsweredCorrectly(true);
      return;
    }

    setIsAwaitingAnswer(false); 
    setHasAnsweredCorrectly(false);
    setCurrentMCQ(null); 
    setIncorrectAttempts([]); 
    
    if (!imageDataUri) {
      addMessage({ sender: 'ai', type: 'error', text: "Image data is not available to generate new questions." });
      toast({ title: "Error", description: "Cannot fetch new question: Image data missing.", variant: "destructive" });
      return;
    }
    setIsLoading(true);
    try {
      const mcqResult = await generateMCQ({ imageDataUri });
      const nextMCQData: ActiveMCQ = {
        ...mcqResult,
        originalQuestionTextForFlow: mcqResult.mcq, 
      };
      setCurrentMCQ(nextMCQData);
      addMessage({ sender: 'ai', type: 'mcq', mcq: nextMCQData });
      setIsAwaitingAnswer(true);
    } catch (error) {
      console.error("Error generating next MCQ:", error);
      const errorMessage = error instanceof Error ? error.message : "An unknown error occurred.";
      addMessage({ sender: 'ai', type: 'error', text: `Failed to generate new question: ${errorMessage}` });
      toast({
        title: "Error",
        description: `Could not generate a new question. ${errorMessage}`,
        variant: "destructive",
      });
      // Potentially allow user to try again or go to summary if multiple errors occur
    } finally {
      setIsLoading(false);
    }
  };

  const handleGoToSummary = () => {
    router.push(`/journey/${journeyId}/summary`);
  };


  return (
    <div className="flex h-full flex-col rounded-lg border bg-card shadow-xl">
      <div className="border-b p-4">
        <h2 className="font-headline text-lg font-semibold text-center">AI Chat Helper</h2>
      </div>
      <ScrollArea className="flex-1 p-4" ref={scrollAreaRef}>
        <div className="space-y-4">
          {messages.map((msg) => {
             const isLastMessageTheActiveMCQ =
              msg.type === 'mcq' &&
              currentMCQ &&
              msg.id === messages.findLast(m => m.type === 'mcq' && m.mcq?.mcq === currentMCQ.mcq && JSON.stringify(m.mcq?.options) === JSON.stringify(currentMCQ.options))?.id;

            const shouldThisMessageBeInteractive =
              isLastMessageTheActiveMCQ &&
              isAwaitingAnswer &&
              !hasAnsweredCorrectly;
            
            return (
              <ChatMessage
                key={msg.id}
                message={msg}
                activeMCQ={currentMCQ} 
                isAwaitingActiveMCQAnswer={shouldThisMessageBeInteractive}
                onOptionSelectActiveMCQ={handleOptionSelect}
                incorrectAttemptsForMCQ={
                  shouldThisMessageBeInteractive
                  ? incorrectAttempts
                  : [] 
                }
              />
            );
          })}
          {isLoading && !currentMCQ && messages[messages.length -1]?.type !== 'feedback' && (
            <div className="flex items-start space-x-3">
               <Skeleton className="h-8 w-8 rounded-full" />
               <div className="space-y-2">
                  <Skeleton className="h-4 w-48 rounded" />
                  <Skeleton className="h-4 w-32 rounded" />
               </div>
            </div>
          )}
        </div>
      </ScrollArea>
      <div className="border-t bg-background/80 p-4">
        {isLoading && (
            <div className="flex items-center justify-center text-sm text-muted-foreground">
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                AI is thinking...
            </div>
        )}

        {!isLoading && questionCount >= MAX_QUESTIONS && hasAnsweredCorrectly && (
          <Button onClick={handleGoToSummary} className="w-full" variant="default">
            Go to Report Summary <FileText className="ml-2 h-4 w-4" />
          </Button>
        )}

        {!isLoading && questionCount < MAX_QUESTIONS && currentMCQ && hasAnsweredCorrectly && (
           <Button onClick={handleNextQuestionClick} className="w-full" variant="default" disabled={isLoading}>
            Next Question <Send className="ml-2 h-4 w-4" />
          </Button>
        )}
        
        {!isLoading && currentMCQ && !hasAnsweredCorrectly && isAwaitingAnswer && (
            <p className="text-center text-sm text-muted-foreground">
              Please choose an answer from the options above.
            </p>
        )}

        {!imageDataUri && !isLoading && messages.length > 0 && messages[messages.length -1]?.text === "Preparing your journey..." &&(
          <p className="text-center text-sm text-muted-foreground">Loading image, please wait...</p>
        )}
         {!currentMCQ && !isLoading && imageDataUri && messages.length === 0 && ( 
           <p className="text-center text-sm text-muted-foreground">Loading first question...</p>
         )}
          {!currentMCQ && !isLoading && imageDataUri && messages.length > 0 && messages[messages.length -1]?.type === 'error' && (
             <p className="text-center text-sm text-destructive">Could not load question. Try refreshing the page or selecting another journey.</p>
         )}
      </div>
    </div>
  );
}
    
