/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */
/* tslint:disable */
import {
  ChevronDown,
  Library,
  LoaderCircle,
  Paintbrush,
  PictureInPicture,
  Redo2,
  SendHorizontal,
  Sparkles,
  Trash2,
  Undo2,
  X,
} from 'lucide-react';
import {useEffect, useRef, useState} from 'react';

// This function remains useful for parsing potential error messages
function parseError(error: string) {
  try {
    // Attempt to parse the error as a JSON object which the proxy might send
    const errObj = JSON.parse(error);
    return errObj.message || error;
  } catch (e) {
    // If it's not JSON, return the original error string
    const regex = /{"error":(.*)}/gm;
    const m = regex.exec(error);
    try {
      const e = m[1];
      const err = JSON.parse(e);
      return err.message || error;
    } catch (e) {
      return error;
    }
  }
}

export default function Home() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const backgroundImageRef = useRef<HTMLImageElement | null>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [prompt, setPrompt] = useState('');
  const [generatedImage, setGeneratedImage] = useState<string | null>(null);
  const [multiImages, setMultiImages] = useState<
    {url: string; type: string}[]
  >([]);
  const [isLoading, setIsLoading] = useState(false);
  const [showErrorModal, setShowErrorModal] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const [mode, setMode] = useState<
    'canvas' | 'editor' | 'imageGen' | 'multi-img-edit'
  >('editor');
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
  const [apiKey, setApiKey] = useState('');
  const [showApiKeyModal, setShowApiKeyModal] = useState(false);

  // State for canvas history
  const [history, setHistory] = useState<string[]>([]);
  const [historyIndex, setHistoryIndex] = useState(-1);

  // When switching to canvas mode, initialize it and its history
  useEffect(() => {
    if (mode === 'canvas' && canvasRef.current) {
      const canvas = canvasRef.current;
      const ctx = canvas.getContext('2d');
      ctx.fillStyle = '#FFFFFF';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // If an image already exists from another mode, draw it.
      if (generatedImage) {
        const img = new window.Image();
        img.onload = () => {
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          // Save this as the initial state for this session
          const dataUrl = canvas.toDataURL();
          setHistory([dataUrl]);
          setHistoryIndex(0);
        };
        img.src = generatedImage;
      } else {
        // Otherwise, save the blank state as initial
        const dataUrl = canvas.toDataURL();
        setHistory([dataUrl]);
        setHistoryIndex(0);
      }
    }
  }, [mode, generatedImage]);

  // Load background image when generatedImage changes
  useEffect(() => {
    if (generatedImage && canvasRef.current) {
      const img = new window.Image();
      img.onload = () => {
        backgroundImageRef.current = img;
        drawImageToCanvas();
        if (mode === 'canvas') {
          // A small timeout to let the draw happen before saving
          setTimeout(saveCanvasState, 50);
        }
      };
      img.src = generatedImage;
    }
  }, [generatedImage, mode]);

  // Handle clicks outside the dropdown to close it
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node)
      ) {
        setIsDropdownOpen(false);
      }
    }
    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [dropdownRef]);

  // Initialize canvas with white background
  const initializeCanvas = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
  };

  // Draw the background image to the canvas
  const drawImageToCanvas = () => {
    if (!canvasRef.current || !backgroundImageRef.current) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(
      backgroundImageRef.current,
      0,
      0,
      canvas.width,
      canvas.height,
    );
  };

  // Canvas history functions
  const saveCanvasState = () => {
    if (!canvasRef.current) return;
    const canvas = canvasRef.current;
    const dataUrl = canvas.toDataURL();
    const newHistory = history.slice(0, historyIndex + 1);
    newHistory.push(dataUrl);
    setHistory(newHistory);
    setHistoryIndex(newHistory.length - 1);
  };

  const restoreCanvasState = (index: number) => {
    if (!canvasRef.current || !history[index]) return;
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    const dataUrl = history[index];
    const img = new window.Image();
    img.onload = () => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    };
    img.src = dataUrl;
  };

  const handleUndo = () => {
    if (historyIndex > 0) {
      const newIndex = historyIndex - 1;
      setHistoryIndex(newIndex);
      restoreCanvasState(newIndex);
    }
  };

  const handleRedo = () => {
    if (historyIndex < history.length - 1) {
      const newIndex = historyIndex + 1;
      setHistoryIndex(newIndex);
      restoreCanvasState(newIndex);
    }
  };

  // Get the correct coordinates based on canvas scaling
  const getCoordinates = (e: any) => {
    const canvas = canvasRef.current!;
    const rect = canvas.getBoundingClientRect();
    const scaleX = canvas.width / rect.width;
    const scaleY = canvas.height / rect.height;
    return {
      x:
        (e.nativeEvent.offsetX ||
          e.nativeEvent.touches?.[0]?.clientX - rect.left) * scaleX,
      y:
        (e.nativeEvent.offsetY ||
          e.nativeEvent.touches?.[0]?.clientY - rect.top) * scaleY,
    };
  };

  const startDrawing = (e: any) => {
    const canvas = canvasRef.current!;
    const ctx = canvas.getContext('2d')!;
    const {x, y} = getCoordinates(e);
    if (e.type === 'touchstart') {
      e.preventDefault();
    }
    ctx.beginPath();
    ctx.moveTo(x, y);
    setIsDrawing(true);
  };

  const draw = (e: any) => {
    if (!isDrawing) return;
    if (e.type === 'touchmove') {
      e.preventDefault();
    }
    const canvas = canvasRef.current!;
    const ctx = canvas.getContext('2d')!;
    const {x, y} = getCoordinates(e);
    ctx.lineWidth = 5;
    ctx.lineCap = 'round';
    ctx.strokeStyle = '#000000';
    ctx.lineTo(x, y);
    ctx.stroke();
  };

  const stopDrawing = () => {
    if (!isDrawing) return;
    setIsDrawing(false);
    saveCanvasState();
  };

  const handleClear = () => {
    if (mode === 'canvas' && canvasRef.current) {
      initializeCanvas();
      const dataUrl = canvasRef.current.toDataURL();
      setHistory([dataUrl]);
      setHistoryIndex(0);
    }
    setGeneratedImage(null);
    setMultiImages([]);
    backgroundImageRef.current = null;
    setPrompt('');
  };

  const processFiles = (files: FileList | null) => {
    if (!files) return;
    const fileArray = Array.from(files).filter((f) =>
      f.type.startsWith('image/'),
    );
    if (fileArray.length === 0) return;

    if (!apiKey) {
      setShowApiKeyModal(true);
    }

    if (mode === 'multi-img-edit') {
      const readers = fileArray.map((file) => {
        return new Promise<{url: string; type: string}>((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = () =>
            resolve({url: reader.result as string, type: file.type});
          reader.onerror = reject;
          reader.readAsDataURL(file);
        });
      });
      Promise.all(readers).then((newImages) => {
        setMultiImages((prev) => [...prev, ...newImages]);
      });
    } else {
      const file = fileArray[0];
      const reader = new FileReader();
      reader.onload = () => {
        setGeneratedImage(reader.result as string);
      };
      reader.readAsDataURL(file);
    }
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    processFiles(e.target.files);
    e.target.value = '';
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    e.currentTarget.classList.remove('border-blue-500');
    processFiles(e.dataTransfer.files);
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
  };
  const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {
    e.currentTarget.classList.add('border-blue-500');
  };
  const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
    e.currentTarget.classList.remove('border-blue-500');
  };

  const removeImage = (indexToRemove: number) => {
    setMultiImages((prev) =>
      prev.filter((_, index) => index !== indexToRemove),
    );
  };

  // *** MODIFIED FUNCTION ***
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!apiKey) {
      setShowApiKeyModal(true);
      return;
    }

    setIsLoading(true);

    try {
      if (mode === 'editor' && !generatedImage) {
        setErrorMessage('Please upload an image to edit.');
        setShowErrorModal(true);
        return;
      }

      if (mode === 'multi-img-edit' && multiImages.length === 0) {
        setErrorMessage('Please upload at least one image to edit.');
        setShowErrorModal(true);
        return;
      }

      const parts: any[] = [];

      // This logic for building the 'parts' array is correct.
      if (mode === 'imageGen') {
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 960;
        tempCanvas.height = 540;
        const tempCtx = tempCanvas.getContext('2d')!;
        tempCtx.fillStyle = '#FFFFFF';
        tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
        tempCtx.fillStyle = '#FEFEFE';
        tempCtx.fillRect(0, 0, 1, 1);
        const imageB64 = tempCanvas.toDataURL('image/png').split(',')[1];
        parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
      } else if (mode === 'canvas') {
        if (!canvasRef.current) return;
        const canvas = canvasRef.current;
        const imageB64 = canvas.toDataURL('image/png').split(',')[1];
        parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
      } else if (mode === 'editor' && generatedImage) {
        const mimeType = generatedImage.substring(
          generatedImage.indexOf(':') + 1,
          generatedImage.indexOf(';'),
        );
        const imageB64 = generatedImage.split(',')[1];
        parts.push({inlineData: {data: imageB64, mimeType}});
      } else if (mode === 'multi-img-edit') {
        multiImages.forEach((img) => {
          parts.push({
            inlineData: {data: img.url.split(',')[1], mimeType: img.type},
          });
        });
      }

      parts.push({text: prompt});

      // Construct the request body for the Gemini REST API
      const requestBody = {
        contents: [{role: 'USER', parts}],
      };

      // Define the proxy endpoint
      const proxyUrl = `/api-proxy/v1beta/models/gemini-2.5-flash-image-preview:generateContent?key=${apiKey}`;

      // Use fetch to send the request to your proxy server
      const response = await fetch(proxyUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(requestBody),
      });

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

      const responseData = await response.json();

      // Process the response
      const result = {message: '', imageData: null};

      if (responseData.candidates && responseData.candidates.length > 0) {
        for (const part of responseData.candidates[0].content.parts) {
          if (part.text) {
            result.message = part.text;
          } else if (part.inlineData) {
            result.imageData = part.inlineData.data;
          }
        }
      } else {
        throw new Error('Invalid response structure from API.');
      }

      if (result.imageData) {
        const imageUrl = `data:image/png;base64,${result.imageData}`;
        if (mode === 'multi-img-edit') {
          setGeneratedImage(imageUrl);
          setMultiImages([]);
          setMode('editor');
        } else {
          setGeneratedImage(imageUrl);
        }
      } else {
        setErrorMessage(
          result.message || 'Failed to generate image. Please try again.',
        );
        setShowErrorModal(true);
      }
    } catch (error: any) {
      console.error('Error submitting:', error);
      setErrorMessage(error.message || 'An unexpected error occurred.');
      setShowErrorModal(true);
    } finally {
      setIsLoading(false);
    }
  };

  const closeErrorModal = () => {
    setShowErrorModal(false);
  };

  const handleApiKeySubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const newApiKey = (e.target as any).apiKey.value;
    if (newApiKey) {
      setApiKey(newApiKey);
      setShowApiKeyModal(false);
    }
  };

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const preventTouchDefault = (e: TouchEvent) => {
      if (isDrawing) {
        e.preventDefault();
      }
    };

    canvas.addEventListener('touchstart', preventTouchDefault, {
      passive: false,
    });
    canvas.addEventListener('touchmove', preventTouchDefault, {
      passive: false,
    });

    return () => {
      canvas.removeEventListener('touchstart', preventTouchDefault);
      canvas.removeEventListener('touchmove', preventTouchDefault);
    };
  }, [isDrawing]);

  const baseDisplayClass =
    'w-full sm:h-[60vh] h-[40vh] min-h-[320px] bg-white/90 touch-none flex items-center justify-center p-4 transition-colors';

  return (
    <>
      <div className="min-h-screen text-gray-900 flex flex-col justify-start items-center">
        <main className="container mx-auto px-3 sm:px-6 py-5 sm:py-10 pb-32 max-w-5xl w-full">
          <div className="flex flex-col sm:flex-row sm:justify-between sm:items-end mb-2 sm:mb-6 gap-2">
            <div>
              <h1 className="text-2xl sm:text-3xl font-bold mb-0 leading-tight">
                Nano Banana AIO
              </h1>
              <p className="text-sm sm:text-base text-gray-500 mt-1">
                constructed with the{' '}
                <a
                  className="underline"
                  href="https://aistudio.google.com/app/apikey"
                  target="_blank"
                  rel="noopener noreferrer">
                  gemini api
                </a>{' '}
                by{' '}
                <a
                  className="underline"
                  href="https://huggingface.co/prithivMLmods"
                  target="_blank"
                  rel="noopener noreferrer">
                  prithivsakthi-ur
                </a>
              </p>
            </div>

            <menu className="flex items-center bg-gray-300 rounded-full p-2 shadow-sm self-start sm:self-auto">
              <div className="flex flex-wrap justify-center items-center bg-gray-200/80 rounded-full p-1 mr-2">
                <div className="relative" ref={dropdownRef}>
                  <button
                    onClick={() => setIsDropdownOpen(!isDropdownOpen)}
                    className={`p-2 sm:px-3 sm:py-1.5 rounded-full text-sm font-medium flex items-center gap-2 transition-colors ${
                      mode === 'editor' || mode === 'multi-img-edit'
                        ? 'bg-white shadow'
                        : 'text-gray-600 hover:bg-gray-300/50'
                    }`}
                    aria-haspopup="true"
                    aria-expanded={isDropdownOpen}>
                    {mode === 'multi-img-edit' ? (
                      <>
                        <Library className="w-4 h-4" />
                        <span className="hidden sm:inline">Multi-Image</span>
                      </>
                    ) : (
                      <>
                        <PictureInPicture className="w-4 h-4" />
                        <span className="hidden sm:inline">Editor</span>
                      </>
                    )}
                    <ChevronDown className="w-4 h-4 opacity-70" />
                  </button>
                  {isDropdownOpen && (
                    <div className="absolute top-full mt-2 w-48 bg-white rounded-lg shadow-xl z-10 border border-gray-200 py-1">
                      <button
                        onClick={() => {
                          setMode('editor');
                          setIsDropdownOpen(false);
                        }}
                        className={`w-full text-left px-3 py-2 text-sm flex items-center gap-3 transition-colors ${
                          mode === 'editor'
                            ? 'bg-gray-100 text-gray-900'
                            : 'text-gray-700 hover:bg-gray-50'
                        }`}
                        aria-pressed={mode === 'editor'}>
                        <PictureInPicture className="w-4 h-4" />
                        <span>Single Image Edit</span>
                      </button>
                      <button
                        onClick={() => {
                          setMode('multi-img-edit');
                          setIsDropdownOpen(false);
                        }}
                        className={`w-full text-left px-3 py-2 text-sm flex items-center gap-3 transition-colors ${
                          mode === 'multi-img-edit'
                            ? 'bg-gray-100 text-gray-900'
                            : 'text-gray-700 hover:bg-gray-50'
                        }`}
                        aria-pressed={mode === 'multi-img-edit'}>
                        <Library className="w-4 h-4" />
                        <span>Multi-Image Edit</span>
                      </button>
                    </div>
                  )}
                </div>

                <button
                  onClick={() => setMode('canvas')}
                  className={`p-2 sm:px-3 sm:py-1.5 rounded-full text-sm font-medium flex items-center gap-2 transition-colors ${
                    mode === 'canvas'
                      ? 'bg-white shadow'
                      : 'text-gray-600 hover:bg-gray-300/50'
                  }`}
                  aria-pressed={mode === 'canvas'}>
                  <Paintbrush className="w-4 h-4" />
                  <span className="hidden sm:inline">Canvas</span>
                </button>
                <button
                  onClick={() => setMode('imageGen')}
                  className={`p-2 sm:px-3 sm:py-1.5 rounded-full text-sm font-medium flex items-center gap-2 transition-colors ${
                    mode === 'imageGen'
                      ? 'bg-white shadow'
                      : 'text-gray-600 hover:bg-gray-300/50'
                  }`}
                  aria-pressed={mode === 'imageGen'}>
                  <Sparkles className="w-4 h-4" />
                  <span className="hidden sm:inline">Image Gen</span>
                </button>
              </div>
              <button
                type="button"
                onClick={handleClear}
                className="w-10 h-10 rounded-full flex items-center justify-center bg-white shadow-sm transition-all hover:bg-gray-50 hover:scale-110">
                <Trash2
                  className="w-5 h-5 text-gray-700"
                  aria-label="Clear Canvas"
                />
              </button>
            </menu>
          </div>

          <div className="w-full mb-6">
            <input
              ref={fileInputRef}
              type="file"
              onChange={handleFileChange}
              accept="image/*"
              className="hidden"
              aria-label="Upload image"
              multiple={mode === 'multi-img-edit'}
            />
            {mode === 'canvas' ? (
              <div className="relative w-full">
                <canvas
                  ref={canvasRef}
                  width={960}
                  height={540}
                  onMouseDown={startDrawing}
                  onMouseMove={draw}
                  onMouseUp={stopDrawing}
                  onMouseLeave={stopDrawing}
                  onTouchStart={startDrawing}
                  onTouchMove={draw}
                  onTouchEnd={stopDrawing}
                  className="border-2 border-black w-full sm:h-[60vh] h-[40vh] min-h-[320px] bg-white/90 touch-none"
                  style={{
                    cursor:
                      "url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"%23FF0000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 5v14M5 12h14\"/></svg>') 12 12, crosshair",
                  }}
                />
                <div className="absolute top-2 right-2 flex gap-2">
                  <button
                    onClick={handleUndo}
                    disabled={historyIndex <= 0}
                    className="p-2 bg-white rounded-md shadow disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100 transition-colors"
                    aria-label="Undo">
                    <Undo2 className="w-5 h-5" />
                  </button>
                  <button
                    onClick={handleRedo}
                    disabled={historyIndex >= history.length - 1}
                    className="p-2 bg-white rounded-md shadow disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100 transition-colors"
                    aria-label="Redo">
                    <Redo2 className="w-5 h-5" />
                  </button>
                </div>
              </div>
            ) : mode === 'editor' ? (
              <div
                className={`${baseDisplayClass} ${
                  generatedImage ? 'border-black' : 'border-gray-400'
                } border-2 border-dashed`}
                onDrop={handleDrop}
                onDragOver={handleDragOver}
                onDragEnter={handleDragEnter}
                onDragLeave={handleDragLeave}>
                {generatedImage ? (
                  <img
                    src={generatedImage}
                    alt="Current image"
                    className="max-w-full max-h-full object-contain"
                  />
                ) : (
                  <button
                    type="button"
                    onClick={() => fileInputRef.current?.click()}
                    className="text-center text-gray-500 hover:text-gray-700 p-8 rounded-lg">
                    <h3 className="font-semibold text-lg">Upload Image</h3>
                    <p>Click to upload or drag & drop</p>
                  </button>
                )}
              </div>
            ) : mode === 'multi-img-edit' ? (
              <div
                className={`${baseDisplayClass} ${
                  multiImages.length > 0
                    ? 'border-black items-start'
                    : 'border-gray-400'
                } border-2 border-dashed flex-col`}
                onDrop={handleDrop}
                onDragOver={handleDragOver}
                onDragEnter={handleDragEnter}
                onDragLeave={handleDragLeave}>
                {multiImages.length > 0 ? (
                  <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 p-4 overflow-y-auto w-full h-full">
                    {multiImages.map((image, index) => (
                      <div key={index} className="relative group aspect-square">
                        <img
                          src={image.url}
                          alt={`upload preview ${index + 1}`}
                          className="w-full h-full object-cover rounded-md"
                        />
                        <button
                          onClick={() => removeImage(index)}
                          className="absolute top-1 right-1 bg-black/50 text-white rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity"
                          aria-label={`Remove image ${index + 1}`}>
                          <X className="w-4 h-4" />
                        </button>
                      </div>
                    ))}
                    <button
                      type="button"
                      onClick={() => fileInputRef.current?.click()}
                      className="flex items-center justify-center border-2 border-dashed border-gray-300 rounded-md text-gray-400 hover:text-gray-600 hover:border-gray-400 transition-colors aspect-square">
                      + Add more
                    </button>
                  </div>
                ) : (
                  <button
                    type="button"
                    onClick={() => fileInputRef.current?.click()}
                    className="text-center text-gray-500 hover:text-gray-700 p-8 rounded-lg m-auto">
                    <h3 className="font-semibold text-lg">
                      Upload one or multiple images
                    </h3>
                    <p>Click to upload or drag & drop</p>
                  </button>
                )}
              </div>
            ) : (
              // Image Gen mode display
              <div
                className={`relative ${baseDisplayClass} border-2 ${
                  generatedImage ? 'border-black' : 'border-gray-400'
                }`}>
                {generatedImage ? (
                  <img
                    src={generatedImage}
                    alt="Generated image"
                    className="max-w-full max-h-full object-contain"
                  />
                ) : (
                  <div className="text-center text-gray-500">
                    <h3 className="font-semibold text-lg">Image Generation</h3>
                    <p>Enter a prompt below to create an image</p>
                  </div>
                )}
              </div>
            )}
          </div>

          {/* Input form */}
          <form onSubmit={handleSubmit} className="w-full">
            <div className="relative">
              <input
                type="text"
                value={prompt}
                onChange={(e) => setPrompt(e.target.value)}
                placeholder={
                  mode === 'imageGen'
                    ? 'Describe the image you want to create...'
                    : mode === 'multi-img-edit'
                    ? 'Describe how to edit or combine the images...'
                    : 'Add your change...'
                }
                className="w-full p-3 sm:p-4 pr-12 sm:pr-14 text-sm sm:text-base border-2 border-black bg-white text-gray-800 shadow-sm focus:ring-2 focus:ring-gray-200 focus:outline-none transition-all"
                required
              />
              <button
                type="submit"
                disabled={isLoading}
                className="absolute right-3 sm:right-4 top-1/2 -translate-y-1/2 p-1.5 sm:p-2 rounded-none bg-black text-white hover:cursor-pointer hover:bg-gray-800 disabled:bg-gray-300 disabled:cursor-not-allowed transition-colors">
                {isLoading ? (
                  <LoaderCircle
                    className="w-5 sm:w-6 h-5 sm:h-6 animate-spin"
                    aria-label="Loading"
                  />
                ) : (
                  <SendHorizontal
                    className="w-5 sm:w-6 h-5 sm:h-6"
                    aria-label="Submit"
                  />
                )}
              </button>
            </div>
          </form>
        </main>
        {/* Error Modal */}
        {showErrorModal && (
          <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
            <div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
              <div className="flex justify-between items-start mb-4">
                <h3 className="text-xl font-bold text-gray-700">
                  Failed to generate
                </h3>
                <button
                  onClick={closeErrorModal}
                  className="text-gray-400 hover:text-gray-500">
                  <X className="w-5 h-5" />
                </button>
              </div>
              <p className="font-medium text-gray-600">
                {parseError(errorMessage)}
              </p>
            </div>
          </div>
        )}
        {/* API Key Modal */}
        {showApiKeyModal && (
          <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
            <div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
              <div className="flex justify-between items-start mb-4">
                <h3 className="text-xl font-bold text-gray-700">
                  Add Gemini API Key
                </h3>
                <button
                  onClick={() => setShowApiKeyModal(false)}
                  className="text-gray-400 hover:text-gray-500">
                  <X className="w-5 h-5" />
                </button>
              </div>
              <p className="text-gray-600 mb-4">
                Add the API key to process the request. The API key will be
                removed if the app page is refreshed or closed.
              </p>
              <form onSubmit={handleApiKeySubmit}>
                <input
                  type="password"
                  name="apiKey"
                  className="w-full p-2 border-2 border-gray-300 rounded-md mb-4"
                  placeholder="Enter your Gemini API Key"
                  required
                />
                <button
                  type="submit"
                  className="w-full bg-black text-white p-2 rounded-md hover:bg-gray-800 transition-colors">
                  Submit
                </button>
              </form>
            </div>
          </div>
        )}
      </div>
    </>
  );
}