import { useState, useRef, useEffect, memo } from 'react';
import { formatDistanceToNow } from 'date-fns';
import { ru, enUS } from 'date-fns/locale';
import { Check, CheckCheck, Image, FileText, Mic, Video, Pin, Trash2, Bookmark } from 'lucide-react';
import { useAuthStore } from '../../../auth/application/authStore';
import { useChatStore } from '../../application/chatStore';
import { httpClient } from '../../../../core/infrastructure/httpClient';
import { useLang } from '../../../../core/infrastructure/i18n';
import { stripMarkdown } from '../../../../core/utils/utils';
import { ChatApi } from '../../infrastructure/chatApi';
import ConfirmModal from '../../../../core/presentation/components/ui/ConfirmModal';
import Avatar from '../../../../core/presentation/components/ui/Avatar';
import type { Chat } from '../../../../core/domain/types';

interface ChatListItemProps {
  chat: Chat;
  isActive: boolean;
}

function ChatListItem({ chat, isActive }: ChatListItemProps) {
  const { user } = useAuthStore();
  const { setActiveChat, loadMessages, typingUsers, drafts, loadChats } = useChatStore();
  const { t, lang } = useLang();

  const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number } | null>(null);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const ctxRef = useRef<HTMLDivElement>(null);

  const myMember = chat.members.find((m) => m.user.id === user?.id);
  const isPinned = myMember?.isPinned ?? false;

  const draft = drafts[chat.id] || '';

  const otherMember = chat.members.find((m) => m.user.id !== user?.id);
  const isFavorites = chat.type === 'favorites';
  const chatName = (isFavorites
    ? t('favorites')
    : chat.type === 'personal'
      ? otherMember?.user.displayName || otherMember?.user.userName || otherMember?.user.username || t('chat')
      : chat.name || t('group')) || '??';

  const chatAvatar: string | null = isFavorites
    ? null
    : chat.type === 'personal'
      ? otherMember?.user.avatarUrl || otherMember?.user.avatar || null
      : chat.avatarUrl || chat.avatar || null;

  const isOnline = chat.type === 'personal' && !!otherMember?.user.isOnline;

  // Check if someone is typing in this chat
  const typingInChat = typingUsers.filter((t) => t.chatId === chat.id && t.userId !== user?.id);
  const isTyping = typingInChat.length > 0;

  const lastMessage = chat.messages?.[0];
  const lastMessageText = lastMessage
    ? lastMessage.isDeleted
      ? t('messageDeleted')
      : lastMessage.type === 'voice'
        ? t('voice')
        : lastMessage.type === 'file' || lastMessage.type === 'image' || lastMessage.type === 'video'
          ? lastMessage.media?.[0]?.type === 'image'
            ? t('photo')
            : lastMessage.media?.[0]?.type === 'video'
              ? t('video')
              : t('file')
          : lastMessage.type === 'call'
            ? `${lastMessage.callType === 'video' ? '🎬' : '📞'} ${t(
              lastMessage.callStatus === 'missed' ? 'missedCall' :
                lastMessage.callStatus === 'declined' ? 'declinedCall' :
                  lastMessage.callStatus === 'cancelled' ? 'cancelledCall' :
                    'completedCall'
            )}`
            : lastMessage.content || ''
    : '';

  const previewText = chat.isImporting ? 'Импорт...' : stripMarkdown(lastMessageText);

  const isMine = !chat.isImporting && lastMessage?.senderId === user?.id;

  // Галочки прочтения
  // Для своих сообщений: проверено, есть ли в readBy другие пользователи (получатели)
  // Для чужих сообщений: не показываем галочки
  const isRead = !chat.isImporting && isMine && lastMessage?.readBy?.some((r) => r.userId !== user?.id);

  const timeStr = !chat.isImporting && lastMessage
    ? formatDistanceToNow(new Date(lastMessage.createdAt), { addSuffix: false, locale: lang === 'ru' ? ru : enUS })
    : '';

  const [showAttachmentConfirm, setShowAttachmentConfirm] = useState(false);
  const [importStatus, setImportStatus] = useState<{ processed: number, total: number } | null>(null);

  useEffect(() => {
    if (!chat.isImporting || !chat.importJobId) {
      setImportStatus(null);
      return;
    }

    const poll = async () => {
      try {
        const data = await httpClient.request<any>(`/import/telegram/status/${chat.importJobId}`);
        setImportStatus({ processed: data.processedMessages, total: data.totalMessages });
        if (data.status === 'Completed' || data.status === 'Failed') {
          loadChats();
        }
      } catch (e: any) {
        if (e.status === 404) {
          // Job might have expired or backend restarted
          console.warn('Import job not found');
        } else {
          console.error('Failed to poll status', e);
        }
      }
    };

    poll();
    const interval = setInterval(poll, 1500);
    return () => clearInterval(interval);
  }, [chat.isImporting, chat.importJobId, loadChats]);

  const handleClick = () => {
    if (chat.isImporting) {
      // Here we could show a progress modal, but for now just select it
      setActiveChat(chat.id);
      return;
    }
    if ((window as any).hasUnsavedAttachments && !isActive) {
      setShowAttachmentConfirm(true);
      return;
    }
    proceedWithClick();
  };

  const proceedWithClick = () => {
    setShowAttachmentConfirm(false);
    (window as any).hasUnsavedAttachments = false;

    if (isActive) {
      window.dispatchEvent(new CustomEvent('CHAT_SCROLL_TO_BOTTOM', { detail: { chatId: chat.id } }));
    } else {
      setActiveChat(chat.id);
      loadMessages(chat.id);
    }
  };

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    setCtxMenu({ x: e.clientX, y: e.clientY });
  };

  useEffect(() => {
    if (!ctxMenu) return;
    const close = (e: MouseEvent) => {
      if (ctxRef.current && !ctxRef.current.contains(e.target as Node)) setCtxMenu(null);
    };
    document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, [ctxMenu]);

  const handlePin = async () => {
    setCtxMenu(null);
    try {
      await ChatApi.togglePinChat(chat.id);
      loadChats();
    } catch (e) { console.error(e); }
  };

  const handleDelete = async () => {
    setCtxMenu(null);
    setShowDeleteConfirm(true);
  };

  const confirmDelete = async () => {
    setShowDeleteConfirm(false);
    try {
      await ChatApi.deleteChat(chat.id);
      useChatStore.getState().removeChat(chat.id);
    } catch (e) { console.error(e); }
  };

  const initials = (chatName || '??')
    .split(' ')
    .filter(Boolean)
    .map((w: string) => w[0])
    .join('')
    .slice(0, 2)
    .toUpperCase();

  return (
    <div className="relative">
      <button
        onClick={handleClick}
        onContextMenu={handleContextMenu}
        className={`w-full flex items-center gap-4 px-4 py-3.5 transition-all duration-300 slide-on-ice text-left rounded-2xl mx-1 my-0.5 w-[calc(100%-8px)] ${isActive ? 'bg-primary/10' : 'hover:bg-surface-container-highest/20'
          }`}
      >
        {/* Аватар */}
        <div className="relative flex-shrink-0">
          {isFavorites ? (
            <div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-primary to-primary-container flex items-center justify-center shadow-lg shadow-primary/10 border-2 border-outline-variant/10">
              <span className="material-symbols-outlined text-on-primary-container text-[24px]">bookmark</span>
            </div>
          ) : (
            <div className="avatar-knot-container group-hover:scale-105 transition-transform">
              <Avatar src={chatAvatar || undefined} name={chatName || '??'} size="lg" online={isOnline ? true : false} />
            </div>
          )}
        </div>

        {/* Инфо */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-1.5 min-w-0">
              {isPinned && <span className="material-symbols-outlined text-[14px] text-primary rotate-45">push_pin</span>}
              <span className={`text-sm font-bold tracking-tight truncate ${isActive ? 'text-primary' : 'text-on-surface'}`}>{chatName}</span>
            </div>
            {timeStr && <span className="text-[10px] uppercase font-bold tracking-wider text-on-surface-variant/50 flex-shrink-0 ml-2">{timeStr}</span>}
          </div>
          <div className="flex items-center justify-between mt-0.5">
            <div className="flex items-center gap-1 min-w-0 flex-1">
              {isMine && lastMessage && !lastMessage.isDeleted && (
                <span className="flex-shrink-0">
                  <span className={`material-symbols-outlined text-[14px] ${isRead ? 'text-primary fill-1' : 'text-on-surface-variant/40'}`} style={{ fontVariationSettings: `'FILL' ${isRead ? 1 : 0}` }}>
                    {isRead ? 'done_all' : 'done'}
                  </span>
                </span>
              )}
              <div className="flex flex-col gap-1 w-full min-w-0">
                <p className={`text-[13px] truncate leading-tight ${isTyping ? 'text-tertiary font-bold' : draft ? 'text-error font-medium' : 'text-on-surface-variant/60'}`}>
                  {isTyping ? t('typing') : draft ? <><span className="font-bold">{t('draft')} </span>{stripMarkdown(draft)}</> : previewText}
                  {chat.isImporting && importStatus && importStatus.total > 0 && (
                    <span className="ml-1.5 text-[11px] font-black text-primary/70 tabular-nums">
                      {importStatus.processed} / {importStatus.total}
                    </span>
                  )}
                </p>
                {chat.isImporting && importStatus && importStatus.total > 0 && (
                  <div className="w-full h-1 bg-surface-container-highest rounded-full overflow-hidden mt-0.5">
                    <div
                      className="h-full bg-primary transition-all duration-500 ease-out"
                      style={{ width: `${Math.min(100, Math.round((importStatus.processed / importStatus.total) * 100))}%` }}
                    />
                  </div>
                )}
              </div>
            </div>
            {chat.unreadCount > 0 && !isActive && (
              <span className="ml-2 flex-shrink-0 min-w-[20px] h-5 px-1.5 rounded-full bg-primary text-[#0a0a0a] flex items-center justify-center text-[10px] font-black shadow-lg shadow-primary/20 animate-pulse">
                {chat.unreadCount}
              </span>
            )}
          </div>
        </div>
      </button>

      {/* Context Menu */}
      {ctxMenu && (
        <div
          ref={ctxRef}
          className="fixed z-[9999] min-w-[200px] py-1.5 rounded-[1.25rem] bg-[#1a1a1a] border border-white/10 shadow-[0_20px_50px_rgba(0,0,0,0.5)] animate-in fade-in zoom-in-95 duration-100"
          style={{ top: ctxMenu.y, left: ctxMenu.x }}
        >
          {!isFavorites && (
            <>
              <button
                onClick={handlePin}
                className="flex items-center gap-3 w-full px-4 py-2.5 text-sm text-zinc-300 hover:bg-surface-hover hover:text-white transition-colors"
              >
                <Pin size={16} className={isPinned ? 'rotate-45' : ''} />
                {isPinned ? t('unpinChat') : t('pinChat')}
              </button>
              <div className="border-t border-border my-1" />
            </>
          )}
          <button
            onClick={handleDelete}
            className="flex items-center gap-3 w-full px-4 py-2.5 text-sm text-red-400 hover:bg-red-500/10 transition-colors"
          >
            <Trash2 size={16} />
            {isFavorites ? t('clearHistory') : t('deleteChat')}
          </button>
        </div>
      )}

      <ConfirmModal
        open={showDeleteConfirm}
        message={isFavorites ? t('clearHistoryConfirm') : t('deleteChatConfirm')}
        onConfirm={confirmDelete}
        onCancel={() => setShowDeleteConfirm(false)}
      />

      <ConfirmModal
        open={showAttachmentConfirm}
        message={(t as any)('attachmentDiscardConfirm') || 'У вас есть прикрепленные вложения. Если вы перейдете в другой чат, они будут потеряны. Продолжить?'}
        onConfirm={proceedWithClick}
        onCancel={() => setShowAttachmentConfirm(false)}
      />
    </div>
  );
}

export default memo(ChatListItem);
