/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */
import { GoogleGenAI, Modality } from "@google/genai";

// --- DOM Element Selectors ---
const imageUpload = document.getElementById("image-upload") as HTMLInputElement;
const styleSelect = document.getElementById("style-select") as HTMLSelectElement;
const generateButton = document.getElementById(
  "generate-button"
) as HTMLButtonElement;
const beforeImage = document.getElementById("before-image") as HTMLImageElement;
const afterImage = document.getElementById("after-image") as HTMLImageElement;
const loadingSpinner = document.getElementById(
  "loading-spinner"
) as HTMLDivElement;
const fileNameDisplay = document.getElementById(
  "file-name"
) as HTMLParagraphElement;

// --- State Management ---
let uploadedFile: File | null = null;
let uploadedFileBase64: string | null = null;

// --- Gemini API Initialization ---
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
const model = "gemini-2.5-flash-image-preview";

// --- Event Listeners ---
imageUpload.addEventListener("change", handleImageUpload);
generateButton.addEventListener("click", handleGenerateClick);

// --- Functions ---

/**
 * Handles the file upload event.
 */
function handleImageUpload(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];

  if (file) {
    uploadedFile = file;
    fileNameDisplay.textContent = file.name;
    generateButton.disabled = false;

    const reader = new FileReader();
    reader.onloadend = () => {
      const base64String = (reader.result as string).split(",")[1];
      uploadedFileBase64 = base64String;
      beforeImage.src = reader.result as string;
    };
    reader.readAsDataURL(file);
  }
}

/**
 * Handles the click event for the generate button.
 */
async function handleGenerateClick() {
  if (!uploadedFile || !uploadedFileBase64) {
    alert("Please upload an image first.");
    return;
  }

  setLoading(true);

  try {
    const selectedStyle = styleSelect.value;
    const prompt = `Redesign this room in a ${selectedStyle} style.`;

    const imagePart = {
      inlineData: {
        mimeType: uploadedFile.type,
        data: uploadedFileBase64,
      },
    };

    const textPart = {
      text: prompt,
    };

    const response = await ai.models.generateContent({
      model: model,
      contents: {
        parts: [imagePart, textPart],
      },
      config: {
        responseModalities: [Modality.IMAGE, Modality.TEXT],
      },
    });

    // The model can return multiple parts, find the one that is an image.
    const parts = response.candidates?.[0]?.content?.parts;
    const imageResult = parts?.find((part) => part.inlineData);

    if (imageResult && imageResult.inlineData) {
      const newImageBase64 = imageResult.inlineData.data;
      const newImageType = imageResult.inlineData.mimeType;
      afterImage.src = `data:${newImageType};base64,${newImageBase64}`;
    } else {
      throw new Error("No image was generated. Please try again.");
    }
  } catch (error) {
    console.error("Error generating design:", error);
    alert(
      "An error occurred while generating the design. Please check the console for more details."
    );
    afterImage.src =
      "https://placehold.co/600x400/ff0000/FFFFFF?text=Error!";
  } finally {
    setLoading(false);
  }
}

/**
 * Toggles the loading state of the UI.
 * @param isLoading - Whether to show or hide the loading state.
 */
function setLoading(isLoading: boolean) {
  if (isLoading) {
    loadingSpinner.style.display = "flex";
    generateButton.disabled = true;
    generateButton.textContent = "Generating...";
  } else {
    loadingSpinner.style.display = "none";
    generateButton.disabled = false;
    generateButton.textContent = "Generate Design";
  }
}
