import React, { useState, useEffect, FormEvent, ChangeEvent } from 'react';

interface InputData {
  prompt: string;
  width: number;
  height: number;
  steps: number;
  fps: number;
  seed?: number;
}

interface OutputData {
  prediction: any;
  timestamp: string;
  prompt: string;
}
const TruncatedText = ({ text }: { text: string }) => {
  const [isTruncated, setIsTruncated] = useState(true);

  const toggleTruncated = () => {
    setIsTruncated(!isTruncated);
  };

  if (text.length < 34) {
    return <span>{text}</span>;
  }

  return (
    <span>
      {isTruncated ? `${text.substring(0, 24)}...` : text}
      <button onClick={toggleTruncated}>
        {isTruncated ? 'Read More' : 'Read Less'}
      </button>
    </span>
  );
};

const IndexPage = () => {
  const [inputData, setInputData] = useState<InputData>({
    prompt: '',
    width: 1024,
    height: 576,
    steps: 40,
    fps: 15,
    seed: undefined,
  });
  const [output, setOutput] = useState<OutputData[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const savedOutput = localStorage.getItem('output');
    if (savedOutput) {
      setOutput(JSON.parse(savedOutput));
    }
  }, []);

  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    setInputData((prevData) => ({ ...prevData, [name]: value }));
  };

  
  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setIsLoading(true);

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

      const result = await response.json();

      if (response.ok) {
        const timestamp = new Date().toISOString();
        const newOutput = {
          prediction: result.prediction,
          timestamp,
          prompt: inputData.prompt,
        };
        const updatedOutput = [...output, newOutput];
        setOutput(updatedOutput);
        localStorage.setItem('output', JSON.stringify(updatedOutput));
        setInputData({
          prompt: '',
          width: 1024,
          height: 576,
          steps: 40,
          fps: 15,
          seed: undefined,
        });
      }
    } catch (error) {
      console.error("An error occurred:", error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="bg-gray-900 text-white p-4 container mx-auto" style={{ minHeight: '100vh' }}>
      <h1 className="text-2xl mb-4">Video Generation App</h1>
      <form onSubmit={handleSubmit} className="space-y-4">
        <textarea
          name="prompt"
          value={inputData.prompt}
          onChange={handleChange}
          className="p-2 bg-gray-800 rounded border border-gray-600 w-full h-24"
          placeholder="Enter video prompt..."
        ></textarea>
<div className="flex flex-wrap -mx-2">
  <label className="flex flex-col items-center w-full md:w-1/5 px-2">
    <span>Width</span>
    <input type="number" name="width" value={inputData.width} onChange={handleChange} className="p-2 bg-gray-800 rounded border border-gray-600 w-full" />
  </label>
  <label className="flex flex-col items-center w-full md:w-1/5 px-2">
    <span>Height</span>
    <input type="number" name="height" value={inputData.height} onChange={handleChange} className="p-2 bg-gray-800 rounded border border-gray-600 w-full" />
  </label>
  <label className="flex flex-col items-center w-full md:w-1/5 px-2">
    <span>Steps</span>
    <input type="number" name="steps" value={inputData.steps} onChange={handleChange} className="p-2 bg-gray-800 rounded border border-gray-600 w-full" />
  </label>
  <label className="flex flex-col items-center w-full md:w-1/5 px-2">
    <span>FPS</span>
    <input type="number" name="fps" value={inputData.fps} onChange={handleChange} className="p-2 bg-gray-800 rounded border border-gray-600 w-full" />
  </label>
  <label className="flex flex-col items-center w-full md:w-1/5 px-2">
    <span>Seed</span>
    <input type="number" name="seed" value={inputData.seed} onChange={handleChange} className="p-2 bg-gray-800 rounded border border-gray-600 w-full" />
  </label>
</div>


<button 
  type="submit" 
  className={`p-2 px-5 rounded ${isLoading ? 'bg-gray-600' : 'bg-green-600'} text-white`} 
  disabled={isLoading}
  style={{ cursor: isLoading ? 'not-allowed' : 'pointer' }}
>
  {isLoading ? 'Generating...' : 'Generate'}
</button>

      </form>
      <div className="grid lg:grid-cols-3 grid-cols-1 gap-4 mt-8">
        {output.map((video, index) => (
          <div key={index} className="space-y-2">
            <h2 className="text-xl">Generated Video {index + 1}:</h2>
            <div className="relative">
              <video 
                controls
                loop
                width="100%"
                onMouseOver={event => { 
                  event.currentTarget.play();
                  event.currentTarget.setAttribute("controlsList", "nodownload");
                }}
                onMouseOut={event => {
                  event.currentTarget.pause();
                  event.currentTarget.removeAttribute("controlsList");
                }}
              >
                <source src={video.prediction.output} type="video/mp4" />
              </video>
              {/* Download Button */}
              <button 
  onClick={async () => {
    try {
      const response = await fetch(video.prediction.output);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'video.mp4';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch (error) {
      console.error("Failed to download the video", error);
    }
  }}
  className="absolute top-0 right-0 bg-green-600 text-white px-3 py-1 rounded"
>
  Download
</button>

            </div>
            <p>Date: {new Date(video.timestamp).toLocaleDateString()} Time: {new Date(video.timestamp).toLocaleTimeString()}</p>
            <TruncatedText text={video.prompt} />
          </div>
        ))}
      </div>
    </div>
  );
};

export default IndexPage;