GEM

import React, { useState, useEffect, useCallback } from 'react';
import { initializeApp } from 'firebase/app';
import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged } from 'firebase/auth';
import { getFirestore, doc, setDoc, collection, query, onSnapshot, orderBy, getDocs, addDoc } from 'firebase/firestore';

// Define the main App component
const App = () => {
    // State variables for Firebase and user authentication
    const [app, setApp] = useState(null);
    const [db, setDb] = useState(null);
    const [auth, setAuth] = useState(null);
    const [userId, setUserId] = useState(null);
    const [isAuthReady, setIsAuthReady] = useState(false);

    // State variables for CER input
    const [prompt, setPrompt] = useState('');
    const [claim, setClaim] = useState('');
    const [evidence, setEvidence] = useState('');
    const [reasoning, setReasoning] = useState('');
    const [rubric, setRubric] = useState(''); // New state for rubric

    // State variables for feedback and comprehension
    const [feedback, setFeedback] = useState(null);
    const [comprehensionQuestions, setComprehensionQuestions] = useState([]);
    const [comprehensionAnswers, setComprehensionAnswers] = useState({});
    const [submissions, setSubmissions] = useState([]);

    // State variables for UI feedback
    const [isLoadingFeedback, setIsLoadingFeedback] = useState(false);
    const [isLoadingQuestions, setIsLoadingQuestions] = useState(false);
    const [isSubmittingCER, setIsSubmittingCER] = useState(false);
    const [errorMessage, setErrorMessage] = useState('');
    const [successMessage, setSuccessMessage] = useState('');

    // Constants for app ID and Firebase config
    const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-cer-app';
    const firebaseConfig = typeof __firebase_config !== 'undefined' ? JSON.parse(__firebase_config) : {};
    const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null;

    // Initialize Firebase and set up authentication listener
    useEffect(() => {
        try {
            const firebaseApp = initializeApp(firebaseConfig);
            const firestoreDb = getFirestore(firebaseApp);
            const firebaseAuth = getAuth(firebaseApp);

            setApp(firebaseApp);
            setDb(firestoreDb);
            setAuth(firebaseAuth);

            // Listen for auth state changes
            const unsubscribe = onAuthStateChanged(firebaseAuth, async (user) => {
                if (user) {
                    setUserId(user.uid);
                } else {
                    // Sign in anonymously if no token is provided or user is not logged in
                    try {
                        if (initialAuthToken) {
                            await signInWithCustomToken(firebaseAuth, initialAuthToken);
                        } else {
                            await signInAnonymously(firebaseAuth);
                        }
                    } catch (error) {
                        console.error("Firebase authentication error:", error);
                        setErrorMessage("Failed to authenticate. Please try again.");
                    }
                }
                setIsAuthReady(true); // Mark auth as ready after initial check
            });

            return () => unsubscribe(); // Cleanup auth listener on unmount
        } catch (error) {
            console.error("Failed to initialize Firebase:", error);
            setErrorMessage("Failed to initialize the application. Check console for details.");
        }
    }, [firebaseConfig, initialAuthToken]);

    // Fetch submissions once authentication is ready
    useEffect(() => {
        if (!db || !userId || !isAuthReady) {
            return;
        }

        const submissionsCollectionRef = collection(db, `artifacts/${appId}/users/${userId}/cer_drafts`);
        // Note: orderBy is commented out to avoid potential index errors as per instructions.
        // Data will be sorted client-side if needed.
        const q = query(submissionsCollectionRef); // , orderBy('timestamp', 'desc'));

        const unsubscribe = onSnapshot(q, (snapshot) => {
            const fetchedSubmissions = snapshot.docs.map(doc => ({
                id: doc.id,
                ...doc.data()
            }));
            // Sort client-side by timestamp if needed
            fetchedSubmissions.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
            setSubmissions(fetchedSubmissions);
        }, (error) => {
            console.error("Error fetching submissions:", error);
            setErrorMessage("Failed to load past submissions.");
        });

        return () => unsubscribe(); // Cleanup snapshot listener
    }, [db, userId, appId, isAuthReady]);


    // Function to call the Gemini API for feedback
    const getCERFeedback = async (cerPrompt, cerClaim, cerEvidence, cerReasoning, cerRubric) => {
        setIsLoadingFeedback(true);
        setErrorMessage('');
        setSuccessMessage('');
        try {
            const chatHistory = [];
            let promptText = `As a science teacher, provide constructive feedback on the following Claim, Evidence, and Reasoning (CER) response. Focus on clarity, accuracy, and completeness for each section. Suggest specific ways to refine each part to achieve mastery. Provide the feedback in a structured JSON format with keys: "claim_feedback", "evidence_feedback", "reasoning_feedback", and "overall_suggestions".

            Science Prompt: "${cerPrompt}"
            Student's Claim: "${cerClaim}"
            Student's Evidence: "${cerEvidence}"
            Student's Reasoning: "${cerReasoning}"`;

            // Add rubric to prompt if provided
            if (cerRubric) {
                promptText += `\n\nConsider the following rubric when providing feedback:\nRubric: "${cerRubric}"`;
            }

            chatHistory.push({ role: "user", parts: [{ text: promptText }] });

            const payload = {
                contents: chatHistory,
                generationConfig: {
                    responseMimeType: "application/json",
                    responseSchema: {
                        type: "OBJECT",
                        properties: {
                            claim_feedback: { type: "STRING" },
                            evidence_feedback: { type: "STRING" },
                            reasoning_feedback: { type: "STRING" },
                            overall_suggestions: { type: "STRING" }
                        },
                        propertyOrdering: ["claim_feedback", "evidence_feedback", "reasoning_feedback", "overall_suggestions"]
                    }
                }
            };

            const apiKey = ""; // Canvas will provide this if empty
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;

            const response = await fetch(apiUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(`API error: ${response.status} - ${errorData.error?.message || 'Unknown error'}`);
            }

            const result = await response.json();
            if (result.candidates && result.candidates.length > 0 &&
                result.candidates[0].content && result.candidates[0].content.parts &&
                result.candidates[0].content.parts.length > 0) {
                const jsonString = result.candidates[0].content.parts[0].text;
                const parsedFeedback = JSON.parse(jsonString);
                setFeedback(parsedFeedback);
                setSuccessMessage("Feedback generated successfully!");
            } else {
                setErrorMessage("Failed to get feedback from AI. Please try again.");
            }
        } catch (error) {
            console.error("Error fetching CER feedback:", error);
            setErrorMessage(`Error generating feedback: ${error.message}`);
        } finally {
            setIsLoadingFeedback(false);
        }
    };

    // Function to call the Gemini API for comprehension questions
    const getComprehensionQuestions = async (cerPrompt, cerClaim, cerEvidence, cerReasoning) => {
        setIsLoadingQuestions(true);
        setErrorMessage('');
        setSuccessMessage('');
        try {
            const chatHistory = [];
            const promptText = `Based on the following science prompt and the student's CER response, generate 3-5 comprehension questions to assess their understanding of the topic and their CER. Provide the questions in a JSON array format, where each element is a string representing a question.

            Science Prompt: "${cerPrompt}"
            Student's Claim: "${cerClaim}"
            Student's Evidence: "${cerEvidence}"
            Student's Reasoning: "${cerReasoning}"`;

            chatHistory.push({ role: "user", parts: [{ text: promptText }] });

            const payload = {
                contents: chatHistory,
                generationConfig: {
                    responseMimeType: "application/json",
                    responseSchema: {
                        type: "ARRAY",
                        items: { type: "STRING" }
                    }
                }
            };

            const apiKey = ""; // Canvas will provide this if empty
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;

            const response = await fetch(apiUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(`API error: ${response.status} - ${errorData.error?.message || 'Unknown error'}`);
            }

            const result = await response.json();
            if (result.candidates && result.candidates.length > 0 &&
                result.candidates[0].content && result.candidates[0].content.parts &&
                result.candidates[0].content.parts.length > 0) {
                const jsonString = result.candidates[0].content.parts[0].text;
                const parsedQuestions = JSON.parse(jsonString);
                setComprehensionQuestions(parsedQuestions);
                // Initialize answers state
                const initialAnswers = parsedQuestions.reduce((acc, _, index) => ({ ...acc, [`q${index}`]: '' }), {});
                setComprehensionAnswers(initialAnswers);
                setSuccessMessage("Comprehension questions generated!");
            } else {
                setErrorMessage("Failed to get comprehension questions from AI. Please try again.");
            }
        } catch (error) {
            console.error("Error fetching comprehension questions:", error);
            setErrorMessage(`Error generating questions: ${error.message}`);
        } finally {
            setIsLoadingQuestions(false);
        }
    };

    // Handle form submission
    const handleSubmitCER = async (e) => {
        e.preventDefault();
        if (!db || !userId) {
            setErrorMessage("Application not ready. Please wait for authentication.");
            return;
        }

        if (!prompt || !claim || !evidence || !reasoning) {
            setErrorMessage("Please fill in all CER fields and the prompt.");
            return;
        }

        setIsSubmittingCER(true);
        setErrorMessage('');
        setSuccessMessage('');

        try {
            // Get feedback and questions concurrently
            await Promise.all([
                getCERFeedback(prompt, claim, evidence, reasoning, rubric), // Pass rubric here
                getComprehensionQuestions(prompt, claim, evidence, reasoning)
            ]);

            setSuccessMessage("CER submitted! Please review feedback and answer comprehension questions.");

        } catch (error) {
            console.error("Error during CER submission process:", error);
            setErrorMessage(`Failed to process CER: ${error.message}`);
        } finally {
            setIsSubmittingCER(false);
        }
    };

    // Handle submission of comprehension answers and save everything to Firestore
    const handleSaveFullSubmission = async () => {
        if (!db || !userId) {
            setErrorMessage("Application not ready. Please wait for authentication.");
            return;
        }

        setIsSubmittingCER(true);
        setErrorMessage('');
        setSuccessMessage('');

        try {
            const submissionData = {
                prompt,
                claim,
                evidence,
                reasoning,
                rubric, // Save the rubric
                feedback: feedback, // Save the generated feedback
                comprehensionQuestions: comprehensionQuestions,
                comprehensionAnswers: comprehensionAnswers,
                timestamp: Date.now(),
                userId: userId // Include userId for potential teacher review
            };

            const cerCollectionRef = collection(db, `artifacts/${appId}/users/${userId}/cer_drafts`);
            await addDoc(cerCollectionRef, submissionData);

            setSuccessMessage("Your full CER and comprehension answers have been saved!");
            // Clear form and feedback/questions after successful save
            setPrompt('');
            setClaim('');
            setEvidence('');
            setReasoning('');
            setRubric(''); // Clear rubric
            setFeedback(null);
            setComprehensionQuestions([]);
            setComprehensionAnswers({});
        } catch (error) {
            console.error("Error saving full CER submission:", error);
            setErrorMessage(`Failed to save submission: ${error.message}`);
        } finally {
            setIsSubmittingCER(false);
        }
    };

    // Handle change for comprehension answers
    const handleComprehensionAnswerChange = (index, value) => {
        setComprehensionAnswers(prev => ({ ...prev, [`q${index}`]: value }));
    };

    // Function to load a previous submission into the form
    const loadSubmission = (submission) => {
        setPrompt(submission.prompt || '');
        setClaim(submission.claim || '');
        setEvidence(submission.evidence || '');
        setReasoning(submission.reasoning || '');
        setRubric(submission.rubric || ''); // Load rubric
        setFeedback(submission.feedback || null);
        setComprehensionQuestions(submission.comprehensionQuestions || []);
        setComprehensionAnswers(submission.comprehensionAnswers || {});
        window.scrollTo({ top: 0, behavior: 'smooth' }); // Scroll to top
        setSuccessMessage("Previous submission loaded.");
        setErrorMessage('');
    };

    // Tailwind CSS classes for consistent styling
    const inputClasses = "w-full p-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 mb-4";
    const buttonClasses = "bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-md transition duration-300 ease-in-out shadow-lg";
    const sectionTitleClasses = "text-xl font-semibold text-gray-800 mb-4 border-b-2 border-blue-300 pb-2";
    const cardClasses = "bg-white p-6 rounded-lg shadow-xl mb-6 border border-gray-200";

    return (
        <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 p-6 font-inter text-gray-800">
            <div className="max-w-4xl mx-auto">
                <h1 className="text-4xl font-extrabold text-center text-blue-800 mb-10 drop-shadow-md">
                    Science CER Helper
                </h1>

                {!isAuthReady && (
                    <div className="text-center p-4 bg-yellow-100 text-yellow-800 rounded-md mb-6">
                        Loading application... Please wait.
                    </div>
                )}

                {errorMessage && (
                    <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-6" role="alert">
                        <strong className="font-bold">Error!</strong>
                        <span className="block sm:inline"> {errorMessage}</span>
                    </div>
                )}

                {successMessage && (
                    <div className="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative mb-6" role="alert">
                        <strong className="font-bold">Success!</strong>
                        <span className="block sm:inline"> {successMessage}</span>
                    </div>
                )}

                {userId && (
                    <div className="text-center text-sm text-gray-600 mb-6">
                        Your User ID: <span className="font-mono bg-gray-100 p-1 rounded">{userId}</span>
                    </div>
                )}

                {/* CER Input Form */}
                <div className={cardClasses}>
                    <h2 className={sectionTitleClasses}>Your CER Draft</h2>
                    <form onSubmit={handleSubmitCER}>
                        <div className="mb-4">
                            <label htmlFor="prompt" className="block text-gray-700 text-sm font-bold mb-2">
                                Science Prompt:
                            </label>
                            <textarea
                                id="prompt"
                                className={inputClasses + " h-24"}
                                value={prompt}
                                onChange={(e) => setPrompt(e.target.value)}
                                placeholder="Enter the science prompt here (e.g., 'Explain why seasons occur')."
                                required
                            ></textarea>
                        </div>

                        <div className="mb-4">
                            <label htmlFor="claim" className="block text-gray-700 text-sm font-bold mb-2">
                                Claim:
                            </label>
                            <textarea
                                id="claim"
                                className={inputClasses + " h-24"}
                                value={claim}
                                onChange={(e) => setClaim(e.target.value)}
                                placeholder="State your main argument or conclusion."
                                required
                            ></textarea>
                        </div>

                        <div className="mb-4">
                            <label htmlFor="evidence" className="block text-gray-700 text-sm font-bold mb-2">
                                Evidence:
                            </label>
                            <textarea
                                id="evidence"
                                className={inputClasses + " h-32"}
                                value={evidence}
                                onChange={(e) => setEvidence(e.target.value)}
                                placeholder="Provide specific data, observations, or facts that support your claim."
                                required
                            ></textarea>
                        </div>

                        <div className="mb-6">
                            <label htmlFor="reasoning" className="block text-gray-700 text-sm font-bold mb-2">
                                Reasoning:
                            </label>
                            <textarea
                                id="reasoning"
                                className={inputClasses + " h-40"}
                                value={reasoning}
                                onChange={(e) => setReasoning(e.target.value)}
                                placeholder="Explain how your evidence supports your claim. Connect the evidence to scientific principles."
                                required
                            ></textarea>
                        </div>

                        {/* New Rubric Input Field */}
                        <div className="mb-6">
                            <label htmlFor="rubric" className="block text-gray-700 text-sm font-bold mb-2">
                                Optional Rubric (as appropriate):
                            </label>
                            <textarea
                                id="rubric"
                                className={inputClasses + " h-32"}
                                value={rubric}
                                onChange={(e) => setRubric(e.target.value)}
                                placeholder="Enter a rubric or specific criteria for feedback here (e.g., 'Claim must be a single, clear sentence.')."
                            ></textarea>
                        </div>

                        <button
                            type="submit"
                            className={buttonClasses + " w-full"}
                            disabled={isLoadingFeedback || isLoadingQuestions || isSubmittingCER || !isAuthReady}
                        >
                            {isSubmittingCER ? 'Processing...' : 'Get Feedback & Questions'}
                        </button>
                    </form>
                </div>

                {/* Feedback Display */}
                {feedback && (
                    <div className={cardClasses}>
                        <h2 className={sectionTitleClasses}>AI Feedback</h2>
                        <div className="space-y-4">
                            <div>
                                <h3 className="font-semibold text-lg text-gray-700 mb-1">Claim Feedback:</h3>
                                <p className="text-gray-600 leading-relaxed">{feedback.claim_feedback}</p>
                            </div>
                            <div>
                                <h3 className="font-semibold text-lg text-gray-700 mb-1">Evidence Feedback:</h3>
                                <p className="text-gray-600 leading-relaxed">{feedback.evidence_feedback}</p>
                            </div>
                            <div>
                                <h3 className="font-semibold text-lg text-gray-700 mb-1">Reasoning Feedback:</h3>
                                <p className="text-gray-600 leading-relaxed">{feedback.reasoning_feedback}</p>
                            </div>
                            <div>
                                <h3 className="font-semibold text-lg text-gray-700 mb-1">Overall Suggestions:</h3>
                                <p className="text-gray-600 leading-relaxed">{feedback.overall_suggestions}</p>
                            </div>
                        </div>
                    </div>
                )}

                {/* Comprehension Questions */}
                {comprehensionQuestions.length > 0 && (
                    <div className={cardClasses}>
                        <h2 className={sectionTitleClasses}>Comprehension Questions</h2>
                        <p className="text-gray-600 mb-4">Answer these questions to demonstrate your understanding:</p>
                        <div className="space-y-4">
                            {comprehensionQuestions.map((question, index) => (
                                <div key={index}>
                                    <label htmlFor={`q${index}`} className="block text-gray-700 text-sm font-bold mb-2">
                                        {index + 1}. {question}
                                    </label>
                                    <textarea
                                        id={`q${index}`}
                                        className={inputClasses + " h-20"}
                                        value={comprehensionAnswers[`q${index}`] || ''}
                                        onChange={(e) => handleComprehensionAnswerChange(index, e.target.value)}
                                        placeholder="Your answer here..."
                                    ></textarea>
                                </div>
                            ))}
                        </div>
                        <button
                            onClick={handleSaveFullSubmission}
                            className={buttonClasses + " w-full mt-6"}
                            disabled={isSubmittingCER || !isAuthReady}
                        >
                            {isSubmittingCER ? 'Saving...' : 'Save Full Submission'}
                        </button>
                    </div>
                )}

                {/* Past Submissions */}
                {submissions.length > 0 && (
                    <div className={cardClasses}>
                        <h2 className={sectionTitleClasses}>Your Past Submissions</h2>
                        <div className="space-y-4">
                            {submissions.map((sub) => (
                                <div key={sub.id} className="border border-gray-200 p-4 rounded-md bg-gray-50 hover:bg-gray-100 transition duration-200 ease-in-out">
                                    <p className="font-semibold text-gray-700">Prompt: <span className="font-normal">{sub.prompt.substring(0, 100)}...</span></p>
                                    <p className="text-sm text-gray-500">Submitted: {new Date(sub.timestamp).toLocaleString()}</p>
                                    <button
                                        onClick={() => loadSubmission(sub)}
                                        className="mt-2 bg-indigo-500 hover:bg-indigo-600 text-white text-sm py-2 px-4 rounded-md shadow-sm transition duration-300 ease-in-out"
                                    >
                                        Load This Submission
                                    </button>
                                </div>
                            ))}
                        </div>
                    </div>
                )}
            </div>
        </div>
    );
};

export default App;