import React, { useState, useRef, useEffect, useMemo } from 'react';
import { Post, User, Clash } from '../types';
import { TAG_REPOSITORY } from '../constants';
import { TagIcon } from './icons/TagIcon';
import { EllipsisVerticalIcon } from './icons/EllipsisVerticalIcon';
import { CrownIcon } from './icons/CrownIcon';
import { PencilIcon } from './icons/PencilIcon';
import { XIcon } from './icons/XIcon';
import { ShareIcon } from './icons/ShareIcon';
import { ShieldExclamationIcon } from './icons/ShieldExclamationIcon';

interface PostCardProps {
  post: Post;
  author: User;
  currentUser: User;
  users: User[];
  onVote: (postId: string, tagName: string) => void;
  onSuggest: (postId: string, tagName: string) => void;
  onApproveSuggestion: (postId: string, tagName: string) => void;
  onNavigate: (view: 'profile', userId: string) => void;
  onEdit: (post: Post) => void;
  onDelete: (postId: string, deleterId: string) => void;
  onClashVote: (postId: string, tagToVoteFor: string) => void;
  onShareRequest: (post: Post) => void;
  onReportRequest: (postId: string) => void;
}

const SuggestTagForm: React.FC<{ onSuggest: (tagName: string) => void }> = ({ onSuggest }) => {
    const [suggestion, setSuggestion] = useState('');
    const [filteredTags, setFilteredTags] = useState<string[]>([]);

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const value = e.target.value;
        setSuggestion(value);
        if (value) {
            setFilteredTags(
                TAG_REPOSITORY.filter(tag =>
                    tag.startsWith(value.toLowerCase())
                )
            );
        } else {
            setFilteredTags([]);
        }
    };
    
    const handleTagSelect = (tagName: string) => {
        setSuggestion(tagName);
        setFilteredTags([]);
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        const lowercasedSuggestion = suggestion.trim().toLowerCase();
        if (lowercasedSuggestion && TAG_REPOSITORY.includes(lowercasedSuggestion)) {
            onSuggest(lowercasedSuggestion);
            setSuggestion('');
        }
    };

    return (
        <form onSubmit={handleSubmit} className="relative mt-2">
            <div className="flex gap-2">
                <input
                    type="text"
                    value={suggestion}
                    onChange={handleInputChange}
                    placeholder="Suggest a tag..."
                    className="flex-grow bg-muted border border-accent rounded-full px-4 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary"
                />
                <button type="submit" className="bg-secondary text-primary-foreground px-3 py-1 rounded-full text-sm hover:bg-primary transition-colors">Suggest</button>
            </div>
            {filteredTags.length > 0 && (
                 <ul className="absolute z-10 w-full bg-background border border-gray-200 mt-1 rounded-md shadow-lg max-h-40 overflow-y-auto">
                    {filteredTags.slice(0, 5).map(tag => (
                        <li key={tag}
                            className="px-4 py-2 cursor-pointer hover:bg-muted"
                            onClick={() => handleTagSelect(tag)}>
                            {tag}
                        </li>
                    ))}
                </ul>
            )}
        </form>
    );
};

const TagClashView: React.FC<{ clash: Clash; currentUser: User; onClashVote: (postId: string, tagToVoteFor: string) => void; postId: string }> = ({ clash, currentUser, onClashVote, postId }) => {
    const clashEndTime = useMemo(() => new Date(new Date(clash.startTime).getTime() + 24 * 60 * 60 * 1000), [clash.startTime]);
    const [timeLeft, setTimeLeft] = useState('');

    const isClashActive = useMemo(() => clashEndTime > new Date(), [clashEndTime]);

    useEffect(() => {
        if (!isClashActive) {
            setTimeLeft('Finished');
            return;
        }

        const interval = setInterval(() => {
            const now = new Date();
            const distance = clashEndTime.getTime() - now.getTime();

            if (distance < 0) {
                setTimeLeft('Finished');
                clearInterval(interval);
                return;
            }

            const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            const seconds = Math.floor((distance % (1000 * 60)) / 1000);
            setTimeLeft(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);
        }, 1000);

        return () => clearInterval(interval);
    }, [clashEndTime, isClashActive]);
    
    const totalVotes = clash.votes1 + clash.votes2;
    const percent1 = totalVotes === 0 ? 50 : (clash.votes1 / totalVotes) * 100;
    const percent2 = totalVotes === 0 ? 50 : (clash.votes2 / totalVotes) * 100;

    const userHasVoted = clash.voters.includes(currentUser.id);
    const winner = !isClashActive && totalVotes > 0 ? (clash.votes1 > clash.votes2 ? clash.tag1 : clash.votes2 > clash.votes1 ? clash.tag2 : 'draw') : null;

    return (
        <div className="mt-4 border-2 border-accent rounded-lg p-4">
            <div className="flex justify-between items-center mb-2">
                <h4 className="font-bold text-sm">Tag Clash!</h4>
                <p className="text-sm font-mono bg-muted px-2 py-0.5 rounded">{timeLeft}</p>
            </div>
            <p className="text-sm text-muted-foreground mb-3">Which tag describes this post better?</p>

            <div className="space-y-3">
                <div className="relative">
                    <div className="h-10 bg-muted rounded-full overflow-hidden flex">
                        <div className="bg-yellow-500/20 h-full transition-all duration-500" style={{ width: `${percent1}%` }}></div>
                        <div className="bg-secondary/20 h-full transition-all duration-500" style={{ width: `${percent2}%` }}></div>
                    </div>
                    <div className="absolute inset-0 flex items-center justify-between px-3">
                        <span className="font-semibold text-foreground flex items-center gap-1.5">
                            {winner === clash.tag1 && <CrownIcon className="w-4 h-4 text-yellow-500" />}
                            {clash.tag1} ({clash.votes1})
                        </span>
                        <span className="font-semibold text-foreground flex items-center gap-1.5">
                            ({clash.votes2}) {clash.tag2}
                            {winner === clash.tag2 && <CrownIcon className="w-4 h-4 text-yellow-500" />}
                        </span>
                    </div>
                </div>

                <div className="flex justify-between gap-2">
                    <button 
                        onClick={() => onClashVote(postId, clash.tag1)}
                        disabled={!isClashActive || userHasVoted}
                        className="w-full py-1.5 rounded-full font-semibold bg-primary/10 text-primary border-2 border-primary/20 hover:bg-primary/20 disabled:opacity-50 disabled:cursor-not-allowed"
                    >
                        Vote for {clash.tag1}
                    </button>
                    <button 
                        onClick={() => onClashVote(postId, clash.tag2)}
                        disabled={!isClashActive || userHasVoted}
                        className="w-full py-1.5 rounded-full font-semibold bg-secondary/10 text-secondary border-2 border-secondary/20 hover:bg-secondary/20 disabled:opacity-50 disabled:cursor-not-allowed"
                    >
                        Vote for {clash.tag2}
                    </button>
                </div>
                {userHasVoted && !isClashActive && <p className="text-xs text-center text-muted-foreground">The clash has finished. You voted.</p>}
                {userHasVoted && isClashActive && <p className="text-xs text-center text-muted-foreground">You have already voted in this clash.</p>}
                {winner === 'draw' && <p className="text-xs text-center font-bold text-primary">It's a draw!</p>}
            </div>
        </div>
    );
};

const PostCard: React.FC<PostCardProps> = (props) => {
  const { post, author, currentUser, users, onVote, onSuggest, onApproveSuggestion, onNavigate, onEdit, onDelete, onClashVote, onShareRequest, onReportRequest } = props;
  const isOwner = currentUser.id === author.id;
  const isFollowing = currentUser.following.includes(author.id);
  const [isMenuOpen, setMenuOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  const pendingSuggestions = post.suggestions.filter(s => s.status === 'pending');
  
  const getUserById = (userId: string) => users.find(u => u.id === userId);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
        setMenuOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  return (
    <div className="bg-background rounded-lg border border-accent">
      <div className="p-4 flex items-center justify-between">
        <div className="flex items-center gap-3">
            <img
            src={author.avatar}
            alt={author.username}
            className="w-12 h-12 rounded-full cursor-pointer border-2 border-muted"
            onClick={() => onNavigate('profile', author.id)}
            />
            <div>
            <p 
                className="font-bold cursor-pointer hover:underline"
                onClick={() => onNavigate('profile', author.id)}
            >
                {author.username}
            </p>
            <p className="text-sm text-muted-foreground">{new Date(post.createdAt).toLocaleString()}</p>
            </div>
        </div>
        <div className="relative" ref={menuRef}>
            <button onClick={() => setMenuOpen(!isMenuOpen)} className="text-muted-foreground hover:text-foreground p-1 rounded-full">
              <EllipsisVerticalIcon className="w-6 h-6"/>
            </button>
            {isMenuOpen && (
              <div className="absolute right-0 mt-2 w-48 bg-background rounded-md shadow-lg z-20 border border-muted py-1">
                {isOwner ? (
                  <>
                    <button onClick={() => { onEdit(post); setMenuOpen(false); }} className="flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-foreground hover:bg-muted">
                      <PencilIcon className="w-4 h-4" /> Edit Post
                    </button>
                     <button onClick={() => { onShareRequest(post); setMenuOpen(false); }} className="flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-foreground hover:bg-muted">
                      <ShareIcon className="w-4 h-4" /> Share Post
                    </button>
                    <button onClick={() => { onDelete(post.id, currentUser.id); setMenuOpen(false); }} className="flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-destructive hover:bg-muted">
                      <XIcon className="w-4 h-4" /> Delete Post
                    </button>
                  </>
                ) : (
                  <>
                    <button onClick={() => { onShareRequest(post); setMenuOpen(false); }} className="flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-foreground hover:bg-muted">
                       <ShareIcon className="w-4 h-4" /> Share Post
                    </button>
                    <button onClick={() => { onReportRequest(post.id); setMenuOpen(false); }} className="flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-destructive hover:bg-muted">
                       <ShieldExclamationIcon className="w-4 h-4" /> Report Post
                    </button>
                  </>
                )}
              </div>
            )}
        </div>
      </div>
      
      <div 
        className="overflow-hidden bg-muted" 
        style={{ aspectRatio: post.mediaDimensions ? `${post.mediaDimensions.width} / ${post.mediaDimensions.height}` : '16 / 9' }}
      >
        {post.mediaType === 'image' ? (
          <img 
            src={post.mediaUrl} 
            alt={post.caption} 
            className="w-full h-full object-cover" 
            loading="lazy"
          />
        ) : (
          <video 
            src={post.mediaUrl} 
            poster={post.posterUrl}
            controls 
            playsInline
            preload="metadata" 
            className="w-full h-full object-cover"
          >
            Your browser does not support the video tag.
          </video>
        )}
      </div>

      <div className="p-4">
        <p className="mb-4">{post.caption}</p>
        
        {post.clash ? (
            <TagClashView key={`${post.id}-clash`} clash={post.clash} currentUser={currentUser} onClashVote={onClashVote} postId={post.id} />
        ) : (
            <div key={`${post.id}-tags`} className="flex flex-wrap gap-2">
                {post.tags.sort((a,b) => b.count - a.count).map(tag => (
                    <button
                    key={tag.name}
                    onClick={() => onVote(post.id, tag.name)}
                    disabled={tag.voters.includes(currentUser.id)}
                    className="flex items-center gap-1.5 px-3 py-1.5 bg-muted rounded-full text-sm font-semibold hover:bg-accent transition-colors disabled:cursor-not-allowed disabled:opacity-70"
                    >
                    <TagIcon className="w-4 h-4 text-secondary"/>
                    <span>{tag.name}</span>
                    <span className="text-xs font-bold bg-primary text-primary-foreground rounded-full w-5 h-5 flex items-center justify-center">{tag.count}</span>
                    </button>
                ))}
            </div>
        )}

        { isFollowing && !isOwner && !post.clash && <SuggestTagForm onSuggest={(tagName) => onSuggest(post.id, tagName)} /> }

        {isOwner && pendingSuggestions.length > 0 && !post.clash && (
          <div className="mt-4 border-t border-muted pt-3">
            <h4 className="font-bold text-sm mb-2">Tag Suggestions:</h4>
            <ul className="space-y-2">
              {pendingSuggestions.map(suggestion => {
                const suggester = getUserById(suggestion.userId);
                return (
                  <li key={`${suggestion.tagName}-${suggestion.userId}`} className="flex justify-between items-center text-sm">
                    <span>
                      <strong>{suggestion.tagName}</strong> suggested by <span className="font-semibold cursor-pointer hover:underline" onClick={() => onNavigate('profile', suggestion.userId)}>{suggester?.username || 'a user'}</span>
                    </span>
                    <button 
                      onClick={() => onApproveSuggestion(post.id, suggestion.tagName)}
                      className="bg-primary text-primary-foreground px-2 py-0.5 rounded-md text-xs hover:bg-opacity-80"
                    >
                      Approve
                    </button>
                  </li>
                );
              })}
            </ul>
          </div>
        )}
      </div>
    </div>
  );
};

export default PostCard;