// app/page.tsx
'use client';

import { useState, useEffect, useRef } from 'react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import {
  Hash,
  MessageCircle,
  Send,
  Settings,
  Users,
  Image as ImageIcon,
  Plus,
  Edit,
  Trash,
  Menu,
} from 'lucide-react';
import EmojiPicker, { EmojiClickData } from 'emoji-picker-react';
import Image from 'next/image';
import { motion, AnimatePresence } from 'framer-motion';

const defaultAvatarUrl = 'https://via.placeholder.com/40';

// Array de emojis para reações
const reactionEmojis = ['👍', '❤️', '😂', '😮', '😢', '👎'];

type Config = {
  notifications: boolean;
  fontSize: number;
  username: string;
  avatarUrl: string;
  fontFamily: string;
};

type User = {
  username: string;
  avatarUrl: string;
};

type Reaction = {
  emoji: string;
  count: number;
  users: string[];
};

type FileData = {
  name: string;
  type: string;
  data: string;
};

type Message = {
  id: string;
  content: string;
  timestamp: Date;
  user: User;
  file?: FileData;
  reactions: Reaction[];
};

type Channel = {
  id: string;
  name: string;
  messages: Message[];
};

const initialConfig: Config = {
  notifications: true,
  fontSize: 16,
  username: 'Anonymous',
  avatarUrl: '',
  fontFamily: 'sans-serif',
};

const initialChannels: Channel[] = [
  { id: '1', name: 'general', messages: [] },
  { id: '2', name: 'random', messages: [] },
  { id: '3', name: 'announcements', messages: [] },
];

const initialUsers: User[] = [
  { username: 'Alice', avatarUrl: defaultAvatarUrl },
  { username: 'Bob', avatarUrl: defaultAvatarUrl },
  // Adicione mais usuários conforme necessário
];

export default function App() {
  const [config, setConfig] = useState<Config>(initialConfig);
  const [isSettingsOpen, setIsSettingsOpen] = useState(false);
  const [channels, setChannels] = useState<Channel[]>(initialChannels);
  const [activeChannelId, setActiveChannelId] = useState<string>(
    channels[0].id
  );
  const activeChannel =
    channels.find((channel) => channel.id === activeChannelId) || channels[0];
  const [messageInput, setMessageInput] = useState('');
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const [showReactionPicker, setShowReactionPicker] = useState<string | null>(
    null
  );
  const [editingMessageId, setEditingMessageId] = useState<string | null>(null);
  const [users, setUsers] = useState<User[]>(initialUsers);
  const [mentionSuggestions, setMentionSuggestions] = useState<User[]>([]);
  const [caretPosition, setCaretPosition] = useState<number | null>(null);
  const [previewImage, setPreviewImage] = useState<string | null>(null);
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);

  const handleConfigChange = (
    key: keyof Config,
    value: boolean | number | string
  ) => {
    setConfig((prevConfig) => ({ ...prevConfig, [key]: value }));
  };

  const handleChannelSelect = (channel: Channel) => {
    setActiveChannelId(channel.id);
  };

  const handleSendMessage = async () => {
    if (messageInput.trim() === '' && !selectedFile) return;

    let content = messageInput;
    let fileData: FileData | undefined;

    if (selectedFile) {
      const reader = new FileReader();
      reader.readAsDataURL(selectedFile);
      await new Promise((resolve) => {
        reader.onload = () => {
          fileData = {
            name: selectedFile!.name,
            type: selectedFile!.type,
            data: reader.result as string,
          };
          resolve(null);
        };
      });
    }

    if (editingMessageId) {
      // Atualizar mensagem existente
      setChannels((prevChannels) =>
        prevChannels.map((channel) =>
          channel.id === activeChannelId
            ? {
                ...channel,
                messages: channel.messages.map((message) =>
                  message.id === editingMessageId
                    ? { ...message, content, file: fileData }
                    : message
                ),
              }
            : channel
        )
      );
      setEditingMessageId(null);
    } else {
      const newMessage: Message = {
        id: Date.now().toString(),
        content,
        timestamp: new Date(),
        user: {
          username: config.username,
          avatarUrl: config.avatarUrl || defaultAvatarUrl,
        },
        file: fileData,
        reactions: [],
      };

      setChannels((prevChannels) =>
        prevChannels.map((channel) =>
          channel.id === activeChannelId
            ? { ...channel, messages: [...channel.messages, newMessage] }
            : channel
        )
      );
    }

    setMessageInput('');
    setSelectedFile(null);
    setPreviewImage(null);
    setShowEmojiPicker(false);
    setMentionSuggestions([]);
  };

  const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      setSelectedFile(file);
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        setPreviewImage(reader.result as string);
      };
    }
  };

  const handleAddReaction = (messageId: string, emoji: string) => {
    setChannels((prevChannels) =>
      prevChannels.map((channel) =>
        channel.id === activeChannelId
          ? {
              ...channel,
              messages: channel.messages.map((message) => {
                if (message.id === messageId) {
                  const existingReactionIndex = message.reactions.findIndex(
                    (r) => r.emoji === emoji
                  );
                  
                  if (existingReactionIndex > -1) {
                    const existingReaction = message.reactions[existingReactionIndex];
                    if (existingReaction.users.includes(config.username)) {
                      // Remove a reação se o usuário já reagiu
                      const updatedReaction = {
                        ...existingReaction,
                        count: existingReaction.count - 1,
                        users: existingReaction.users.filter((u) => u !== config.username),
                      };
                      
                      if (updatedReaction.count === 0) {
                        // Remove a reação se não houver mais usuários
                        return {
                          ...message,
                          reactions: message.reactions.filter((_, index) => index !== existingReactionIndex),
                        };
                      } else {
                        // Atualiza a reação existente
                        return {
                          ...message,
                          reactions: message.reactions.map((r, index) =>
                            index === existingReactionIndex ? updatedReaction : r
                          ),
                        };
                      }
                    } else {
                      // Adiciona o usuário à reação existente
                      return {
                        ...message,
                        reactions: message.reactions.map((r, index) =>
                          index === existingReactionIndex
                            ? {
                                ...r,
                                count: r.count + 1,
                                users: [...r.users, config.username],
                              }
                            : r
                        ),
                      };
                    }
                  } else {
                    // Adiciona uma nova reação
                    return {
                      ...message,
                      reactions: [
                        ...message.reactions,
                        { emoji, count: 1, users: [config.username] },
                      ],
                    };
                  }
                }
                return message;
              }),
            }
          : channel
      )
    );
    setShowReactionPicker(null);
  };

  const handleEditMessage = (messageId: string) => {
    const messageToEdit = activeChannel.messages.find(
      (m) => m.id === messageId
    );
    if (messageToEdit) {
      setMessageInput(messageToEdit.content);
      setEditingMessageId(messageId);
      if (messageToEdit.file) {
        setSelectedFile(null);
        setPreviewImage(messageToEdit.file.data);
      } else {
        setSelectedFile(null);
        setPreviewImage(null);
      }
    }
  };

  const handleDeleteMessage = (messageId: string) => {
    setChannels((prevChannels) =>
      prevChannels.map((channel) =>
        channel.id === activeChannelId
          ? {
              ...channel,
              messages: channel.messages.filter(
                (message) => message.id !== messageId
              ),
            }
          : channel
      )
    );
  };

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [activeChannel.messages]);

  const handleEmojiSelect = (emojiData: EmojiClickData) => {
    setMessageInput((prev) => prev + emojiData.emoji);
    setShowEmojiPicker(false);
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setMessageInput(value);

    const caret = e.target.selectionStart || 0;
    setCaretPosition(caret);

    const lastAt = value.lastIndexOf('@', caret - 1);
    if (lastAt >= 0) {
      const query = value.substring(lastAt + 1, caret).toLowerCase();
      if (query.length > 0) {
        const suggestions = users.filter((user) =>
          user.username.toLowerCase().startsWith(query)
        );
        setMentionSuggestions(suggestions);
      } else {
        setMentionSuggestions([]);
      }
    } else {
      setMentionSuggestions([]);
    }
  };

  const handleSuggestionClick = (username: string) => {
    if (caretPosition !== null) {
      const lastAt = messageInput.lastIndexOf('@', caretPosition - 1);
      const beforeAt = messageInput.substring(0, lastAt + 1);
      const afterAt = messageInput.substring(caretPosition);
      setMessageInput(beforeAt + username + ' ' + afterAt);
      setMentionSuggestions([]);
    }
  };

  const SettingsModal = () => (
    <Dialog open={isSettingsOpen} onOpenChange={setIsSettingsOpen}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Configurações do Chat</DialogTitle>
        </DialogHeader>
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <Label htmlFor="notifications">Notificações</Label>
            <Switch
              id="notifications"
              checked={config.notifications}
              onCheckedChange={(checked) =>
                handleConfigChange('notifications', checked)
              }
            />
          </div>
          <div className="flex items-center justify-between">
            <Label htmlFor="fontSize">Tamanho da Fonte</Label>
            <Input
              id="fontSize"
              type="number"
              value={config.fontSize}
              onChange={(e) =>
                handleConfigChange('fontSize', parseInt(e.target.value, 10))
              }
              className="w-20"
            />
          </div>
          <div className="flex items-center justify-between">
            <Label htmlFor="username">Nome de Usuário</Label>
            <Input
              id="username"
              value={config.username}
              onChange={(e) => handleConfigChange('username', e.target.value)}
              className="w-48"
            />
          </div>
          <div className="flex items-center justify-between">
            <Label htmlFor="avatarUrl">URL do Avatar</Label>
            <Input
              id="avatarUrl"
              value={config.avatarUrl}
              onChange={(e) => handleConfigChange('avatarUrl', e.target.value)}
              className="w-48"
              placeholder="https://example.com/avatar.png"
            />
          </div>
          <div className="flex items-center justify-between">
            <Label htmlFor="fontFamily">Fonte</Label>
            <select
              id="fontFamily"
              value={config.fontFamily}
              onChange={(e) => handleConfigChange('fontFamily', e.target.value)}
              className="w-48 border rounded-md p-2"
            >
              <option value="sans-serif">Sans Serif</option>
              <option value="serif">Serif</option>
              <option value="monospace">Monospace</option>
            </select>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );

  return (
    <div
      className={`flex h-screen bg-background text-foreground`}
      style={{
        fontSize: `${config.fontSize}px`,
        fontFamily: config.fontFamily,
      }}
    >
      {/* Sidebar */}
      {isSidebarOpen && (
        <div className="w-64 bg-card border-r border-border">
          <div className="p-4">
            <h2 className="text-lg font-bold mb-4">Canais</h2>
            <Input placeholder="Buscar canais" className="mb-4" />
            <div className="space-y-2">
              {channels.map((channel) => (
                <Button
                  key={channel.id}
                  variant={
                    channel.id === activeChannelId ? 'secondary' : 'ghost'
                  }
                  className="w-full justify-start"
                  onClick={() => handleChannelSelect(channel)}
                >
                  <Hash className="h-4 w-4 mr-2" />
                  {channel.name}
                </Button>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* Main Content */}
      <div className="flex-1 flex flex-col">
        <header className="bg-card border-b border-border p-4 flex items-center justify-between">
          <div className="flex items-center space-x-2">
            <Button
              variant="ghost"
              className="md:hidden"
              onClick={() => setIsSidebarOpen(!isSidebarOpen)}
            >
              <Menu className="h-6 w-6" />
            </Button>
            <h1 className="text-2xl font-bold">#{activeChannel.name}</h1>
          </div>
          <Button
            variant="ghost"
            className="rounded-full p-2"
            onClick={() => setIsSettingsOpen(true)}
          >
            <Settings className="h-6 w-6 text-muted-foreground" />
          </Button>
        </header>
        <div className="flex-1 p-6 overflow-auto">
          <div className="space-y-4">
            <AnimatePresence>
              {activeChannel.messages.map((message) => (
                <motion.div
                  key={message.id}
                  initial={{ opacity: 0, y: 10 }}
                  animate={{ opacity: 1, y: 0 }}
                  exit={{ opacity: 0, x: -100 }}
                >
                  <Card className="p-4 bg-popover text-popover-foreground relative">
                    <div className="flex items-start space-x-4">
                      <Avatar>
                        <AvatarImage
                          src={message.user.avatarUrl}
                          alt={message.user.username}
                        />
                        <AvatarFallback>
                          {message.user.username.charAt(0).toUpperCase()}
                        </AvatarFallback>
                      </Avatar>
                      <div>
                        <p className="font-semibold">{message.user.username}</p>
                        <p>{message.content}</p>
                        {message.file && (
                          <div className="mt-2">
                            {message.file.type.startsWith('image/') ? (
                              <Image
                                src={message.file.data}
                                alt={message.file.name}
                                width={200}
                                height={200}
                                style={{ objectFit: 'contain' }}
                                unoptimized
                              />
                            ) : (
                              <a
                                href={message.file.data}
                                download={message.file.name}
                                className="text-blue-500 underline"
                              >
                                {message.file.name}
                              </a>
                            )}
                          </div>
                        )}
                        <div className="flex items-center space-x-2 mt-2 relative">
                          {/* Reactions */}
                          {message.reactions.map((reaction) => (
                            <Button
                              key={reaction.emoji}
                              variant="ghost"
                              size="sm"
                              onClick={() =>
                                handleAddReaction(message.id, reaction.emoji)
                              }
                            >
                              {reaction.emoji} {reaction.count}
                            </Button>
                          ))}
                          {/* Reaction Picker */}
                          {showReactionPicker === message.id ? (
                            <div className="flex items-center space-x-2">
                              {reactionEmojis.map((emoji) => (
                                <button
                                  key={emoji}
                                  onClick={() => {
                                    handleAddReaction(message.id, emoji);
                                    setShowReactionPicker(null);
                                  }}
                                  className="text-xl"
                                >
                                  {emoji}
                                </button>
                              ))}
                            </div>
                          ) : (
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => setShowReactionPicker(message.id)}
                            >
                              <Plus className="h-4 w-4" />
                            </Button>
                          )}
                        </div>
                        <p className="text-xs text-muted-foreground mt-2">
                          {message.timestamp.toLocaleString()}
                        </p>
                      </div>
                    </div>
                    {message.user.username === config.username && (
                      <div className="absolute top-2 right-2 flex space-x-2">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => handleEditMessage(message.id)}
                        >
                          <Edit className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => handleDeleteMessage(message.id)}
                        >
                          <Trash className="h-4 w-4" />
                        </Button>
                      </div>
                    )}
                  </Card>
                </motion.div>
              ))}
            </AnimatePresence>
            <div ref={messagesEndRef} />
          </div>
        </div>
        <div className="p-4 bg-card border-t border-border relative">
          <div className="flex space-x-2">
            <Input
              value={messageInput}
              onChange={handleInputChange}
              placeholder={
                editingMessageId ? 'Editar sua mensagem...' : 'Digite uma mensagem...'
              }
              onKeyPress={(e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                  e.preventDefault();
                  handleSendMessage();
                }
              }}
              className="flex-1"
            />
            <Button onClick={() => setShowEmojiPicker(!showEmojiPicker)}>
              😊
            </Button>
            {showEmojiPicker && (
              <div className="absolute bottom-16 z-10">
                <EmojiPicker
                  onEmojiClick={handleEmojiSelect}
                />
              </div>
            )}
            <Button onClick={() => fileInputRef.current?.click()}>
              <ImageIcon className="h-4 w-4" />
            </Button>
            <input
              type="file"
              ref={fileInputRef}
              style={{ display: 'none' }}
              onChange={handleFileUpload}
              accept="*/*"
            />
            <Button onClick={handleSendMessage}>
              <Send className="h-4 w-4" />
            </Button>
          </div>
          {mentionSuggestions.length > 0 && (
            <div className="absolute bg-card border border-border mt-1 w-64 max-h-40 overflow-auto z-10">
              {mentionSuggestions.map((user) => (
                <div
                  key={user.username}
                  className="p-2 hover:bg-secondary cursor-pointer"
                  onClick={() => handleSuggestionClick(user.username)}
                >
                  {user.username}
                </div>
              ))}
            </div>
          )}
          {selectedFile && previewImage && (
            <div className="mt-2">
              {selectedFile.type.startsWith('image/') ? (
                <div className="relative w-20 h-20">
                  <Image
                    src={previewImage}
                    alt="Pré-visualização da Imagem"
                    fill
                    style={{ objectFit: 'cover' }}
                    className="rounded-md"
                    unoptimized
                  />
                  <Button
                    variant="destructive"
                    size="sm"
                    className="absolute top-0 right-0"
                    onClick={() => {
                      setSelectedFile(null);
                      setPreviewImage(null);
                    }}
                  >
                    <Trash className="h-4 w-4" />
                  </Button>
                </div>
              ) : (
                <div className="flex items-center space-x-2">
                  <p className="text-sm text-muted-foreground">
                    Arquivo selecionado: {selectedFile.name}
                  </p>
                  <Button
                    variant="destructive"
                    size="sm"
                    onClick={() => {
                      setSelectedFile(null);
                      setPreviewImage(null);
                    }}
                  >
                    <Trash className="h-4 w-4" />
                  </Button>
                </div>
              )}
            </div>
          )}
        </div>
      </div>
      <SettingsModal />
    </div>
  );
}

agr vc pode add mais reações usando emoji-picker-react na hora de add a reação, consegue add se uma mesma pessoa repitir o mesmo emoji muda o contador para 2 3 4 ...