import { useRef, useState } from 'react';
import { formatDistanceToNow } from 'date-fns';
import { ru } from 'date-fns/locale';
import { Pin, BellOff, Bell, LogOut } from 'lucide-react';
import Avatar from './Avatar';
import { Chat } from '../types';

interface Props {
  chat: Chat;
  active: boolean;
  online?: boolean;
  onClick: () => void;
  onPin: (chatId: string, pinned: boolean) => void;
  onMute: (chatId: string, muted: boolean) => void;
  onLeave: (chatId: string) => void;
}

// How far buttons extend when snapped open
const SNAP_LEFT = -120;
const SNAP_RIGHT = 72;

export default function ChatListItem({ chat, active, online, onClick, onPin, onMute, onLeave }: Props) {
  // swipeX: live drag offset; snapped: 'left' | 'right' | null = locked open
  const [swipeX, setSwipeX] = useState(0);
  const [snapped, setSnapped] = useState<'left' | 'right' | null>(null);
  const touchStart = useRef<{ x: number; y: number } | null>(null);
  const dragging = useRef(false);

  const time = chat.lastMessageAt
    ? formatDistanceToNow(new Date(chat.lastMessageAt), { addSuffix: false, locale: ru })
    : '';

  const icon = chat.type === 'channel' ? '📢' : chat.type === 'group' ? '👥' : null;

  // Current visual offset = live drag + snap position
  const baseX = snapped === 'left' ? SNAP_LEFT : snapped === 'right' ? SNAP_RIGHT : 0;
  const visualX = snapped ? baseX : swipeX;

  function handleTouchStart(e: React.TouchEvent) {
    touchStart.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };
    dragging.current = false;
  }

  function handleTouchMove(e: React.TouchEvent) {
    if (!touchStart.current) return;
    const dx = e.touches[0].clientX - touchStart.current.x;
    const dy = Math.abs(e.touches[0].clientY - touchStart.current.y);
    if (!dragging.current && dy > 10 && Math.abs(dx) < dy) { touchStart.current = null; return; }
    if (Math.abs(dx) > 6) dragging.current = true;
    if (!dragging.current) return;
    // If already snapped, allow dragging back from snap position
    const raw = snapped ? baseX + dx : dx;
    setSwipeX(Math.max(SNAP_LEFT, Math.min(SNAP_RIGHT, raw)));
  }

  function handleTouchEnd() {
    if (!dragging.current) { touchStart.current = null; return; }
    dragging.current = false;
    touchStart.current = null;

    if (swipeX > 50) {
      // Snapped right → pin immediately and close
      onPin(chat.id, !chat.isPinned);
      setSwipeX(0);
      setSnapped(null);
    } else if (swipeX < -60) {
      // Snap left open → user can tap action buttons
      setSwipeX(0);
      setSnapped('left');
    } else {
      // Close
      setSwipeX(0);
      setSnapped(null);
    }
  }

  function close() {
    setSwipeX(0);
    setSnapped(null);
  }

  function handleMainClick() {
    if (snapped) { close(); return; }
    onClick();
  }

  const showPinHint = swipeX > 30;
  const leftOpen = snapped === 'left';

  return (
    <div className="relative overflow-hidden rounded-xl">
      {/* Right bg: pin hint while dragging */}
      <div className={`absolute inset-y-0 left-0 w-[72px] flex flex-col items-center justify-center bg-blue-500 rounded-l-xl transition-opacity duration-150 ${showPinHint ? 'opacity-100' : 'opacity-0'}`}>
        <Pin className="w-5 h-5 text-white" />
        <span className="text-white text-[10px] mt-0.5">{chat.isPinned ? 'Открепить' : 'Закрепить'}</span>
      </div>

      {/* Left actions: always rendered, visible when snapped */}
      <div className={`absolute inset-y-0 right-0 flex rounded-r-xl overflow-hidden transition-opacity duration-150 ${leftOpen ? 'opacity-100' : 'opacity-0'}`}>
        <button
          onClick={() => { onMute(chat.id, !chat.isMuted); close(); }}
          className="w-16 h-full flex flex-col items-center justify-center bg-gray-500 text-white text-[10px] gap-0.5 active:brightness-90"
        >
          {chat.isMuted ? <Bell className="w-5 h-5" /> : <BellOff className="w-5 h-5" />}
          <span>{chat.isMuted ? 'Вкл. звук' : 'Без звука'}</span>
        </button>
        {chat.type !== 'private' && (
          <button
            onClick={() => { close(); onLeave(chat.id); }}
            className="w-16 h-full flex flex-col items-center justify-center bg-red-500 text-white text-[10px] gap-0.5 active:brightness-90"
          >
            <LogOut className="w-5 h-5" />
            <span>Выйти</span>
          </button>
        )}
      </div>

      {/* Main row */}
      <button
        onClick={handleMainClick}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
        style={{
          transform: `translateX(${visualX}px)`,
          transition: dragging.current ? 'none' : 'transform 0.2s ease',
        }}
        className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-left ${active ? 'bg-blue-50' : 'bg-white hover:bg-gray-50'}`}
      >
        <div className="relative flex-shrink-0">
          <Avatar
            name={chat.title}
            color={chat.avatarColor}
            online={chat.type === 'private' ? online : undefined}
          />
          {chat.isPinned && (
            <span className="absolute -bottom-0.5 -right-0.5 bg-blue-500 rounded-full p-0.5">
              <Pin className="w-2 h-2 text-white" />
            </span>
          )}
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center justify-between">
            <span className="font-medium text-gray-900 text-sm truncate">
              {icon && <span className="mr-1 text-xs">{icon}</span>}
              {chat.title}
            </span>
            {time && <span className="text-xs text-gray-400 flex-shrink-0 ml-1">{time}</span>}
          </div>
          <div className="flex items-center justify-between mt-0.5">
            <p className="text-xs text-gray-500 truncate">
              {chat.lastMessage || (chat.type === 'channel' ? 'Канал' : 'Нет сообщений')}
            </p>
            <div className="flex items-center gap-1 flex-shrink-0 ml-1">
              {chat.isMuted && <BellOff className="w-3 h-3 text-gray-400" />}
              {chat.unreadCount > 0 && (
                <span className={`${chat.isMuted ? 'bg-gray-400' : 'bg-blue-500'} text-white text-xs rounded-full min-w-[18px] h-[18px] flex items-center justify-center px-1`}>
                  {chat.unreadCount > 99 ? '99+' : chat.unreadCount}
                </span>
              )}
            </div>
          </div>
        </div>
      </button>
    </div>
  );
}
