import { useState, useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  X,
  Camera,
  Edit3,
  Check,
  Loader2,
  UserPlus,
  Trash2,
  Search,
  Crown,
  Users,
  ImageIcon,
  FileText,
  Link as LinkIcon,
  Play,
  Download,
  ExternalLink,
  Video
} from 'lucide-react';
import Cropper from 'react-easy-crop';
import { ChatApi } from '../../infrastructure/chatApi';
import { UserApi } from '../../../users/infrastructure/userApi';
import { useAuthStore } from '../../../auth/application/authStore';
import { useChatStore } from '../../application/chatStore';
import { useLang } from '../../../../core/infrastructure/i18n';
import { Chat, UserPresence, Message } from '../../../../core/domain/types';
import Avatar from '../../../../core/presentation/components/ui/Avatar';
import ConfirmModal from '../../../../core/presentation/components/ui/ConfirmModal';
import ImageLightbox from '../../../../core/presentation/components/ui/ImageLightbox';
import { getMediaUrl } from '../../../../core/utils/utils';
import { getCroppedImg } from '../../../../core/infrastructure/imageCrop';

interface GroupSettingsProps {
  chat: Chat;
  onClose: () => void;
  onGoToMessage?: (messageId: string, sequenceId?: number) => void;
}

export default function GroupSettings({ chat, onClose, onGoToMessage }: GroupSettingsProps) {
  const { user } = useAuthStore();
  const { updateChat } = useChatStore();
  const { t, lang } = useLang();

  const currentMember = chat.members.find((m) => m.user.id === user?.id);
  const [removeTargetId, setRemoveTargetId] = useState<string | null>(null);
  const isAdmin = ['admin', 'owner', 'Admin', 'Owner'].includes(currentMember?.role || '');

  const [isEditingName, setIsEditingName] = useState(false);
  const [isEditingDesc, setIsEditingDesc] = useState(false);
  const [groupName, setGroupName] = useState(chat.name || '');
  const [groupDesc, setGroupDesc] = useState(chat.description || '');
  const [isSaving, setIsSaving] = useState(false);
  const [avatarUploading, setAvatarUploading] = useState(false);
  const [showAddMember, setShowAddMember] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<UserPresence[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [activeTab, setActiveTab] = useState<'members' | 'gifs' | 'media' | 'files' | 'links'>('members');
  const [tabLoading, setTabLoading] = useState(false);
  const [sharedMedia, setSharedMedia] = useState<Message[]>([]);
  const [sharedGifs, setSharedGifs] = useState<Message[]>([]);
  const [sharedFiles, setSharedFiles] = useState<Message[]>([]);
  const [sharedLinks, setSharedLinks] = useState<Array<Message & { links?: string[] }>>([]);
  const [loadedTabs, setLoadedTabs] = useState<Set<string>>(new Set());
  const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);

  // Cropping states
  const [isCropping, setIsCropping] = useState(false);
  const [cropImage, setCropImage] = useState<string | null>(null);
  const [cropFile, setCropFile] = useState<File | null>(null);
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState<any>(null);

  const fileInputRef = useRef<HTMLInputElement>(null);
  const searchInputRef = useRef<HTMLInputElement>(null);

  // Keep local state in sync with chat prop
  useEffect(() => {
    setGroupName(chat.name || '');
    setGroupDesc(chat.description || '');
  }, [chat.name, chat.description]);

  // Search users to add
  useEffect(() => {
    if (!searchQuery.trim()) {
      setSearchResults([]);
      return;
    }
    const timer = setTimeout(async () => {
      try {
        setIsSearching(true);
        const results = await UserApi.searchUsers(searchQuery);
        // Filter out users already in the group
        const memberIds = new Set(chat.members.map((m) => m.user.id));
        setSearchResults(results.filter((u) => !memberIds.has(u.id)));
      } catch (e) {
        console.error(e);
      } finally {
        setIsSearching(false);
      }
    }, 300);
    return () => clearTimeout(timer);
  }, [searchQuery, chat.members]);

  const handleSaveName = async () => {
    if (!groupName.trim()) return;
    try {
      setIsSaving(true);
      const updatedChat = await ChatApi.updateGroup(chat.id, { name: groupName.trim() });
      updateChat(updatedChat);
      setIsEditingName(false);
    } catch (e) {
      console.error(e);
    } finally {
      setIsSaving(false);
    }
  };

  const handleSaveDesc = async () => {
    try {
      setIsSaving(true);
      const updatedChat = await ChatApi.updateGroup(chat.id, { description: groupDesc.trim() });
      updateChat(updatedChat);
      setIsEditingDesc(false);
    } catch (e) {
      console.error(e);
    } finally {
      setIsSaving(false);
    }
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = () => {
        setCropImage(reader.result as string);
        setCropFile(file);
        setIsCropping(true);
      };
      reader.readAsDataURL(file);
    }
  };

  const handleCropSave = async () => {
    if (!cropImage || !croppedAreaPixels) return;
    setAvatarUploading(true);
    try {
      const croppedFile = await getCroppedImg(cropImage, croppedAreaPixels);
      if (!croppedFile) throw new Error("Could not crop image");

      const updatedChat = await ChatApi.uploadGroupAvatar(chat.id, croppedFile);

      useChatStore.getState().updateChat({ ...chat, avatar: updatedChat.avatar });
      setIsCropping(false);
      setCropImage(null);
      setCropFile(null);
    } catch (err) {
      console.error('Failed to crop group avatar:', err);
      alert(t('error'));
    } finally {
      setAvatarUploading(false);
    }
  };

  const handleAvatarUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    try {
      setAvatarUploading(true);
      const updatedChat = await ChatApi.uploadGroupAvatar(chat.id, file);
      updateChat(updatedChat);
    } catch (e) {
      console.error(e);
    } finally {
      setAvatarUploading(false);
      e.target.value = '';
    }
  };

  const handleRemoveAvatar = async () => {
    try {
      setAvatarUploading(true);
      const updatedChat = await ChatApi.removeGroupAvatar(chat.id);
      updateChat(updatedChat);
    } catch (e) {
      console.error(e);
    } finally {
      setAvatarUploading(false);
    }
  };

  const handleAddMember = async (userId: string) => {
    try {
      const updatedChat = await ChatApi.addGroupMembers(chat.id, [userId]);
      updateChat(updatedChat);
      setSearchQuery('');
      setSearchResults([]);
    } catch (e) {
      console.error(e);
    }
  };

  const handleRemoveMember = async (userId: string) => {
    setRemoveTargetId(userId);
  };

  const confirmRemoveMember = async () => {
    if (!removeTargetId) return;
    try {
      const updatedChat = await ChatApi.removeGroupMember(chat.id, removeTargetId);
      updateChat(updatedChat);
    } catch (e) {
      console.error(e);
    }
    setRemoveTargetId(null);
  };

  const initials = (chat.name || 'G')
    .split(' ')
    .map((w: string) => w[0])
    .join('')
    .slice(0, 2)
    .toUpperCase();

  const loadTabData = async (tab: 'gifs' | 'media' | 'files' | 'links') => {
    if (loadedTabs.has(tab)) return;
    setTabLoading(true);
    try {
      const data = await ChatApi.getSharedMedia(chat.id, tab);
      if (tab === 'media') setSharedMedia(data);
      else if (tab === 'gifs') setSharedGifs(data);
      else if (tab === 'files') setSharedFiles(data);
      else setSharedLinks(data);
      setLoadedTabs(prev => new Set(prev).add(tab));
    } catch (e) {
      console.error('Failed to load shared', tab, e);
    } finally {
      setTabLoading(false);
    }
  };

  useEffect(() => {
    loadTabData('gifs');
    loadTabData('media');
    loadTabData('files');
    loadTabData('links');
  }, [chat.id]);

  const API_URL = import.meta.env.VITE_API_URL || '';
  const allMedia = sharedMedia.flatMap(msg => (msg.media || []).map(m => ({
    ...m,
    url: getMediaUrl(m.url),
    thumbnail: m.thumbnail ? getMediaUrl(m.thumbnail) : undefined,
    messageId: msg.id,
    createdAt: msg.createdAt,
    sequenceId: msg.sequenceId
  })));

  const allGifs = sharedGifs.flatMap(msg => (msg.media || []).map(m => ({
    ...m,
    url: getMediaUrl(m.url),
    thumbnail: m.thumbnail ? getMediaUrl(m.thumbnail) : undefined,
    messageId: msg.id,
    createdAt: msg.createdAt,
    sequenceId: msg.sequenceId
  })));

  const sortedMedia = [...allMedia].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  const sortedGifs = [...allGifs].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  const sortedFiles = [...sharedFiles].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  const sortedLinks = [...sharedLinks].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());

  const renderGrouped = <T extends { createdAt: string }>(
    sortedItems: T[],
    renderItem: (item: T, originalIndex: number) => React.ReactNode,
    gridClass?: string
  ) => {
    let currentGroup: { dateStr: string; items: {item: T, idx: number}[] } | null = null;
    const groups: { dateStr: string; items: {item: T, idx: number}[] }[] = [];
    
    sortedItems.forEach((item, idx) => {
      const date = new Date(item.createdAt);
      const dateStr = date.toLocaleDateString(lang === 'ru' ? 'ru-RU' : 'en-US', { day: 'numeric', month: 'long', year: 'numeric' });
      if (currentGroup?.dateStr !== dateStr) {
        currentGroup = { dateStr, items: [] };
        groups.push(currentGroup);
      }
      currentGroup.items.push({item, idx});
    });

    return (
      <div className="flex flex-col gap-4 pb-4 px-1">
        {groups.map((g, i) => (
          <div key={i}>
            <div className="sticky top-0 z-10 bg-black/60 backdrop-blur-md px-3 py-1.5 mb-1.5 shadow-sm border-y border-white/5">
              <span className="text-[10px] font-bold text-knot-300 uppercase tracking-widest">{g.dateStr}</span>
            </div>
            <div className={gridClass || "flex flex-col gap-0.5"}>
              {g.items.map(({item, idx}) => renderItem(item, idx))}
            </div>
          </div>
        ))}
      </div>
    );
  };

  const tabsConfig = [
    { key: 'members' as const, label: t('membersCount') || 'Участники', icon: Users, count: chat.members.length },
    { key: 'gifs' as const, label: 'GIF', icon: Play, count: sortedGifs.length },
    { key: 'media' as const, label: t('mediaTab') || 'Медиа', icon: ImageIcon, count: sortedMedia.length },
    { key: 'files' as const, label: t('filesTab') || 'Файлы', icon: FileText, count: sortedFiles.flatMap(msg => msg.media || []).length },
    { key: 'links' as const, label: t('linksTab') || 'Ссылки', icon: LinkIcon, count: sortedLinks.flatMap(msg => msg.links || []).length },
  ];

  const availableTabs = tabsConfig.filter(tab => tab.key === 'members' || !loadedTabs.has(tab.key) || tab.count > 0);

  useEffect(() => {
    if (loadedTabs.size === 4 && availableTabs.length > 0 && !availableTabs.find(t => t.key === activeTab)) {
      setActiveTab(availableTabs[0].key);
    }
  }, [loadedTabs, activeTab]); // availableTabs removed from dependencies to avoid infinite loops since its reference runs on every render

  return (
    <>
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        className="fixed inset-0 bg-black/60 z-50"
        onClick={onClose}
      />
      <motion.div
        initial={{ opacity: 0, x: 50, scale: 0.95 }}
        animate={{ opacity: 1, x: 0, scale: 1 }}
        exit={{ opacity: 0, x: 50, scale: 0.95 }}
        transition={{ type: 'spring', damping: 25, stiffness: 300 }}
        className="fixed inset-0 lg:inset-auto lg:right-3 lg:top-3 lg:bottom-3 w-full lg:w-[900px] lg:max-w-[calc(100%-24px)] bg-surface-secondary/90 backdrop-blur-3xl shadow-2xl shadow-black/80 border-none lg:border lg:border-white/5 lg:rounded-[2rem] z-50 flex flex-col overflow-hidden ring-1 ring-white/10"
      >
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-border/40">
          <h2 className="text-lg font-semibold text-white">{t('groupSettings')}</h2>
          <button
            onClick={onClose}
            className="p-1.5 rounded-xl text-zinc-400 hover:text-white hover:bg-surface-hover transition-colors"
          >
            <X size={18} />
          </button>
        </div>

        <div className="flex-1 flex flex-col overflow-hidden">
          {/* Avatar */}
          <div className="flex-shrink-0 flex flex-col items-center py-6 px-6 overflow-y-auto max-h-[50%] custom-scrollbar">
            <div className="relative group">
              <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-40 h-40 bg-knot-500/20 rounded-[3rem] blur-[40px] pointer-events-none" />
              <div className="relative z-10 p-1.5 rounded-[2.5rem] bg-gradient-to-br from-white/10 to-transparent backdrop-blur-md border border-white/10 shadow-2xl">
                <Avatar
                  src={chat.avatar ? getMediaUrl(chat.avatar) : null}
                  name={chat.name || '?'}
                  size="2xl"
                  className="shadow-inner"
                />
              </div>

              {isAdmin && (
                <>
                  <button
                    onClick={() => fileInputRef.current?.click()}
                    disabled={avatarUploading}
                    className="absolute inset-0 rounded-full bg-black/50 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity"
                  >
                    {avatarUploading ? (
                      <Loader2 size={32} className="text-white animate-spin" />
                    ) : (
                      <Camera size={32} className="text-white" />
                    )}
                  </button>
                  {chat.avatar && !avatarUploading && (
                    <button
                      onClick={async (e) => {
                        e.stopPropagation();
                        try {
                          const updatedChat = await ChatApi.removeGroupAvatar(chat.id);
                          updateChat(updatedChat);
                        } catch (e) {
                          console.error('Failed to remove avatar', e);
                        }
                      }}
                      className="absolute bottom-0 right-0 p-2 rounded-full bg-red-500/90 text-white opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-500"
                    >
                      <Trash2 size={16} />
                    </button>
                  )}
                </>
              )}
            </div>

            <div className="mt-4 flex flex-col items-center gap-2">
              {isEditingName ? (
                <div className="flex items-center gap-2">
                  <input
                    type="text"
                    value={groupName}
                    onChange={(e) => setGroupName(e.target.value)}
                    className="bg-surface-tertiary border border-accent/30 rounded-xl px-4 py-2 text-lg font-bold text-white text-center focus:outline-none focus:border-accent"
                    autoFocus
                  />
                  <button
                    onClick={handleSaveName}
                    disabled={isSaving}
                    className="p-2 rounded-lg bg-accent text-white hover:bg-accent-light transition-colors"
                  >
                    {isSaving ? <Loader2 size={16} className="animate-spin" /> : <Check size={16} />}
                  </button>
                  <button
                    onClick={() => { setIsEditingName(false); setGroupName(chat.name || ''); }}
                    className="p-2 rounded-lg bg-surface-tertiary text-zinc-400 hover:text-white transition-colors"
                  >
                    <X size={16} />
                  </button>
                </div>
              ) : (
                <div 
                  className="group/name flex items-center gap-2 cursor-pointer"
                  onClick={() => isAdmin && setIsEditingName(true)}
                >
                  <h3 className="text-2xl font-bold text-white tracking-tight">
                    {chat.name || t('group')}
                  </h3>
                  {isAdmin && (
                    <Edit3 size={16} className="text-knot-400 opacity-0 group-hover/name:opacity-100 transition-opacity" />
                  )}
                </div>
              )}
              <p className="text-zinc-500 text-sm">
                {chat.members.length} {t('members')}
              </p>
            </div>

            {/* Description */}
            <div className="mt-6 w-full space-y-2">
              <label className="text-[10px] font-bold text-zinc-500 uppercase tracking-widest px-1">
                {t('groupDescription')}
              </label>
                {isEditingDesc ? (
                  <div className="flex items-center gap-2">
                    <textarea
                      value={groupDesc}
                      onChange={(e) => setGroupDesc(e.target.value)}
                      className="flex-1 bg-surface-tertiary border border-accent/30 rounded-xl px-3 py-2 text-sm text-white focus:outline-none min-h-[80px]"
                      autoFocus
                    />
                    <div className="flex flex-col gap-2">
                      <button
                        onClick={handleSaveDesc}
                        disabled={isSaving}
                        className="p-2 rounded-lg bg-accent text-white hover:bg-accent-light transition-colors"
                      >
                        {isSaving ? <Loader2 size={16} className="animate-spin" /> : <Check size={16} />}
                      </button>
                      <button
                        onClick={() => { setIsEditingDesc(false); setGroupDesc(chat.description || ''); }}
                        className="p-2 rounded-lg bg-surface-tertiary text-zinc-400 hover:text-white transition-colors"
                      >
                        <X size={16} />
                      </button>
                    </div>
                  </div>
                ) : (
                  <div 
                    onClick={() => isAdmin && setIsEditingDesc(true)}
                    className={`group/desc relative p-3 rounded-xl border border-white/5 bg-white/5 transition-all ${isAdmin ? 'cursor-pointer hover:bg-white/10 hover:border-white/10' : ''}`}
                  >
                    <p className={`text-sm ${groupDesc ? 'text-zinc-300' : 'text-zinc-600 italic'}`}>
                      {groupDesc || t('noDescription')}
                    </p>
                    {isAdmin && (
                      <div className="absolute top-3 right-3 opacity-0 group-hover/desc:opacity-100 transition-opacity">
                        <Edit3 size={14} className="text-knot-400" />
                      </div>
                    )}
                  </div>
                )}
              </div>


          </div>


          {/* Media / Files / Links Tabs */}
          {availableTabs.length > 0 ? (
            <div className="mx-4 mb-6 border border-white/5 bg-black/20 rounded-2xl overflow-hidden backdrop-blur-xl flex flex-col flex-1 min-h-0">
              <div className="flex border-b border-white/5">
                {availableTabs.map((tab) => (
                  <button
                    key={tab.key}
                    onClick={() => setActiveTab(tab.key)}
                    className={`flex-1 flex flex-col items-center justify-center gap-2 py-4 text-[10px] font-black uppercase tracking-wider transition-all ${
                      activeTab === tab.key
                        ? 'bg-white/10 text-knot-400 shadow-[inset_0_-2px_0_0_#A855F7]'
                        : 'text-zinc-500 hover:text-zinc-400'
                    }`}
                  >
                    <div className="flex items-center gap-1.5 mb-0.5">
                      <tab.icon size={16} />
                      {(loadedTabs.has(tab.key) || tab.key === 'members') && <span className="text-xs bg-black/40 px-1.5 rounded-full">{tab.count}</span>}
                    </div>
                    <span className="truncate w-full px-1">{tab.label as string}</span>
                  </button>
                ))}
              </div>

              <div className="flex-1 overflow-y-auto custom-scrollbar">
              {tabLoading ? (
                <div className="flex items-center justify-center py-10">
                  <Loader2 size={24} className="text-zinc-500 animate-spin" />
                </div>
              ) : activeTab === 'members' ? (
          <div className="px-4 py-4 pt-2">
            <div className="flex items-center justify-between mb-3">
              <h4 className="text-[10px] font-bold text-zinc-500 uppercase tracking-widest">
                {t('membersCount')}
              </h4>
              {isAdmin && (
                <button
                  onClick={() => {
                    setShowAddMember(!showAddMember);
                    if (!showAddMember) {
                      setTimeout(() => searchInputRef.current?.focus(), 100);
                    }
                  }}
                  className="flex items-center gap-1 text-xs text-knot-400 hover:text-knot-300 transition-colors"
                >
                  <UserPlus size={14} />
                  {t('addMember')}
                </button>
              )}
            </div>

            {/* Add member search */}
            <AnimatePresence>
              {showAddMember && (
                <motion.div
                  initial={{ height: 0, opacity: 0 }}
                  animate={{ height: 'auto', opacity: 1 }}
                  exit={{ height: 0, opacity: 0 }}
                  className="overflow-hidden mb-3"
                >
                  <div className="relative mb-2">
                    <Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500" />
                    <input
                      ref={searchInputRef}
                      type="text"
                      value={searchQuery}
                      onChange={(e) => setSearchQuery(e.target.value)}
                      placeholder={t('findUser')}
                      className="w-full pl-8 pr-3 py-2 rounded-xl bg-surface-tertiary text-sm text-white placeholder-zinc-500 border border-border focus:border-accent transition-colors"
                    />
                  </div>
                  {isSearching && (
                    <div className="flex justify-center py-2">
                      <Loader2 size={16} className="text-zinc-500 animate-spin" />
                    </div>
                  )}
                  {searchResults.map((u) => (
                    <button
                      key={u.id}
                      onClick={() => handleAddMember(u.id)}
                      className="flex items-center gap-3 w-full px-3 py-2 rounded-xl hover:bg-surface-hover transition-colors"
                    >
                      <Avatar 
                        src={u.avatar ? getMediaUrl(u.avatar) : null} 
                        name={u.displayName || u.username || '?'} 
                        size="sm" 
                        online={u.isOnline}
                      />
                      <div className="flex-1 text-left min-w-0">
                        <p className="text-sm text-white truncate">{u.displayName || u.username}</p>
                        <p className="text-xs text-zinc-500">@{u.username}</p>
                      </div>
                      <UserPlus size={14} className="text-knot-400 flex-shrink-0" />
                    </button>
                  ))}
                  {searchQuery.trim() && !isSearching && searchResults.length === 0 && (
                    <p className="text-xs text-zinc-500 text-center py-2">{t('usersNotFound')}</p>
                  )}
                </motion.div>
              )}
            </AnimatePresence>

            {/* Member list */}
            <div className="space-y-1">
              {[...chat.members]
                .sort((a, b) => {
                  if (a.user.id === user?.id) return -1;
                  if (b.user.id === user?.id) return 1;
                  const aIsAdmin = ['admin', 'owner', 'Admin', 'Owner'].includes(a.role || '');
                  const bIsAdmin = ['admin', 'owner', 'Admin', 'Owner'].includes(b.role || '');
                  if (aIsAdmin && !bIsAdmin) return -1;
                  if (bIsAdmin && !aIsAdmin) return 1;
                  return 0;
                })
                .map((member) => (
                  <div
                    key={member.user.id}
                    className="flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-surface-hover/50 transition-colors group"
                  >
                    <div className="relative flex-shrink-0">
                      <Avatar 
                        src={member.user.avatar ? getMediaUrl(member.user.avatar) : null} 
                        name={member.user.displayName || member.user.username || '?'} 
                        size="sm" 
                        online={member.user.isOnline}
                      />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <p className="text-sm font-medium text-white truncate">
                          {member.user.displayName || member.user.username}
                          {member.user.id === user?.id && (
                            <span className="text-zinc-500 ml-1 text-xs">({t('you') || 'вы'})</span>
                          )}
                        </p>
                        {['admin', 'owner', 'Admin', 'Owner'].includes(member.role || '') && (
                          <span className="flex items-center gap-0.5 px-1.5 py-0.5 rounded-md bg-amber-500/10 text-amber-400 text-[10px] font-medium flex-shrink-0">
                            <Crown size={10} />
                            {t('adminBadge') || 'Админ'}
                          </span>
                        )}
                      </div>
                      <p className="text-xs text-zinc-500">@{member.user.username}</p>
                    </div>
                    {isAdmin && member.user.id !== user?.id && !['admin', 'owner', 'Admin', 'Owner'].includes(member.role || '') && (
                      <button
                        onClick={() => handleRemoveMember(member.user.id)}
                        className="p-1.5 rounded-lg text-zinc-500 hover:text-red-400 hover:bg-red-500/10 opacity-0 group-hover:opacity-100 transition-all flex-shrink-0"
                        title={t('removeMember')}
                      >
                        <Trash2 size={14} />
                      </button>
                    )}
                  </div>
                ))}
            </div>
          </div>
              ) : activeTab === 'gifs' ? (
                sortedGifs.length > 0 ? (
                  renderGrouped(sortedGifs, (m, idx) => (
                      <div
                        key={m.id}
                        onClick={() => setLightboxIndex(idx)}
                        className="relative aspect-square bg-zinc-900 overflow-hidden cursor-pointer group"
                      >
                       {(m.url?.toLowerCase().endsWith('.gif') || m.filename?.toLowerCase().endsWith('.gif')) ? (
                         <img
                           src={getMediaUrl(m.url)}
                           alt=""
                           className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
                         />
                       ) : (
                         <video
                           src={getMediaUrl(m.url)}
                           autoPlay
                           loop
                           muted
                           playsInline
                           className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
                         />
                       )}
                        <button
                          onClick={(e) => { e.stopPropagation(); onGoToMessage?.(m.messageId, m.sequenceId); }}
                          className="absolute bottom-2 right-2 px-2 py-1 rounded-md bg-black/60 backdrop-blur-sm flex items-center justify-center text-white text-[10px] font-medium opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/80 shadow-md"
                        >
                          {t('showInChat')}
                        </button>
                      </div>
                    ), "grid grid-cols-3 gap-0.5 px-1")
                ) : (
                  <div className="flex items-center justify-center py-10 px-4 text-center">
                    <p className="text-xs text-zinc-500 italic">Нет GIF файлов</p>
                  </div>
                )
              ) : activeTab === 'media' ? (
                sortedMedia.length > 0 ? (
                  renderGrouped(sortedMedia, (m, idx) => (
                      <div
                        key={m.id}
                        onClick={() => setLightboxIndex(idx)}
                        className="relative aspect-square bg-zinc-900 overflow-hidden cursor-pointer group"
                      >
                          {m.type === 'video' ? (
                            <>
                              <div 
                                className="w-full h-full bg-zinc-800 flex items-center justify-center relative group-hover:scale-105 transition-transform duration-200"
                                onClick={() => setLightboxIndex(idx)}
                              >
                                {m.thumbnail ? (
                                  <img src={getMediaUrl(m.thumbnail)} alt="" className="w-full h-full object-cover" />
                                ) : (
                                  <video src={getMediaUrl(m.url)} preload="metadata" className="w-full h-full object-cover bg-zinc-900" />
                                )}
                                <div className="absolute inset-0 flex items-center justify-center bg-black/20 group-hover:bg-black/40 transition-colors">
                                  <Play size={24} className="text-white fill-white" />
                                </div>
                              </div>
                            </>
                          ) : (
                          <img
                            src={getMediaUrl(m.url)}
                            alt=""
                            onClick={() => setLightboxIndex(idx)}
                            className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
                          />
                        )}
                        <button
                          onClick={(e) => { e.stopPropagation(); onGoToMessage?.(m.messageId, m.sequenceId); }}
                          className="absolute bottom-2 right-2 px-2 py-1 rounded-md bg-black/60 backdrop-blur-sm flex items-center justify-center text-white text-[10px] font-medium opacity-0 group-hover:opacity-100 transition-opacity hover:bg-black/80 shadow-md"
                        >
                          {t('showInChat')}
                        </button>
                      </div>
                    ), "grid grid-cols-3 gap-0.5 px-1")
                ) : (
                  <div className="flex items-center justify-center py-10 px-4 text-center">
                    <p className="text-xs text-zinc-500 italic">{t('sharedPhotos')}</p>
                  </div>
                )
              ) : activeTab === 'files' ? (
                sortedFiles.length > 0 ? (
                  renderGrouped(sortedFiles, (msg, idx) => (
                    <div key={msg.id} className="divide-y divide-border border-b border-border">
                      {(msg.media || []).map((m) => (
                        <div key={m.id} className="relative group/file">
                          <a
                            href={getMediaUrl(m.url)}
                            download={m.filename || 'file'}
                            className="flex items-center gap-3 px-4 py-3 hover:bg-white/5 transition-colors"
                          >
                          <div className="w-8 h-8 rounded-lg bg-knot-500/10 flex items-center justify-center flex-shrink-0 text-knot-400">
                            <FileText size={16} />
                          </div>


                          <div className="flex-1 min-w-0">
                            <p className="text-[13px] text-zinc-200 truncate">{m.filename || 'File'}</p>
                            <p className="text-[10px] text-zinc-500">{m.size ? `${(m.size / 1024).toFixed(1)} KB` : ''}</p>
                          </div>
                          <Download size={14} className="text-zinc-600" />
                        </a>
                        <button
                           onClick={() => onGoToMessage?.(msg.id, msg.sequenceId)}
                           className="absolute right-10 top-1/2 -translate-y-1/2 px-3 py-1.5 rounded-lg hover:bg-white/10 flex items-center justify-center text-zinc-300 text-[11px] font-medium opacity-0 group-hover/file:opacity-100 transition-opacity"
                        >
                           {t('showInChat')}
                        </button>
                      </div>
                    ))}
                    </div>
                  ))
                ) : (
                  <div className="flex items-center justify-center py-10 px-4 text-center">
                    <p className="text-xs text-zinc-500 italic">{t('sharedFiles')}</p>
                  </div>
                )
              ) : (
                sortedLinks.length > 0 ? (
                  renderGrouped(sortedLinks, (msg, idx) => (
                      <div key={msg.id} className="p-4 hover:bg-white/5 transition-colors border-b border-white/5 relative group">
                        {msg.links?.map((link, i) => (
                          <a
                            key={i}
                            href={link}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="flex items-center gap-2 text-[13px] text-knot-400 hover:underline truncate mb-1"
                          >
                            <ExternalLink size={12} className="flex-shrink-0" />
                            {link}
                          </a>
                        ))}
                        {msg.content && <p className="text-[11px] text-zinc-500 line-clamp-1">{msg.content}</p>}
                        <button
                           onClick={() => onGoToMessage?.(msg.id, msg.sequenceId)}
                           className="absolute right-4 top-1/2 -translate-y-1/2 px-3 py-1.5 rounded-lg bg-black/40 hover:bg-knot-500/20 text-zinc-300 hover:text-white text-[11px] font-medium opacity-0 group-hover:opacity-100 transition-all shadow-md z-10"
                        >
                           {t('showInChat')}
                        </button>
                      </div>
                    ))
                ) : (
                  <div className="flex items-center justify-center py-10 px-4 text-center">
                    <p className="text-xs text-zinc-500 italic">{t('sharedLinks')}</p>
                  </div>
                )
              )}
              </div>
            </div>
          ) : loadedTabs.size === 4 ? (
            <div className="mx-4 mb-6 flex flex-col items-center justify-center py-10 px-4 text-center border border-white/5 bg-black/20 rounded-2xl backdrop-blur-xl">
              <ImageIcon size={32} className="text-zinc-600 mb-3" />
              <p className="text-sm text-zinc-500">{(t('sharedPhotos' as any) || 'Нет вложений') as string}</p>
            </div>
          ) : (
             <div className="mx-4 mb-6 flex items-center justify-center py-10 border border-white/5 bg-black/20 rounded-2xl backdrop-blur-xl">
               <Loader2 size={24} className="text-zinc-500 animate-spin" />
             </div>
          )}

        </div>
      </motion.div>

      <ConfirmModal
        open={!!removeTargetId}
        message={t('confirmRemoveMember')}
        onConfirm={confirmRemoveMember}
        onCancel={() => setRemoveTargetId(null)}
      />

      <AnimatePresence>
        {lightboxIndex !== null && (
          <ImageLightbox
            images={(activeTab === 'gifs' ? sortedGifs : sortedMedia).map((m) => ({ 
              url: m.url, // Already contains getMediaUrl in calculated allGifs/allMedia
              type: activeTab === 'gifs' ? 'gif' : m.type 
            }))}
            initialIndex={lightboxIndex}
            onClose={() => setLightboxIndex(null)}
          />
        )}
      </AnimatePresence>

      <AnimatePresence>
        {isCropping && cropImage && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[100] bg-black/90 backdrop-blur-xl flex flex-col items-center justify-center p-6"
          >
            <div className="w-full max-w-[400px] bg-surface-secondary rounded-[2rem] border border-white/10 overflow-hidden shadow-2xl">
              <div className="p-6 border-b border-white/5 flex items-center justify-between">
                <h3 className="text-xl font-bold text-white">{t('changePhoto')}</h3>
                <button onClick={() => setIsCropping(false)} className="text-zinc-400 hover:text-white transition-colors">
                  <X size={20} />
                </button>
              </div>

              <div className="relative w-full h-80 bg-black">
                <Cropper
                  image={cropImage}
                  crop={crop}
                  zoom={zoom}
                  aspect={1}
                  cropShape="round"
                  showGrid={false}
                  onCropChange={setCrop}
                  onZoomChange={setZoom}
                  onCropComplete={(_, pixels) => setCroppedAreaPixels(pixels)}
                />
              </div>
              
              <div className="p-6">
                <div className="flex items-center gap-4 mb-6">
                   <span className="text-zinc-500 text-xs font-medium uppercase">Zoom</span>
                   <input
                     type="range"
                     value={zoom}
                     min={1}
                     max={3}
                     step={0.1}
                     onChange={(e) => setZoom(Number(e.target.value))}
                     className="flex-1 accent-knot-500"
                   />
                </div>

                <div className="flex gap-3 w-full">
                  <button
                    onClick={() => setIsCropping(false)}
                    className="flex-1 py-3 px-4 rounded-xl bg-white/5 hover:bg-white/10 text-white font-semibold transition-all"
                  >
                    {t('cancel')}
                  </button>
                  <button
                    onClick={handleCropSave}
                    disabled={avatarUploading}
                    className="flex-1 py-3 px-4 rounded-xl bg-accent hover:bg-accent-light text-white font-bold transition-all shadow-lg shadow-accent/20 flex items-center justify-center gap-2"
                  >
                    {avatarUploading ? <Loader2 size={18} className="animate-spin" /> : <Check size={18} />}
                    {t('save')}
                  </button>
                </div>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
      <input
        ref={fileInputRef}
        type="file"
        accept="image/*"
        className="hidden"
        onChange={handleFileChange}
      />
    </>
  );
}
