"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { X } from "lucide-react";
import { useMessengerContext } from "@/contexts/MessengerContext";
import { useRooms, useUnreadCount } from "@/hooks/useMessenger";
import { useMessengerSocket } from "@/hooks/useMessengerSocket";
import { RoomList } from "./RoomList";
import { ChatPanel } from "./ChatPanel";
import { NewRoomModal } from "./NewRoomModal";

const MIN_W = 400, MIN_H = 320;
const MAX_W = 1000, MAX_H = 800;
const INIT_W = 720, INIT_H = 500;

type ResizeDir = "n" | "s" | "e" | "w" | "ne" | "nw" | "se" | "sw";

const CURSOR: Record<ResizeDir, string> = {
  n: "ns-resize", s: "ns-resize",
  e: "ew-resize", w: "ew-resize",
  ne: "nesw-resize", sw: "nesw-resize",
  nw: "nwse-resize", se: "nwse-resize",
};

export function MessengerModal() {
  const { isOpen, closeMessenger, selectedRoomId, setUnreadCount } = useMessengerContext();
  const { data: rooms = [] } = useRooms();
  const { data: serverUnread } = useUnreadCount();
  const { userStatuses, typingUsers, emitTypingStart, emitTypingStop } = useMessengerSocket();

  useEffect(() => {
    const count = (serverUnread as any)?.unread_count ?? serverUnread ?? 0;
    setUnreadCount(Number(count));
  }, [serverUnread, setUnreadCount]);

  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape" && isOpen) closeMessenger();
    };
    document.addEventListener("keydown", onKeyDown);
    return () => document.removeEventListener("keydown", onKeyDown);
  }, [isOpen, closeMessenger]);


  const selectedRoom = rooms.find((r) => r.id === selectedRoomId) || null;
  const [newRoomOpen, setNewRoomOpen] = useState(false);

  // Position & size state
  const [pos, setPos] = useState({ x: 0, y: 0 });
  const [size, setSize] = useState({ w: INIT_W, h: INIT_H });
  const initialized = useRef(false);

  // Initialize position to bottom-right on first open
  useEffect(() => {
    if (isOpen && !initialized.current) {
      setPos({
        x: window.innerWidth - INIT_W - 24,
        y: window.innerHeight - INIT_H - 24,
      });
      initialized.current = true;
    }
  }, [isOpen]);

  // Clamp position when window resizes
  useEffect(() => {
    const onResize = () => {
      setPos((p) => ({
        x: Math.min(p.x, window.innerWidth - size.w),
        y: Math.min(p.y, window.innerHeight - size.h),
      }));
    };
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, [size]);

  // --- Drag to move ---
  const dragRef = useRef<{ startX: number; startY: number; origX: number; origY: number } | null>(null);

  const onHeaderMouseDown = useCallback((e: React.MouseEvent) => {
    if ((e.target as HTMLElement).closest("button")) return;
    e.preventDefault();
    dragRef.current = { startX: e.clientX, startY: e.clientY, origX: pos.x, origY: pos.y };

    const onMove = (ev: MouseEvent) => {
      if (!dragRef.current) return;
      const dx = ev.clientX - dragRef.current.startX;
      const dy = ev.clientY - dragRef.current.startY;
      setPos({
        x: Math.max(0, Math.min(dragRef.current.origX + dx, window.innerWidth - size.w)),
        y: Math.max(0, Math.min(dragRef.current.origY + dy, window.innerHeight - size.h)),
      });
    };
    const onUp = () => {
      dragRef.current = null;
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseup", onUp);
    };
    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseup", onUp);
  }, [pos, size]);

  // --- Resize ---
  const resizeRef = useRef<{
    dir: ResizeDir;
    startX: number; startY: number;
    origX: number; origY: number;
    origW: number; origH: number;
  } | null>(null);

  const onResizeMouseDown = useCallback((e: React.MouseEvent, dir: ResizeDir) => {
    e.preventDefault();
    e.stopPropagation();
    resizeRef.current = {
      dir,
      startX: e.clientX, startY: e.clientY,
      origX: pos.x, origY: pos.y,
      origW: size.w, origH: size.h,
    };

    const onMove = (ev: MouseEvent) => {
      const r = resizeRef.current;
      if (!r) return;
      const dx = ev.clientX - r.startX;
      const dy = ev.clientY - r.startY;

      let newX = r.origX, newY = r.origY, newW = r.origW, newH = r.origH;

      if (r.dir.includes("e")) newW = Math.min(MAX_W, Math.max(MIN_W, r.origW + dx));
      if (r.dir.includes("s")) newH = Math.min(MAX_H, Math.max(MIN_H, r.origH + dy));
      if (r.dir.includes("w")) {
        const w = Math.min(MAX_W, Math.max(MIN_W, r.origW - dx));
        newX = r.origX + (r.origW - w);
        newW = w;
      }
      if (r.dir.includes("n")) {
        const h = Math.min(MAX_H, Math.max(MIN_H, r.origH - dy));
        newY = r.origY + (r.origH - h);
        newH = h;
      }

      // Clamp to viewport
      newX = Math.max(0, Math.min(newX, window.innerWidth - newW));
      newY = Math.max(0, Math.min(newY, window.innerHeight - newH));

      setPos({ x: newX, y: newY });
      setSize({ w: newW, h: newH });
    };

    const onUp = () => {
      resizeRef.current = null;
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseup", onUp);
    };
    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseup", onUp);
  }, [pos, size]);

  const handle = (dir: ResizeDir, className: string) => (
    <div
      className={`absolute z-20 ${className}`}
      style={{ cursor: CURSOR[dir] }}
      onMouseDown={(e) => onResizeMouseDown(e, dir)}
    />
  );

  return (
    <>
    <div
      className="fixed z-[9999] flex flex-col bg-background border rounded-lg shadow-2xl overflow-hidden"
      style={{
        left: pos.x,
        top: pos.y,
        width: size.w,
        height: size.h,
        display: isOpen ? "flex" : "none",
      }}
    >
      {/* Resize handles */}
      {handle("n",  "top-0 left-2 right-2 h-1.5")}
      {handle("s",  "bottom-0 left-2 right-2 h-1.5")}
      {handle("e",  "right-0 top-2 bottom-2 w-1.5")}
      {handle("w",  "left-0 top-2 bottom-2 w-1.5")}
      {handle("ne", "top-0 right-0 w-3 h-3")}
      {handle("nw", "top-0 left-0 w-3 h-3")}
      {handle("se", "bottom-0 right-0 w-3 h-3")}
      {handle("sw", "bottom-0 left-0 w-3 h-3")}

      {/* Header */}
      <div
        className="flex items-center justify-between px-4 py-2 border-b bg-muted/30 select-none cursor-move"
        onMouseDown={onHeaderMouseDown}
      >
        <h2 className="text-sm font-semibold">메신저</h2>
        <button
          onClick={closeMessenger}
          className="p-1 hover:bg-muted rounded"
          aria-label="닫기"
        >
          <X className="h-4 w-4 text-muted-foreground" />
        </button>
      </div>

      {/* Body */}
      <div className="flex flex-1 min-h-0 relative">
        <RoomList userStatuses={userStatuses} newRoomOpen={newRoomOpen} setNewRoomOpen={setNewRoomOpen} />
        <ChatPanel room={selectedRoom} typingUsers={typingUsers} emitTypingStart={emitTypingStart} emitTypingStop={emitTypingStop} onNewRoom={() => setNewRoomOpen(true)} />
        <NewRoomModal open={newRoomOpen} onOpenChange={setNewRoomOpen} userStatuses={userStatuses} />

      </div>
    </div>
    </>
  );
}
