"use client";

import React, { useCallback, useMemo, useRef, useState } from "react";
import {
  ChevronLeft,
  ChevronRight,
  Calendar,
  Plus,
  Loader2,
  ZoomIn,
  ZoomOut,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import {
  TimelineSchedulerComponentProps,
  ScheduleItem,
  ZoomLevel,
  DragEvent,
  ResizeEvent,
} from "./types";
import { useTimelineData } from "./hooks/useTimelineData";
import { TimelineHeader, ResourceRow } from "./components";
import { zoomLevelOptions, defaultTimelineSchedulerConfig } from "./config";

/**
 * v2-timeline-scheduler 메인 컴포넌트
 *
 * 간트차트 형태의 일정/계획 시각화 및 편집 컴포넌트
 */
export function TimelineSchedulerComponent({
  config,
  isDesignMode = false,
  formData,
  externalSchedules,
  externalResources,
  isLoading: externalLoading,
  error: externalError,
  componentId,
  onDragEnd,
  onResizeEnd,
  onScheduleClick,
  onCellClick,
  onAddSchedule,
}: TimelineSchedulerComponentProps) {
  const containerRef = useRef<HTMLDivElement>(null);

  // 드래그/리사이즈 상태
  const [dragState, setDragState] = useState<{
    schedule: ScheduleItem;
    startX: number;
    startY: number;
  } | null>(null);

  const [resizeState, setResizeState] = useState<{
    schedule: ScheduleItem;
    direction: "start" | "end";
    startX: number;
  } | null>(null);

  // 타임라인 데이터 훅
  const {
    schedules,
    resources,
    isLoading: hookLoading,
    error: hookError,
    zoomLevel,
    setZoomLevel,
    viewStartDate,
    viewEndDate,
    goToPrevious,
    goToNext,
    goToToday,
    updateSchedule,
  } = useTimelineData(config, externalSchedules, externalResources);

  const isLoading = externalLoading ?? hookLoading;
  const error = externalError ?? hookError;

  // 설정값
  const rowHeight = config.rowHeight || defaultTimelineSchedulerConfig.rowHeight!;
  const headerHeight = config.headerHeight || defaultTimelineSchedulerConfig.headerHeight!;
  const resourceColumnWidth =
    config.resourceColumnWidth || defaultTimelineSchedulerConfig.resourceColumnWidth!;
  const cellWidthConfig = config.cellWidth || defaultTimelineSchedulerConfig.cellWidth!;
  const cellWidth = cellWidthConfig[zoomLevel] || 60;

  // 리소스가 없으면 스케줄의 resourceId로 자동 생성
  const effectiveResources = useMemo(() => {
    if (resources.length > 0) {
      return resources;
    }

    // 스케줄에서 고유한 resourceId 추출하여 자동 리소스 생성
    const uniqueResourceIds = new Set<string>();
    schedules.forEach((schedule) => {
      if (schedule.resourceId) {
        uniqueResourceIds.add(schedule.resourceId);
      }
    });

    return Array.from(uniqueResourceIds).map((id) => ({
      id,
      name: id, // resourceId를 이름으로 사용
    }));
  }, [resources, schedules]);

  // 리소스별 스케줄 그룹화
  const schedulesByResource = useMemo(() => {
    const grouped = new Map<string, ScheduleItem[]>();

    effectiveResources.forEach((resource) => {
      grouped.set(resource.id, []);
    });

    schedules.forEach((schedule) => {
      const list = grouped.get(schedule.resourceId);
      if (list) {
        list.push(schedule);
      } else {
        // 리소스가 없는 스케줄은 첫 번째 리소스에 할당
        const firstResource = effectiveResources[0];
        if (firstResource) {
          const firstList = grouped.get(firstResource.id);
          if (firstList) {
            firstList.push(schedule);
          }
        }
      }
    });

    return grouped;
  }, [schedules, effectiveResources]);

  // 줌 레벨 변경
  const handleZoomIn = useCallback(() => {
    const levels: ZoomLevel[] = ["month", "week", "day"];
    const currentIdx = levels.indexOf(zoomLevel);
    if (currentIdx < levels.length - 1) {
      setZoomLevel(levels[currentIdx + 1]);
    }
  }, [zoomLevel, setZoomLevel]);

  const handleZoomOut = useCallback(() => {
    const levels: ZoomLevel[] = ["month", "week", "day"];
    const currentIdx = levels.indexOf(zoomLevel);
    if (currentIdx > 0) {
      setZoomLevel(levels[currentIdx - 1]);
    }
  }, [zoomLevel, setZoomLevel]);

  // 스케줄 클릭 핸들러
  const handleScheduleClick = useCallback(
    (schedule: ScheduleItem) => {
      const resource = effectiveResources.find((r) => r.id === schedule.resourceId);
      if (resource && onScheduleClick) {
        onScheduleClick({ schedule, resource });
      }
    },
    [effectiveResources, onScheduleClick]
  );

  // 빈 셀 클릭 핸들러
  const handleCellClick = useCallback(
    (resourceId: string, date: Date) => {
      if (onCellClick) {
        onCellClick({
          resourceId,
          date: date.toISOString().split("T")[0],
        });
      }
    },
    [onCellClick]
  );

  // 드래그 시작
  const handleDragStart = useCallback(
    (schedule: ScheduleItem, e: React.MouseEvent) => {
      setDragState({
        schedule,
        startX: e.clientX,
        startY: e.clientY,
      });
    },
    []
  );

  // 드래그 종료
  const handleDragEnd = useCallback(() => {
    if (dragState) {
      // TODO: 드래그 결과 계산 및 업데이트
      setDragState(null);
    }
  }, [dragState]);

  // 리사이즈 시작
  const handleResizeStart = useCallback(
    (schedule: ScheduleItem, direction: "start" | "end", e: React.MouseEvent) => {
      setResizeState({
        schedule,
        direction,
        startX: e.clientX,
      });
    },
    []
  );

  // 리사이즈 종료
  const handleResizeEnd = useCallback(() => {
    if (resizeState) {
      // TODO: 리사이즈 결과 계산 및 업데이트
      setResizeState(null);
    }
  }, [resizeState]);

  // 추가 버튼 클릭
  const handleAddClick = useCallback(() => {
    if (onAddSchedule && effectiveResources.length > 0) {
      onAddSchedule(
        effectiveResources[0].id,
        new Date().toISOString().split("T")[0]
      );
    }
  }, [onAddSchedule, effectiveResources]);

  // 디자인 모드 플레이스홀더
  if (isDesignMode) {
    return (
      <div className="w-full h-full min-h-[200px] border-2 border-dashed border-muted-foreground/30 rounded-lg flex items-center justify-center bg-muted/10">
        <div className="text-center text-muted-foreground">
          <Calendar className="h-8 w-8 mx-auto mb-2" />
          <p className="text-sm font-medium">타임라인 스케줄러</p>
          <p className="text-xs mt-1">
            {config.selectedTable
              ? `테이블: ${config.selectedTable}`
              : "테이블을 선택하세요"}
          </p>
        </div>
      </div>
    );
  }

  // 로딩 상태
  if (isLoading) {
    return (
      <div
        className="w-full flex items-center justify-center bg-muted/10 rounded-lg"
        style={{ height: config.height || 500 }}
      >
        <div className="flex items-center gap-2 text-muted-foreground">
          <Loader2 className="h-5 w-5 animate-spin" />
          <span className="text-sm">로딩 중...</span>
        </div>
      </div>
    );
  }

  // 에러 상태
  if (error) {
    return (
      <div
        className="w-full flex items-center justify-center bg-destructive/10 rounded-lg"
        style={{ height: config.height || 500 }}
      >
        <div className="text-center text-destructive">
          <p className="text-sm font-medium">오류 발생</p>
          <p className="text-xs mt-1">{error}</p>
        </div>
      </div>
    );
  }

  // 스케줄 데이터 없음
  if (schedules.length === 0) {
    return (
      <div
        className="w-full flex items-center justify-center bg-muted/10 rounded-lg border"
        style={{ height: config.height || 500 }}
      >
        <div className="text-center text-muted-foreground">
          <Calendar className="h-10 w-10 mx-auto mb-3 opacity-50" />
          <p className="text-sm font-medium">스케줄 데이터가 없습니다</p>
          <p className="text-xs mt-2 max-w-[200px]">
            좌측 테이블에서 품목을 선택하거나,<br />
            스케줄 생성 버튼을 눌러 스케줄을 생성하세요
          </p>
        </div>
      </div>
    );
  }

  return (
    <div
      ref={containerRef}
      className="w-full border rounded-lg overflow-hidden bg-background"
      style={{
        height: config.height || 500,
        maxHeight: config.maxHeight,
      }}
    >
      {/* 툴바 */}
      {config.showToolbar !== false && (
        <div className="flex items-center justify-between px-3 py-2 border-b bg-muted/30">
          {/* 네비게이션 */}
          <div className="flex items-center gap-1">
            {config.showNavigation !== false && (
              <>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={goToPrevious}
                  className="h-7 px-2"
                >
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={goToToday}
                  className="h-7 px-2"
                >
                  오늘
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={goToNext}
                  className="h-7 px-2"
                >
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </>
            )}

            {/* 현재 날짜 범위 표시 */}
            <span className="ml-2 text-sm text-muted-foreground">
              {viewStartDate.getFullYear()}년 {viewStartDate.getMonth() + 1}월{" "}
              {viewStartDate.getDate()}일 ~{" "}
              {viewEndDate.getMonth() + 1}월 {viewEndDate.getDate()}일
            </span>
          </div>

          {/* 오른쪽 컨트롤 */}
          <div className="flex items-center gap-2">
            {/* 줌 컨트롤 */}
            {config.showZoomControls !== false && (
              <div className="flex items-center gap-1">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={handleZoomOut}
                  disabled={zoomLevel === "month"}
                  className="h-7 px-2"
                >
                  <ZoomOut className="h-4 w-4" />
                </Button>
                <span className="text-xs text-muted-foreground min-w-[24px] text-center">
                  {zoomLevelOptions.find((o) => o.value === zoomLevel)?.label}
                </span>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={handleZoomIn}
                  disabled={zoomLevel === "day"}
                  className="h-7 px-2"
                >
                  <ZoomIn className="h-4 w-4" />
                </Button>
              </div>
            )}

            {/* 추가 버튼 */}
            {config.showAddButton !== false && config.editable && (
              <Button
                variant="default"
                size="sm"
                onClick={handleAddClick}
                className="h-7"
              >
                <Plus className="h-4 w-4 mr-1" />
                추가
              </Button>
            )}
          </div>
        </div>
      )}

      {/* 타임라인 본문 */}
      <div
        className="overflow-auto"
        style={{
          height: config.showToolbar !== false
            ? `calc(100% - 48px)`
            : "100%",
        }}
      >
        <div className="min-w-max">
          {/* 헤더 */}
          <TimelineHeader
            startDate={viewStartDate}
            endDate={viewEndDate}
            zoomLevel={zoomLevel}
            cellWidth={cellWidth}
            headerHeight={headerHeight}
            resourceColumnWidth={resourceColumnWidth}
            showTodayLine={config.showTodayLine}
          />

          {/* 리소스 행들 */}
          <div>
            {effectiveResources.map((resource) => (
              <ResourceRow
                key={resource.id}
                resource={resource}
                schedules={schedulesByResource.get(resource.id) || []}
                startDate={viewStartDate}
                endDate={viewEndDate}
                zoomLevel={zoomLevel}
                rowHeight={rowHeight}
                cellWidth={cellWidth}
                resourceColumnWidth={resourceColumnWidth}
                config={config}
                onScheduleClick={handleScheduleClick}
                onCellClick={handleCellClick}
                onDragStart={handleDragStart}
                onDragEnd={handleDragEnd}
                onResizeStart={handleResizeStart}
                onResizeEnd={handleResizeEnd}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
