/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import { GoogleGenAI, Chat } from "@google/genai";

// --- PASTE YOUR GEMINI API KEY HERE ---
const API_KEY = "YOUR_API_KEY"; 
// ------------------------------------

document.addEventListener('DOMContentLoaded', () => {
  // Setup screen elements
  const setupContainer = document.getElementById('setup-container') as HTMLDivElement;
  const setupForm = document.getElementById('setup-form') as HTMLFormElement;
  const nameInput = document.getElementById('name-input') as HTMLInputElement;
  const gradeSelect = document.getElementById('grade-select') as HTMLSelectElement;
  const boardSelect = document.getElementById('board-select') as HTMLSelectElement;
  const subjectSelect = document.getElementById('subject-select') as HTMLSelectElement;

  // Chat screen elements
  const chatContainer = document.getElementById('chat-container') as HTMLDivElement;
  const chatTitle = document.getElementById('chat-title') as HTMLHeadingElement;
  const messageForm = document.getElementById('message-form') as HTMLFormElement;
  const messageInput = document.getElementById('message-input') as HTMLInputElement;
  const sendButton = document.getElementById('send-button') as HTMLButtonElement;
  const messageList = document.getElementById('message-list') as HTMLDivElement;
  const typingIndicator = document.getElementById('typing-indicator') as HTMLDivElement;
  
  // Attachment and Image elements
  const attachmentButton = document.getElementById('attachment-button') as HTMLButtonElement;
  const attachmentMenu = document.getElementById('attachment-menu') as HTMLDivElement;
  const uploadImageButton = document.getElementById('upload-image-button') as HTMLButtonElement;
  const useCameraButton = document.getElementById('use-camera-button') as HTMLButtonElement;
  const imageUpload = document.getElementById('image-upload') as HTMLInputElement;
  const imagePreviewContainer = document.getElementById('image-preview-container') as HTMLDivElement;
  const imagePreview = document.getElementById('image-preview') as HTMLImageElement;
  const removeImageButton = document.getElementById('remove-image-button') as HTMLButtonElement;

  // Camera Modal elements
  const cameraModal = document.getElementById('camera-modal') as HTMLDivElement;
  const cameraView = document.getElementById('camera-view') as HTMLVideoElement;
  const cameraCanvas = document.getElementById('camera-canvas') as HTMLCanvasElement;
  const captureButton = document.getElementById('capture-button') as HTMLButtonElement;
  const cancelCameraButton = document.getElementById('cancel-camera-button') as HTMLButtonElement;
  
  let ai: GoogleGenAI;
  let chat: Chat | null = null;
  let studentName: string = '';
  let attachedImage: { mimeType: string, data: string } | null = null;
  let cameraStream: MediaStream | null = null;

  /**
   * Converts a file to a Base64 encoded string.
   */
  const fileToGenerativePart = async (file: File) => {
    const base64EncodedDataPromise = new Promise<string>((resolve) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve((reader.result as string).split(',')[1]);
      reader.readAsDataURL(file);
    });
    return {
      inlineData: { data: await base64EncodedDataPromise, mimeType: file.type },
    };
  };

  /**
   * Formats the AI's text response into safe HTML.
   */
  const formatResponse = (text: string): string => {
    let html = '';
    let inList = false;
    const lines = text.split('\n');

    for (const line of lines) {
      let processedLine = line.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');

      if (processedLine.startsWith('* ')) {
        if (!inList) {
          html += '<ul>';
          inList = true;
        }
        html += `<li>${processedLine.substring(2)}</li>`;
      } else {
        if (inList) {
          html += '</ul>';
          inList = false;
        }
        if (processedLine.trim()) {
          html += `<p>${processedLine}</p>`;
        }
      }
    }

    if (inList) {
      html += '</ul>';
    }
    return html;
  };

  /**
   * Scrolls the message list to the bottom.
   */
  const scrollToBottom = () => {
    messageList.scrollTop = messageList.scrollHeight;
  };

  /**
   * Displays the selected image preview.
   */
  const showImagePreview = (file: File) => {
    const reader = new FileReader();
    reader.onload = async (e) => {
        imagePreview.src = e.target?.result as string;
        imagePreviewContainer.classList.remove('hidden');
        const part = await fileToGenerativePart(file);
        attachedImage = {
            mimeType: part.inlineData.mimeType,
            data: part.inlineData.data,
        };
    };
    reader.readAsDataURL(file);
  };
  
  /**
   * Removes the attached image.
   */
  const removeImage = () => {
    attachedImage = null;
    imagePreview.src = '#';
    imageUpload.value = ''; // Reset file input
    imagePreviewContainer.classList.add('hidden');
  };

  /**
   * Adds a message to the chat window.
   */
  const addMessage = (text: string, sender: 'user' | 'ai' | 'system', imageUrl?: string) => {
    const messageElement = document.createElement('div');
    messageElement.classList.add('message', `${sender}-message`);

    let content = '';
    if (imageUrl) {
        const img = document.createElement('img');
        img.src = imageUrl;
        content += img.outerHTML;
    }

    if (sender === 'ai') {
        content += formatResponse(text);
    } else {
        const p = document.createElement('p');
        p.textContent = text;
        content += p.outerHTML;
    }
    
    messageElement.innerHTML = content;
    messageList.appendChild(messageElement);
    scrollToBottom();
  };

  /**
   * Initializes a new chat session with the current settings.
   */
  const initializeChat = () => {
    const grade = gradeSelect.value;
    const board = boardSelect.value;
    const subject = subjectSelect.value;

    const systemInstruction = `You are an expert AI Tutor. Your student's name is ${studentName}. They are in grade ${grade}, following the ${board} curriculum, and are asking about ${subject}. Please provide a clear, concise, and age-appropriate explanation. Explain the concept simply and use analogies if helpful. Do not just give the answer; help the student understand the 'how' and the 'why'. Format your response with markdown-style syntax for bolding (**text**) and bullet points (* point).`;
    
    chat = ai.chats.create({
        model: 'gemini-2.5-flash',
        config: {
            systemInstruction: systemInstruction,
        }
    });
  };

  /**
   * Handles the form submission for sending a message.
   */
  const handleSendMessage = async (e: Event) => {
    e.preventDefault();
    const userMessage = messageInput.value.trim();
    if (!userMessage && !attachedImage) return;

    const imageUrl = attachedImage ? `data:${attachedImage.mimeType};base64,${attachedImage.data}` : undefined;
    addMessage(userMessage, 'user', imageUrl);
    
    const messageToSend = [];
    if (attachedImage) {
        messageToSend.push({ inlineData: attachedImage });
    }
    if (userMessage) {
        messageToSend.push({ text: userMessage });
    }

    messageInput.value = '';
    messageInput.disabled = true;
    sendButton.disabled = true;
    removeImage();

    typingIndicator.style.display = 'flex';
    scrollToBottom();
    
    try {
      if (!chat) initializeChat();
      const result = await chat!.sendMessage({ message: messageToSend });
      addMessage(result.text, 'ai');
    } catch (err) {
      console.error(err);
      addMessage('Sorry, something went wrong. Please try again.', 'ai');
    } finally {
      typingIndicator.style.display = 'none';
      messageInput.disabled = false;
      sendButton.disabled = false;
      messageInput.focus();
    }
  };
  
  /**
   * Handles the initial setup form submission.
   */
  const handleSetup = (e: Event) => {
    e.preventDefault();
    studentName = nameInput.value.trim();

    if (!studentName) {
        alert('Please fill in your name.');
        return;
    }

    if (!API_KEY || API_KEY === "YOUR_API_KEY") {
        alert("Please provide your Gemini API key in the index.tsx file.");
        return;
    }

    try {
        ai = new GoogleGenAI({ apiKey: API_KEY });
    } catch (error) {
        alert('Failed to initialize AI. Please check your API key configuration.');
        console.error(error);
        return;
    }
    
    setupContainer.classList.add('hidden');
    chatContainer.classList.remove('hidden');

    chatTitle.textContent = `AI Tutor for ${studentName}`;
    
    initializeChat();
    addMessage(`Hello ${studentName}! I'm your AI Tutor. Ask me anything about ${subjectSelect.value}.`, 'ai');
  };

  /**
   * Camera functionality
   */
  const openCamera = async () => {
    try {
        cameraStream = await navigator.mediaDevices.getUserMedia({ video: true });
        cameraView.srcObject = cameraStream;
        cameraModal.classList.remove('hidden');
    } catch (err) {
        console.error("Error accessing camera: ", err);
        alert("Could not access the camera. Please ensure you have given permission.");
    }
  };

  const closeCamera = () => {
    if (cameraStream) {
        cameraStream.getTracks().forEach(track => track.stop());
    }
    cameraModal.classList.add('hidden');
  };

  const captureImage = () => {
    const context = cameraCanvas.getContext('2d');
    cameraCanvas.width = cameraView.videoWidth;
    cameraCanvas.height = cameraView.videoHeight;
    context?.drawImage(cameraView, 0, 0, cameraCanvas.width, cameraCanvas.height);
    cameraCanvas.toBlob(blob => {
        if (blob) {
            const file = new File([blob], "camera-shot.jpg", { type: "image/jpeg" });
            showImagePreview(file);
        }
    }, 'image/jpeg');
    closeCamera();
  };

  // --- Event Listeners ---
  setupForm.addEventListener('submit', handleSetup);
  messageForm.addEventListener('submit', handleSendMessage);
  removeImageButton.addEventListener('click', removeImage);

  // Attachment menu toggle
  attachmentButton.addEventListener('click', (e) => {
    e.stopPropagation();
    attachmentMenu.classList.toggle('hidden');
  });

  document.addEventListener('click', () => {
    if (!attachmentMenu.classList.contains('hidden')) {
        attachmentMenu.classList.add('hidden');
    }
  });

  // Upload image
  uploadImageButton.addEventListener('click', () => imageUpload.click());
  imageUpload.addEventListener('change', (e) => {
    const files = (e.target as HTMLInputElement).files;
    if (files && files[0]) {
        showImagePreview(files[0]);
    }
  });

  // Camera events
  useCameraButton.addEventListener('click', openCamera);
  captureButton.addEventListener('click', captureImage);
  cancelCameraButton.addEventListener('click', closeCamera);
});