import React, { useState, useEffect } from 'react';
import { Post, Tag, Clash } from '../types';
import { TAG_REPOSITORY } from '../constants';
import { XIcon } from './icons/XIcon';
import { TagIcon } from './icons/TagIcon';

// FIX: Updated prop type to reflect that the modal is not responsible for providing the 'reports' field, which resolves the compilation error.
interface CreatePostModalProps {
  onClose: () => void;
  onCreatePost: (postData: Omit<Post, 'id' | 'userId' | 'suggestions' | 'createdAt' | 'reports'>) => void;
}

const CreatePostModal: React.FC<CreatePostModalProps> = ({ onClose, onCreatePost }) => {
  const [mediaFile, setMediaFile] = useState<File | null>(null);
  const [mediaPreview, setMediaPreview] = useState<string | null>(null);
  const [mediaType, setMediaType] = useState<'image' | 'video'>('image');
  const [caption, setCaption] = useState('');
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [tagInput, setTagInput] = useState('');
  const [filteredTags, setFilteredTags] = useState<string[]>([]);
  const [isClashPost, setIsClashPost] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    // Clean up the object URL when the component unmounts or the preview changes
    return () => {
      if (mediaPreview) {
        URL.revokeObjectURL(mediaPreview);
      }
    };
  }, [mediaPreview]);
  
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    setError(null);
    
    // Clear previous state while validating the new file
    setMediaFile(null);
    setMediaPreview(null);

    if (!file) {
      e.target.value = '';
      return;
    }
    
    const isVideo = file.type.startsWith('video');
    const objectUrl = URL.createObjectURL(file);

    if (isVideo) {
      const video = document.createElement('video');
      video.preload = 'metadata';
      
      video.onloadedmetadata = () => {
        if (video.duration > 60) {
          setError("Video is too long. Please select a video that is 60 seconds or less.");
          URL.revokeObjectURL(objectUrl);
          e.target.value = '';
        } else {
          setMediaFile(file);
          setMediaPreview(objectUrl);
          setMediaType('video');
        }
      };

      video.onerror = () => {
          setError("Could not load video metadata. File might be corrupt or in an unsupported format.");
          URL.revokeObjectURL(objectUrl);
          e.target.value = '';
      };
      
      video.src = objectUrl;
    } else { // It's an image
      setMediaFile(file);
      setMediaPreview(objectUrl);
      setMediaType('image');
    }
  };

  const handleTagInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setTagInput(value);
    if (value) {
      const lowercasedValue = value.toLowerCase();
      const limit = isClashPost ? 2 : 15;
      setFilteredTags(
        TAG_REPOSITORY.filter(tag => 
          tag.includes(lowercasedValue) && !selectedTags.includes(tag) && selectedTags.length < limit
        ).slice(0, 5)
      );
    } else {
      setFilteredTags([]);
    }
  };
  
  const addTag = (tagName: string) => {
    const limit = isClashPost ? 2 : 15;
    if (selectedTags.length < limit && !selectedTags.includes(tagName)) {
      setSelectedTags([...selectedTags, tagName]);
    }
    setTagInput('');
    setFilteredTags([]);
  };

  const removeTag = (tagName: string) => {
    setSelectedTags(selectedTags.filter(t => t !== tagName));
  };
  
  const handleClashCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const checked = e.target.checked;
      setIsClashPost(checked);
      // When toggling, clear tags to avoid state confusion (e.g., having 5 tags then checking the box)
      setSelectedTags([]);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!mediaPreview || !mediaFile) {
        setError("Please upload an image or video.");
        return;
    }

    if (isClashPost && selectedTags.length !== 2) {
      setError("Tag Clash posts must have exactly 2 tags.");
      return;
    }

    if (!isClashPost && selectedTags.length === 0) {
        setError("Please add at least one tag.");
        return;
    }
    
    const postTags: Tag[] = selectedTags.map(name => ({
      name,
      count: 0,
      voters: [],
    }));

    let clash: Clash | undefined = undefined;
    if (isClashPost) {
      clash = {
        tag1: selectedTags[0],
        tag2: selectedTags[1],
        votes1: 0,
        votes2: 0,
        voters: [],
        startTime: new Date().toISOString(),
      };
    }

    // Since mediaPreview is an object URL, it's fine for the mock app.
    // In a real app, you'd upload `mediaFile` and use the returned URL.
    onCreatePost({
      mediaUrl: mediaPreview,
      mediaType,
      caption,
      tags: postTags,
      clash,
    });
  };
  
  const tagLimit = isClashPost ? 2 : 15;
  const canAddMoreTags = selectedTags.length < tagLimit;

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
      <div className="bg-background rounded-lg shadow-xl w-full max-w-lg max-h-full overflow-y-auto border border-accent">
        <div className="flex justify-between items-center p-4 border-b border-muted">
          <h2 className="text-xl font-bold">Create New Post</h2>
          <button onClick={onClose} className="text-secondary hover:text-foreground"><XIcon className="w-6 h-6"/></button>
        </div>
        <form onSubmit={handleSubmit}>
          <div className="p-6 space-y-4">
            <div>
              {!mediaPreview ? (
                <div className="border-2 border-dashed border-accent rounded-lg p-8 text-center">
                  <p className="mb-2 text-muted-foreground">Upload Image or Video (60s max)</p>
                  <input type="file" accept="image/*,video/mp4" onChange={handleFileChange} className="block w-full text-sm text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-accent file:text-primary hover:file:bg-gray-200"/>
                  {error && <p className="text-destructive text-sm mt-2">{error}</p>}
                </div>
              ) : (
                <div className="w-full">
                  {mediaType === 'image' ? (
                    <img src={mediaPreview} alt="Preview" className="w-full rounded-lg" />
                  ) : (
                    <video src={mediaPreview} controls className="w-full rounded-lg" />
                  )}
                </div>
              )}
            </div>
            <div>
              <label htmlFor="caption" className="block text-sm font-medium mb-1">Caption</label>
              <textarea id="caption" value={caption} onChange={e => setCaption(e.target.value)} rows={3} className="w-full p-2 border border-accent rounded-md focus:outline-none focus:ring-2 focus:ring-primary bg-muted"></textarea>
            </div>

            <div className="flex items-center space-x-2">
                <input
                    type="checkbox"
                    id="isClashPost"
                    checked={isClashPost}
                    onChange={handleClashCheckboxChange}
                    className="h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary"
                />
                <label htmlFor="isClashPost" className="text-sm font-medium text-foreground">
                    Make it a Tag Clash post
                </label>
            </div>

            <div className="relative">
              <label htmlFor="tags" className="block text-sm font-medium mb-1">
                {isClashPost ? `Select 2 Tags for Clash` : `Tags (up to 15)`}
              </label>
              <input 
                type="text" 
                id="tags" 
                value={tagInput} 
                onChange={handleTagInputChange} 
                placeholder={canAddMoreTags ? "Search and add tags" : "Tag limit reached"}
                className="w-full p-2 border border-accent rounded-md focus:outline-none focus:ring-2 focus:ring-primary bg-muted"
                disabled={!canAddMoreTags}
              />
              {filteredTags.length > 0 && (
                <ul className="absolute z-10 w-full bg-background border border-accent mt-1 rounded-md shadow-lg">
                  {filteredTags.map(tag => (
                    <li key={tag} onClick={() => addTag(tag)} className="px-4 py-2 cursor-pointer hover:bg-muted">{tag}</li>
                  ))}
                </ul>
              )}
            </div>
            <div className="flex flex-wrap gap-2 min-h-[34px]">
              {selectedTags.map(tag => (
                <div key={tag} className="flex items-center gap-1.5 px-3 py-1 bg-muted rounded-full text-sm font-semibold">
                  <TagIcon className="w-4 h-4 text-secondary"/>
                  <span>{tag}</span>
                  <button type="button" onClick={() => removeTag(tag)} className="ml-1 font-bold text-secondary hover:text-destructive"><XIcon className="w-4 h-4"/></button>
                </div>
              ))}
            </div>
            {error && !mediaPreview && <p className="text-destructive text-sm -mt-2">{error}</p>}
          </div>
          <div className="p-4 bg-muted border-t border-accent flex justify-end">
            <button type="submit" disabled={!mediaFile} className="bg-primary text-primary-foreground font-bold py-2 px-6 rounded-full hover:opacity-90 transition-colors disabled:bg-secondary disabled:cursor-not-allowed">Post</button>
          </div>
        </form>
      </div>
    </div>
  );
};

export default CreatePostModal;