"use client";

import React, { useState, useCallback, useRef } from "react";
import { cn } from "@/lib/utils";
import { AlertTriangle } from "lucide-react";
import {
  ScheduleItem,
  ScheduleBarPosition,
  TimelineSchedulerConfig,
} from "../types";
import { statusOptions } from "../config";

interface ScheduleBarProps {
  schedule: ScheduleItem;
  position: ScheduleBarPosition;
  config: TimelineSchedulerConfig;
  draggable?: boolean;
  resizable?: boolean;
  hasConflict?: boolean;
  isMilestone?: boolean;
  onClick?: (schedule: ScheduleItem) => void;
  /** 드래그 완료 시 deltaX(픽셀) 전달 */
  onDragComplete?: (schedule: ScheduleItem, deltaX: number) => void;
  /** 리사이즈 완료 시 direction과 deltaX(픽셀) 전달 */
  onResizeComplete?: (
    schedule: ScheduleItem,
    direction: "start" | "end",
    deltaX: number
  ) => void;
}

// 드래그/리사이즈 판정 최소 이동 거리 (px)
const MIN_MOVE_THRESHOLD = 5;

export function ScheduleBar({
  schedule,
  position,
  config,
  draggable = true,
  resizable = true,
  hasConflict = false,
  isMilestone = false,
  onClick,
  onDragComplete,
  onResizeComplete,
}: ScheduleBarProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [isResizing, setIsResizing] = useState(false);
  const [dragOffset, setDragOffset] = useState(0);
  const [resizeOffset, setResizeOffset] = useState(0);
  const [resizeDir, setResizeDir] = useState<"start" | "end">("end");
  const barRef = useRef<HTMLDivElement>(null);
  const startXRef = useRef(0);
  const movedRef = useRef(false);

  const statusColor =
    schedule.color ||
    config.statusColors?.[schedule.status] ||
    statusOptions.find((s) => s.value === schedule.status)?.color ||
    "#3b82f6";

  const progressWidth =
    config.showProgress && schedule.progress !== undefined
      ? `${schedule.progress}%`
      : "0%";

  const isEditable = config.editable !== false;

  // ────────── 드래그 핸들러 ──────────
  const handleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      if (!draggable || isResizing || !isEditable) return;
      e.preventDefault();
      e.stopPropagation();

      startXRef.current = e.clientX;
      movedRef.current = false;
      setIsDragging(true);
      setDragOffset(0);

      const handleMouseMove = (moveEvent: MouseEvent) => {
        const delta = moveEvent.clientX - startXRef.current;
        if (Math.abs(delta) > MIN_MOVE_THRESHOLD) {
          movedRef.current = true;
        }
        setDragOffset(delta);
      };

      const handleMouseUp = (upEvent: MouseEvent) => {
        const finalDelta = upEvent.clientX - startXRef.current;
        setIsDragging(false);
        setDragOffset(0);

        if (movedRef.current && Math.abs(finalDelta) > MIN_MOVE_THRESHOLD) {
          onDragComplete?.(schedule, finalDelta);
        }

        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    },
    [draggable, isResizing, isEditable, schedule, onDragComplete]
  );

  // ────────── 리사이즈 핸들러 ──────────
  const handleResizeMouseDown = useCallback(
    (direction: "start" | "end", e: React.MouseEvent) => {
      if (!resizable || !isEditable) return;
      e.preventDefault();
      e.stopPropagation();

      startXRef.current = e.clientX;
      movedRef.current = false;
      setIsResizing(true);
      setResizeOffset(0);
      setResizeDir(direction);

      const handleMouseMove = (moveEvent: MouseEvent) => {
        const delta = moveEvent.clientX - startXRef.current;
        if (Math.abs(delta) > MIN_MOVE_THRESHOLD) {
          movedRef.current = true;
        }
        setResizeOffset(delta);
      };

      const handleMouseUp = (upEvent: MouseEvent) => {
        const finalDelta = upEvent.clientX - startXRef.current;
        setIsResizing(false);
        setResizeOffset(0);

        if (movedRef.current && Math.abs(finalDelta) > MIN_MOVE_THRESHOLD) {
          onResizeComplete?.(schedule, direction, finalDelta);
        }

        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    },
    [resizable, isEditable, schedule, onResizeComplete]
  );

  // ────────── 클릭 핸들러 ──────────
  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      if (movedRef.current) return;
      e.stopPropagation();
      onClick?.(schedule);
    },
    [onClick, schedule]
  );

  // ────────── 드래그/리사이즈 중 시각적 위치 계산 ──────────
  let visualLeft = position.left;
  let visualWidth = position.width;

  if (isDragging) {
    visualLeft += dragOffset;
  }

  if (isResizing) {
    if (resizeDir === "start") {
      visualLeft += resizeOffset;
      visualWidth -= resizeOffset;
    } else {
      visualWidth += resizeOffset;
    }
  }

  visualWidth = Math.max(10, visualWidth);

  // ────────── 마일스톤 렌더링 (단일 날짜 마커) ──────────
  if (isMilestone) {
    return (
      <div
        ref={barRef}
        className="absolute flex cursor-pointer items-center justify-center"
        style={{
          left: visualLeft + position.width / 2 - 8,
          top: position.top + position.height / 2 - 8,
          width: 16,
          height: 16,
        }}
        onClick={handleClick}
        title={schedule.title}
      >
        <div
          className="h-2.5 w-2.5 rotate-45 shadow-sm transition-transform hover:scale-125 sm:h-3 sm:w-3"
          style={{ backgroundColor: statusColor }}
        />
      </div>
    );
  }

  // ────────── 일반 스케줄 바 렌더링 ──────────
  return (
    <div
      ref={barRef}
      className={cn(
        "absolute cursor-pointer rounded-md shadow-sm transition-shadow",
        "hover:z-10 hover:shadow-md",
        isDragging && "z-20 opacity-70 shadow-lg",
        isResizing && "z-20 opacity-80",
        draggable && isEditable && "cursor-grab",
        isDragging && "cursor-grabbing",
        hasConflict && "ring-2 ring-destructive ring-offset-1"
      )}
      style={{
        left: visualLeft,
        top: position.top + 4,
        width: visualWidth,
        height: position.height - 8,
        backgroundColor: statusColor,
      }}
      onClick={handleClick}
      onMouseDown={handleMouseDown}
      title={schedule.title}
    >
      {/* 진행률 바 */}
      {config.showProgress && schedule.progress !== undefined && (
        <div
          className="absolute inset-y-0 left-0 rounded-l-md bg-white opacity-30"
          style={{ width: progressWidth }}
        />
      )}

      {/* 제목 */}
      <div className="relative z-10 truncate px-1.5 py-0.5 text-[10px] font-medium text-white sm:px-2 sm:py-1 sm:text-xs">
        {schedule.title}
      </div>

      {/* 진행률 텍스트 */}
      {config.showProgress && schedule.progress !== undefined && (
        <div className="absolute right-1 top-1/2 -translate-y-1/2 text-[8px] font-medium text-white/80 sm:right-2 sm:text-[10px]">
          {schedule.progress}%
        </div>
      )}

      {/* 충돌 인디케이터 */}
      {hasConflict && (
        <div className="absolute -right-0.5 -top-0.5 sm:-right-1 sm:-top-1">
          <AlertTriangle className="h-2.5 w-2.5 fill-destructive text-white sm:h-3 sm:w-3" />
        </div>
      )}

      {/* 리사이즈 핸들 - 왼쪽 */}
      {resizable && isEditable && (
        <div
          className="absolute bottom-0 left-0 top-0 w-1.5 cursor-ew-resize rounded-l-md hover:bg-white/20 sm:w-2"
          onMouseDown={(e) => handleResizeMouseDown("start", e)}
        />
      )}

      {/* 리사이즈 핸들 - 오른쪽 */}
      {resizable && isEditable && (
        <div
          className="absolute bottom-0 right-0 top-0 w-1.5 cursor-ew-resize rounded-r-md hover:bg-white/20 sm:w-2"
          onMouseDown={(e) => handleResizeMouseDown("end", e)}
        />
      )}
    </div>
  );
}
