"use client";

import React, { useEffect, useRef, useState } from "react";
import { MessageSquare, Pencil, Check, X, ChevronsDown, Bell, BellOff } from "lucide-react";
import { useMessages, useMarkAsRead, useUpdateRoom } from "@/hooks/useMessenger";
import { useAuth } from "@/hooks/useAuth";
import { useMessengerContext } from "@/contexts/MessengerContext";
import { MessageItem } from "./MessageItem";
import { MessageInput } from "./MessageInput";
import type { Room } from "@/hooks/useMessenger";

interface ChatPanelProps {
  room: Room | null;
  typingUsers: Map<string, string[]>;
  emitTypingStart: (roomId: string) => void;
  emitTypingStop: (roomId: string) => void;
  onNewRoom: () => void;
}

const formatDateLabel = (dateStr: string) => {
  const d = new Date(dateStr);
  const today = new Date();
  const yesterday = new Date();
  yesterday.setDate(today.getDate() - 1);
  if (d.toDateString() === today.toDateString()) return "오늘";
  if (d.toDateString() === yesterday.toDateString()) return "어제";
  return d.toLocaleDateString("ko-KR", { year: "numeric", month: "long", day: "numeric", weekday: "short" });
};

export function ChatPanel({ room, typingUsers, emitTypingStart, emitTypingStop, onNewRoom }: ChatPanelProps) {
  const { user } = useAuth();
  const { selectedRoomId, isOpen, mutedRooms, toggleRoomMute } = useMessengerContext();
  const { data: messages } = useMessages(selectedRoomId);
  const markAsRead = useMarkAsRead();
  const updateRoom = useUpdateRoom();
  const scrollRef = useRef<HTMLDivElement>(null);
  const [isAtBottom, setIsAtBottom] = useState(true);
  const [isEditingName, setIsEditingName] = useState(false);
  const [editName, setEditName] = useState("");
  const editInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (isOpen && selectedRoomId) {
      markAsRead.mutate(selectedRoomId);
    }
  }, [isOpen, selectedRoomId, messages?.length]);

  // Re-attach scroll listener whenever room changes
  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    const onScroll = () => {
      // In flex-col-reverse, scrollTop=0 means bottom (newest messages)
      setIsAtBottom(Math.abs(el.scrollTop) < 60);
    };
    el.addEventListener("scroll", onScroll);
    return () => el.removeEventListener("scroll", onScroll);
  }, [room?.id]);

  if (!room) {
    return (
      <div className="flex-1 flex flex-col items-center justify-center text-muted-foreground gap-3">
        <MessageSquare className="h-10 w-10" />
        <p className="text-sm">대화를 선택하세요</p>
        <button
          onClick={onNewRoom}
          className="px-4 py-1.5 text-sm bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors"
        >
          새 대화 시작하기
        </button>
      </div>
    );
  }

  const roomTyping = selectedRoomId ? typingUsers.get(selectedRoomId) : undefined;

  // messages is oldest-first; flex-col-reverse CSS pins scroll to bottom (newest visible)
  const isFirstInGroup = (idx: number) => {
    if (!messages) return true;
    if (idx === 0) return true;
    const prev = messages[idx - 1];
    const curr = messages[idx];
    if (prev.senderId !== curr.senderId || curr.isDeleted || prev.isDeleted) return true;
    const gap = new Date(curr.createdAt).getTime() - new Date(prev.createdAt).getTime();
    return gap > 5 * 60 * 1000;
  };

  const isLastInGroup = (idx: number) => {
    if (!messages) return true;
    if (idx === messages.length - 1) return true;
    const curr = messages[idx];
    const next = messages[idx + 1];
    if (curr.senderId !== next.senderId || next.isDeleted || curr.isDeleted) return true;
    const gap = new Date(next.createdAt).getTime() - new Date(curr.createdAt).getTime();
    return gap > 5 * 60 * 1000;
  };

  const shouldShowDate = (idx: number) => {
    if (!messages) return false;
    if (idx === 0) return true;
    const prev = new Date(messages[idx - 1].createdAt).toDateString();
    const curr = new Date(messages[idx].createdAt).toDateString();
    return prev !== curr;
  };

  // Compute display name based on room type
  const displayName = (() => {
    if (room.type === "dm") {
      const other = room.participants.find((p) => p.userId !== user?.userId);
      return other?.userName ?? room.name;
    }
    if (room.name) return room.name;
    const others = room.participants.filter((p) => p.userId !== user?.userId);
    if (others.length <= 2) {
      return others.map((p) => p.userName).join(", ");
    }
    return `${others[0].userName}, ${others[1].userName} 외 ${others.length - 2}명`;
  })();

  return (
    <div className="flex-1 flex flex-col min-w-0 min-h-0 overflow-hidden relative">
      {/* Header */}
      <div className="border-b px-4 py-2 flex items-center gap-2">
        {isEditingName ? (
          <form
            className="flex items-center gap-1 flex-1 min-w-0"
            onSubmit={(e) => {
              e.preventDefault();
              const trimmed = editName.trim();
              if (trimmed && trimmed !== room.name) {
                updateRoom.mutate({ roomId: room.id, name: trimmed });
              }
              setIsEditingName(false);
            }}
          >
            <input
              ref={editInputRef}
              value={editName}
              onChange={(e) => setEditName(e.target.value)}
              className="font-semibold text-sm bg-transparent border-b border-primary outline-none flex-1 min-w-0"
              autoFocus
            />
            <button type="submit" className="p-0.5 hover:bg-muted rounded">
              <Check className="h-3.5 w-3.5 text-primary" />
            </button>
            <button type="button" onClick={() => setIsEditingName(false)} className="p-0.5 hover:bg-muted rounded">
              <X className="h-3.5 w-3.5 text-muted-foreground" />
            </button>
          </form>
        ) : (
          <>
            <h3 className="font-semibold text-sm truncate">{displayName}</h3>
            {room.type !== "dm" && (
              <button
                onClick={() => { setEditName(room.name); setIsEditingName(true); }}
                className="p-0.5 hover:bg-muted rounded shrink-0"
              >
                <Pencil className="h-3.5 w-3.5 text-muted-foreground" />
              </button>
            )}
            <span className="text-xs text-muted-foreground">
              {room.participants.length}명
            </span>
            <button
              onClick={() => selectedRoomId && toggleRoomMute(selectedRoomId)}
              className="p-0.5 hover:bg-muted rounded shrink-0 ml-auto"
              title={selectedRoomId && mutedRooms.has(selectedRoomId) ? "알림 켜기" : "알림 끄기"}
            >
              {selectedRoomId && mutedRooms.has(selectedRoomId)
                ? <BellOff className="h-3.5 w-3.5 text-muted-foreground" />
                : <Bell className="h-3.5 w-3.5 text-muted-foreground" />
              }
            </button>
          </>
        )}
      </div>

      {/* Messages — flex-col-reverse keeps scroll pinned to bottom (newest visible) */}
      <div ref={scrollRef} className="flex-1 min-h-0 overflow-y-auto relative flex flex-col-reverse">
        <div className="pb-2">
          {/* Typing indicator at top of inner div = visually just above messages */}
          <div className="px-4 h-5 flex items-center text-xs text-muted-foreground gap-1">
            {roomTyping && roomTyping.length > 0 && (
              <>
                <span>{roomTyping.join(", ")}님이 입력 중</span>
                <span className="flex gap-0.5 items-center">
                  <span className="w-1 h-1 bg-muted-foreground rounded-full animate-bounce [animation-delay:0ms]" />
                  <span className="w-1 h-1 bg-muted-foreground rounded-full animate-bounce [animation-delay:150ms]" />
                  <span className="w-1 h-1 bg-muted-foreground rounded-full animate-bounce [animation-delay:300ms]" />
                </span>
              </>
            )}
          </div>
          {messages?.map((msg, idx) => (
            <div key={msg.id}>
              {shouldShowDate(idx) && (
                <div className="flex items-center gap-2 px-4 py-2">
                  <div className="flex-1 h-px bg-border" />
                  <span className="text-[10px] text-muted-foreground">
                    {formatDateLabel(msg.createdAt)}
                  </span>
                  <div className="flex-1 h-px bg-border" />
                </div>
              )}
              <MessageItem
                message={msg}
                isOwn={msg.senderId === user?.userId}
                showAvatar={isFirstInGroup(idx)}
                isLastInGroup={isLastInGroup(idx)}
              />
            </div>
          ))}
        </div>
      </div>

      {!isAtBottom && (
        <button
          onClick={() => { const el = scrollRef.current; if (el) el.scrollTop = 0; }}
          className="absolute bottom-14 left-1/2 -translate-x-1/2 z-10 flex items-center gap-1 bg-primary text-primary-foreground text-xs px-3 py-1.5 rounded-full shadow-md hover:bg-primary/90"
        >
          <ChevronsDown className="h-3.5 w-3.5" />
          최신 메시지
        </button>
      )}

      {/* Input */}
      <MessageInput
        roomId={room.id}
        onTypingStart={() => emitTypingStart(room.id)}
        onTypingStop={() => emitTypingStop(room.id)}
      />
    </div>
  );
}
