"use client";

import { TranscriptionTile } from "@/transcriptions/TranscriptionTile";
import { TrackReferenceOrPlaceholder } from "@livekit/components-react";
import { useCallback, useEffect, useRef, useState } from "react";

export interface ChatOverlayProps {
  agentAudioTrack?: TrackReferenceOrPlaceholder;
  accentColor: string;
  inputDisabled?: boolean;
  isVisible: boolean;
  position: { x: number; y: number };
  onPositionChange: (position: { x: number; y: number }) => void;
  containerRef: React.RefObject<HTMLDivElement>;
  onToggle: () => void;
}

export function ChatOverlay({
  agentAudioTrack,
  accentColor,
  inputDisabled,
  isVisible,
  position,
  onPositionChange,
  containerRef,
  onToggle,
}: ChatOverlayProps) {
  const overlayRef = useRef<HTMLDivElement>(null);
  const headerRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const dragOffset = useRef({ x: 0, y: 0 });

  // Responsive sizing based on container size
  const [containerSize, setContainerSize] = useState({ width: 360, height: 500 });

  useEffect(() => {
    const updateSize = () => {
      if (containerRef.current) {
        const rect = containerRef.current.getBoundingClientRect();
        setContainerSize({ width: rect.width, height: rect.height });
      }
    };

    updateSize();
    const resizeObserver = new ResizeObserver(updateSize);
    if (containerRef.current) {
      resizeObserver.observe(containerRef.current);
    }

    return () => {
      resizeObserver.disconnect();
    };
  }, [containerRef]);

  // Calculate overlay size as percentage of container, with min/max constraints
  // Width: larger (up to 95% of container)
  const overlayWidth = Math.min(
    Math.max(containerSize.width * 0.9, 280),
    containerSize.width * 0.95
  );
  // Height: smaller (reduced from 60-85% to 40-60%)
  const overlayHeight = Math.min(
    Math.max(containerSize.height * 0.4, 250),
    containerSize.height * 0.6
  );

  // Position overlay at center (slightly moved up) when first shown
  const hasPositionedRef = useRef(false);
  useEffect(() => {
    if (isVisible && containerRef.current && containerSize.width > 0 && overlayWidth > 0 && overlayHeight > 0) {
      // Calculate center position, moved up by 15% of container height
      const centerX = (containerSize.width - overlayWidth) / 2;
      const centerY = (containerSize.height - overlayHeight) / 2 - (containerSize.height * 0.15);
      
      // Only auto-position on first show (when position is at origin)
      if (!hasPositionedRef.current && position.x === 0 && position.y === 0) {
        onPositionChange({ x: Math.max(0, centerX), y: Math.max(0, centerY) });
        hasPositionedRef.current = true;
      }
    }
  }, [isVisible, containerSize.width, containerSize.height, overlayWidth, overlayHeight, containerRef, position, onPositionChange]);

  const handleDragStart = (e: React.MouseEvent | React.TouchEvent) => {
    if (!overlayRef.current || !headerRef.current) return;
    
    // Only allow dragging from the header, but not from buttons
    const target = e.target as HTMLElement;
    if (!headerRef.current.contains(target)) return;
    
    // Don't drag if clicking on the close button
    if (target.closest('button') || target.closest('svg')) return;

    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
    
    const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;
    
    dragOffset.current = {
      x: clientX - position.x,
      y: clientY - position.y,
    };
  };

  const handleDragMove = useCallback((e: MouseEvent | TouchEvent) => {
    if (!isDragging || !containerRef.current || !overlayRef.current) return;

    e.preventDefault();
    e.stopPropagation();

    const containerRect = containerRef.current.getBoundingClientRect();
    const overlayRect = overlayRef.current.getBoundingClientRect();

    const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;

    let newX = clientX - dragOffset.current.x;
    let newY = clientY - dragOffset.current.y;

    // Constrain within container bounds
    const maxX = containerRect.width - overlayRect.width;
    const maxY = containerRect.height - overlayRect.height;
    const minY = 0; // Allow dragging to top

    newX = Math.max(0, Math.min(newX, maxX));
    newY = Math.max(minY, Math.min(newY, maxY));

    onPositionChange({ x: newX, y: newY });
  }, [isDragging, containerRef, overlayRef, onPositionChange]);

  const handleDragEnd = useCallback(() => {
    setIsDragging(false);
  }, []);

  useEffect(() => {
    if (isDragging) {
      window.addEventListener("mousemove", handleDragMove);
      window.addEventListener("mouseup", handleDragEnd);
      window.addEventListener("touchmove", handleDragMove, { passive: false });
      window.addEventListener("touchend", handleDragEnd);
    }
    return () => {
      window.removeEventListener("mousemove", handleDragMove);
      window.removeEventListener("mouseup", handleDragEnd);
      window.removeEventListener("touchmove", handleDragMove);
      window.removeEventListener("touchend", handleDragEnd);
    };
  }, [isDragging, handleDragMove, handleDragEnd]);

  return (
    <div
      ref={overlayRef}
      className="absolute z-40 rounded-lg border border-white/20 shadow-2xl backdrop-blur-md transition-all duration-300 flex flex-col"
      style={{
        left: `${position.x}px`,
        top: `${position.y}px`,
        width: `${overlayWidth}px`,
        height: `${overlayHeight}px`,
        backgroundColor: 'rgba(0, 0, 0, 0.85)',
        cursor: isDragging ? 'grabbing' : 'default',
        display: isVisible ? 'flex' : 'none',
      }}
      onMouseDown={handleDragStart}
      onTouchStart={handleDragStart}
    >
      {/* Header with drag handle and close button */}
      <div
        ref={headerRef}
        className="flex items-center justify-between px-4 py-2 border-b border-white/10 cursor-move select-none"
        style={{ backgroundColor: 'rgba(0, 0, 0, 0.3)' }}
      >
        <div className="flex items-center gap-2">
          <div className="w-2 h-2 rounded-full bg-white/40"></div>
          <span className="text-white text-xs font-medium">Chat</span>
        </div>
        <button
          onClick={(e) => {
            e.stopPropagation();
            e.preventDefault();
            onToggle();
          }}
          className="text-white hover:text-white transition-colors p-2 rounded hover:bg-white/10 flex items-center justify-center"
          aria-label="Close chat overlay"
          style={{ minWidth: '32px', minHeight: '32px' }}
        >
          <svg
            className="w-5 h-5"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
            strokeWidth={2.5}
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              d="M6 18L18 6M6 6l12 12"
            />
          </svg>
        </button>
      </div>

      {/* Chat content with padding */}
      <div className="overflow-hidden flex flex-col px-2 py-2" style={{ height: `calc(100% - 40px)` }}>
        <TranscriptionTile
          agentAudioTrack={agentAudioTrack}
          accentColor={accentColor}
          inputDisabled={inputDisabled}
        />
      </div>
    </div>
  );
}

