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

interface InputData {
  prompt: string;
  negativePrompt: string;  // New field
  base_model: string;
  steps: number;
  guidance_scale: number;
  frames: number;
  width: number;
  height: number;
  seed: number;
  zoom_in_motion_strength: number;
  zoom_out_motion_strength: number;
  pan_left_motion_strength: number;
  pan_right_motion_strength: number;
  pan_up_motion_strength: number;
  pan_down_motion_strength: number;
  rolling_clockwise_motion_strength: number;
  rolling_anticlockwise_motion_strength: number;
  output_format: string;
}

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: '',
    negativePrompt: '',  
    base_model: 'realisticVisionV20_v20',
    steps: 25,
    guidance_scale: 7.5,
    frames: 16,
    width: 768,
    height: 512,
    seed: -1,
    zoom_in_motion_strength: 0,
    zoom_out_motion_strength: 0,
    pan_left_motion_strength: 0,
    pan_right_motion_strength: 0.75,
    pan_up_motion_strength: 0,
    pan_down_motion_strength: 0,
    rolling_clockwise_motion_strength: 0,
    rolling_anticlockwise_motion_strength: 0,
    output_format: 'mp4'
  });
  
  const [output, setOutput] = useState<OutputData[]>([]);
  const [isLoading, setIsLoading] = useState(false);

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

  useEffect(() => {
    output.forEach(video => {
      console.log('Video URL:', video.prediction.output);
    });
  }, [output]);
  
  const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
    const { name, value } = e.target;
    setInputData((prevData) => ({ ...prevData, [name]: value }));
  };
  
  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setIsLoading(true);
  
    // Automatically convert string numbers to actual numbers
    const payload = Object.fromEntries(
      Object.entries(inputData).map(([key, value]) => {
        return [key, isNaN(Number(value)) ? value : Number(value)];
      })
    );
  
    try {
      const response = await fetch('/api/animatediff', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload),  // use payload here instead of 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: '',
          negativePrompt: '',  
          base_model: 'realisticVisionV20_v20',
          steps: 25,
          guidance_scale: 7.5,
          frames: 16,
          width: 768,
          height: 512,
          seed: -1,
          zoom_in_motion_strength: 0,
          zoom_out_motion_strength: 0,
          pan_left_motion_strength: 0,
          pan_right_motion_strength: 0.75,
          pan_up_motion_strength: 0,
          pan_down_motion_strength: 0,
          rolling_clockwise_motion_strength: 0,
          rolling_anticlockwise_motion_strength: 0,
          output_format: 'mp4'
        });
      }
    } 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">AnimateDiff Generation</h1>
      <form onSubmit={handleSubmit} className="space-y-4">
      {/* Video Settings */}
      <div className="bg-gray-800 p-4 rounded space-y-2">
        <h2 className="text-lg font-bold">Video Settings</h2>
        <div className="flex space-x-4">  {/* Added flex container */}
  <textarea
    name="prompt"
    value={inputData.prompt}
    onChange={handleChange}
    className="p-2 bg-gray-700 rounded border border-gray-600 w-1/2 h-24"
    placeholder="Enter video prompt..."
  ></textarea>
  
  <textarea
    name="negativePrompt"
    value={inputData.negativePrompt}
    onChange={handleChange}
    className="p-2 bg-gray-700 rounded border border-gray-600 w-1/2 h-24"
    placeholder="Enter negative prompt..."
  ></textarea>
</div></div>


{/* Dimensions */}
<div className="bg-gray-800 p-4 rounded space-y-2">
  <label className="block text-lg">Base Settings</label>
  <div className="flex flex-wrap space-x-4">
    <div className="w-1/5">
      <label>Base Model:</label>
      <select 
        name="base_model" 
        value={inputData.base_model} 
        onChange={handleChange} 
        className="p-3 bg-gray-800 rounded border border-gray-600 text-lg w-full">
        {/* Options */}
        <option value="realisticVisionV20_v20">realisticVisionV20_v20</option>
        <option value="lyriel_v16">lyriel_v16</option>
        <option value="majicmixRealistic_v5Preview">majicmixRealistic_v5Preview</option>
        <option value="rcnzCartoon3d_v10">rcnzCartoon3d_v10</option>
        <option value="toonyou_beta3">toonyou_beta3</option>
      </select>
    </div>
   {/* Numeric Inputs */}
{['steps', 'guidance_scale', 'frames', 'width', 'height', 'seed'].map((key) => (
  <div className="w-1/5" key={key}>
    <label>{key.replace('_', ' ').charAt(0).toUpperCase() + key.slice(1)}:</label>
    <input 
      type="number" 
      name={key} 
      value={inputData[key as keyof InputData]} 
      onChange={handleChange} 
      className="p-2 bg-gray-800 rounded border border-gray-600 text-lg w-full" 
    />
  </div>
))}
  </div>
</div>


      
      
      {/* Motion Settings */}
      <div className="bg-gray-800 p-4 rounded space-y-2">
        <h2 className="text-lg font-bold">Motion Settings</h2>
        <div className="flex space-x-4">
        <label>Zoom In: <input type="range" min="0" max="1" step="0.01" name="zoom_in_motion_strength" value={inputData.zoom_in_motion_strength} onChange={handleChange} /><span>{inputData.zoom_in_motion_strength}</span></label>
        <label>Zoom Out: <input type="range" min="0" max="1" step="0.01" name="zoom_out_motion_strength" value={inputData.zoom_out_motion_strength} onChange={handleChange} /><span>{inputData.zoom_out_motion_strength}</span></label>
      </div>
      <label>Pan Left: <input type="range" min="0" max="1" step="0.01" name="pan_left_motion_strength" value={inputData.pan_left_motion_strength} onChange={handleChange} /><span>{inputData.pan_left_motion_strength}</span></label>
      <label>Pan Right: <input type="range" min="0" max="1" step="0.01" name="pan_right_motion_strength" value={inputData.pan_right_motion_strength} onChange={handleChange} /><span>{inputData.pan_right_motion_strength}</span></label>
      <label>Pan Up: <input type="range" min="0" max="1" step="0.01" name="pan_up_motion_strength" value={inputData.pan_up_motion_strength} onChange={handleChange} /><span>{inputData.pan_up_motion_strength}</span></label>
      <label>Pan Down: <input type="range" min="0" max="1" step="0.01" name="pan_down_motion_strength" value={inputData.pan_down_motion_strength} onChange={handleChange} /><span>{inputData.pan_down_motion_strength}</span></label>
      </div>
      
      {/* Output Settings */}
      <div className="bg-gray-800 p-4 rounded space-y-2">
        <h2 className="text-lg font-bold">Output Settings</h2>
        <div className="flex space-x-4">
          <input type="radio" id="mp4" name="output_format" value="mp4" checked={inputData.output_format === 'mp4'} onChange={handleChange} />
          <label htmlFor="mp4">MP4</label>
          <input type="radio" id="gif" name="output_format" value="gif" checked={inputData.output_format === 'gif'} onChange={handleChange} />
          <label htmlFor="gif">GIF</label>
        </div>
      </div>
    
    {/* Submit Button */}
    <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;