'use client';

import { useMemo, useRef, useEffect, useState } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import type { Project, ChartViewMode } from './types';
import { GANTT_BAR_COLORS } from './types';

interface ProjectGanttChartProps {
  projects: Project[];
  viewMode: ChartViewMode;
  currentDate: Date;
  onProjectClick: (project: Project) => void;
  onDateChange: (date: Date) => void;
}

export default function ProjectGanttChart({
  projects,
  viewMode,
  currentDate,
  onProjectClick,
  onDateChange,
}: ProjectGanttChartProps) {
  const scrollContainerRef = useRef<HTMLDivElement>(null);
  const [isScrolling, setIsScrolling] = useState(false);

  // 현재 날짜 기준으로 표시할 기간 계산
  const { columns, startDate, endDate, yearGroups, monthGroups } = useMemo(() => {
    const now = currentDate;

    if (viewMode === 'day') {
      // 일 모드: 현재 월의 1일~말일
      const year = now.getFullYear();
      const month = now.getMonth();
      const daysInMonth = new Date(year, month + 1, 0).getDate();
      const cols = Array.from({ length: daysInMonth }, (_, i) => ({
        label: String(i + 1),
        date: new Date(year, month, i + 1),
        year,
        month,
      }));
      return {
        columns: cols,
        startDate: new Date(year, month, 1),
        endDate: new Date(year, month, daysInMonth),
        yearGroups: null,
        monthGroups: null,
      };
    } else if (viewMode === 'week') {
      // 주 모드: 현재 월 기준 전후 2개월 (총 12주)
      const year = now.getFullYear();
      const month = now.getMonth();

      // 전월 1일부터 시작
      const startMonth = month === 0 ? 11 : month - 1;
      const startYear = month === 0 ? year - 1 : year;
      const periodStart = new Date(startYear, startMonth, 1);

      // 다음월 말일까지
      const endMonth = month === 11 ? 0 : month + 1;
      const endYear = month === 11 ? year + 1 : year;
      const periodEnd = new Date(endYear, endMonth + 1, 0);

      // 주차별 컬럼 생성 (월요일 시작)
      const cols: { label: string; date: Date; year: number; month: number; weekStart: Date; weekEnd: Date }[] = [];
      const tempDate = new Date(periodStart);

      // 첫 번째 월요일 찾기
      while (tempDate.getDay() !== 1) {
        tempDate.setDate(tempDate.getDate() + 1);
      }

      let weekNum = 1;
      while (tempDate <= periodEnd) {
        const weekStart = new Date(tempDate);
        const weekEnd = new Date(tempDate);
        weekEnd.setDate(weekEnd.getDate() + 6);

        cols.push({
          label: `${weekNum}주`,
          date: new Date(tempDate),
          year: tempDate.getFullYear(),
          month: tempDate.getMonth(),
          weekStart,
          weekEnd,
        });

        tempDate.setDate(tempDate.getDate() + 7);
        weekNum++;
      }

      // 월별 그룹 계산
      const monthGroupsMap = new Map<string, number>();
      cols.forEach((col) => {
        const key = `${col.year}-${col.month}`;
        monthGroupsMap.set(key, (monthGroupsMap.get(key) || 0) + 1);
      });

      const mGroups = Array.from(monthGroupsMap.entries()).map(([key, count]) => {
        const [y, m] = key.split('-').map(Number);
        return { year: y, month: m, count, label: `${m + 1}월` };
      });

      return {
        columns: cols,
        startDate: cols[0]?.weekStart || periodStart,
        endDate: cols[cols.length - 1]?.weekEnd || periodEnd,
        yearGroups: null,
        monthGroups: mGroups,
      };
    } else {
      // 월 모드: 전년도 + 올해 (2년치, 24개월)
      const year = now.getFullYear();
      const prevYear = year - 1;
      const cols: { label: string; date: Date; year: number; month: number }[] = [];

      // 전년도 12개월
      for (let i = 0; i < 12; i++) {
        cols.push({
          label: `${i + 1}월`,
          date: new Date(prevYear, i, 1),
          year: prevYear,
          month: i,
        });
      }
      // 올해 12개월
      for (let i = 0; i < 12; i++) {
        cols.push({
          label: `${i + 1}월`,
          date: new Date(year, i, 1),
          year: year,
          month: i,
        });
      }

      return {
        columns: cols,
        startDate: new Date(prevYear, 0, 1),
        endDate: new Date(year, 11, 31),
        yearGroups: [
          { year: prevYear, count: 12 },
          { year: year, count: 12 },
        ],
        monthGroups: null,
      };
    }
  }, [viewMode, currentDate]);

  // 막대 위치 및 너비 계산
  const getBarStyle = (project: Project) => {
    const projectStart = new Date(project.startDate);
    const projectEnd = new Date(project.endDate);

    // 범위 밖이면 표시 안함
    if (projectEnd < startDate || projectStart > endDate) {
      return null;
    }

    // 시작/종료 위치 계산
    const totalDays = (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24);
    const barStartDays = Math.max(0, (projectStart.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
    const barEndDays = Math.min(totalDays, (projectEnd.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));

    const leftPercent = (barStartDays / totalDays) * 100;
    const widthPercent = ((barEndDays - barStartDays) / totalDays) * 100;

    // 색상 결정
    let bgColor: string = GANTT_BAR_COLORS.in_progress;
    if (project.status === 'completed') {
      bgColor = GANTT_BAR_COLORS.completed;
    } else if (project.hasUrgentIssue || project.status === 'urgent') {
      bgColor = GANTT_BAR_COLORS.urgent;
    }

    return {
      left: `${leftPercent}%`,
      width: `${Math.max(widthPercent, 1)}%`,
      backgroundColor: bgColor,
    };
  };

  // 이전/다음 이동
  const handlePrev = () => {
    const newDate = new Date(currentDate);
    if (viewMode === 'day') {
      newDate.setMonth(newDate.getMonth() - 1);
    } else if (viewMode === 'week') {
      newDate.setMonth(newDate.getMonth() - 1);
    } else {
      newDate.setFullYear(newDate.getFullYear() - 1);
    }
    onDateChange(newDate);
  };

  const handleNext = () => {
    const newDate = new Date(currentDate);
    if (viewMode === 'day') {
      newDate.setMonth(newDate.getMonth() + 1);
    } else if (viewMode === 'week') {
      newDate.setMonth(newDate.getMonth() + 1);
    } else {
      newDate.setFullYear(newDate.getFullYear() + 1);
    }
    onDateChange(newDate);
  };

  // 월 모드에서 올해 시작 위치로 스크롤
  useEffect(() => {
    if (scrollContainerRef.current && viewMode === 'month') {
      // 올해 1월 위치로 스크롤 (전년도 12개월 건너뛰기)
      const totalWidth = scrollContainerRef.current.scrollWidth;
      const scrollPosition = totalWidth / 2 - scrollContainerRef.current.clientWidth / 3;
      scrollContainerRef.current.scrollLeft = Math.max(0, scrollPosition);
    } else if (scrollContainerRef.current && viewMode === 'day') {
      const today = new Date();
      const dayOfMonth = today.getDate();
      const columnWidth = scrollContainerRef.current.scrollWidth / columns.length;
      const scrollPosition = (dayOfMonth - 1) * columnWidth - scrollContainerRef.current.clientWidth / 2;
      scrollContainerRef.current.scrollLeft = Math.max(0, scrollPosition);
    }
  }, [viewMode, columns.length]);

  return (
    <div className="border rounded-lg bg-card">
      {/* 헤더: 날짜 네비게이션 */}
      <div className="flex items-center justify-between p-3 border-b">
        <div className="flex items-center gap-2">
          <Button variant="outline" size="icon" onClick={handlePrev}>
            <ChevronLeft className="h-4 w-4" />
          </Button>
          <span className="text-sm font-medium min-w-[140px] text-center">
            {viewMode === 'day'
              ? `${currentDate.getFullYear()}년 ${currentDate.getMonth() + 1}월`
              : viewMode === 'week'
              ? `${currentDate.getFullYear()}년 ${currentDate.getMonth()}월 ~ ${currentDate.getMonth() + 2}월`
              : `${currentDate.getFullYear() - 1}년 ~ ${currentDate.getFullYear()}년`}
          </span>
          <Button variant="outline" size="icon" onClick={handleNext}>
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>

        {/* 범례 */}
        <div className="flex items-center gap-4 text-xs">
          <div className="flex items-center gap-1">
            <div className="w-3 h-3 rounded" style={{ backgroundColor: GANTT_BAR_COLORS.in_progress }} />
            <span>진행중</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-3 h-3 rounded" style={{ backgroundColor: GANTT_BAR_COLORS.completed }} />
            <span>종료</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-3 h-3 rounded" style={{ backgroundColor: GANTT_BAR_COLORS.urgent }} />
            <span>긴급 이슈</span>
          </div>
        </div>
      </div>

      {/* 차트 영역 */}
      <div className="overflow-hidden">
        <div
          ref={scrollContainerRef}
          className="overflow-x-auto"
          onMouseDown={() => setIsScrolling(true)}
          onMouseUp={() => setIsScrolling(false)}
          onMouseLeave={() => setIsScrolling(false)}
        >
          <div className={cn(
            viewMode === 'month' ? 'min-w-[1600px]' : viewMode === 'week' ? 'min-w-[1000px]' : 'min-w-[800px]'
          )}>
            {/* 전체를 하나의 세로 스크롤 영역으로 */}
            <div className="max-h-[450px] overflow-y-auto">
              {/* 연도 헤더 (월 모드에서만) */}
              {viewMode === 'month' && yearGroups && (
                <div className="flex bg-muted/50 sticky top-0 z-20">
                  {yearGroups.map((group) => (
                    <div
                      key={group.year}
                      className="flex-1 p-1.5 text-xs font-semibold text-center border-r border-border last:border-r-0"
                      style={{ flex: group.count }}
                    >
                      {group.year}년
                    </div>
                  ))}
                </div>
              )}

              {/* 월 헤더 (주 모드에서만) */}
              {viewMode === 'week' && monthGroups && (
                <div className="flex bg-muted/50 sticky top-0 z-20">
                  {monthGroups.map((group, idx) => (
                    <div
                      key={`${group.year}-${group.month}-${idx}`}
                      className="flex-1 p-1.5 text-xs font-semibold text-center border-r border-border last:border-r-0"
                      style={{ flex: group.count }}
                    >
                      {group.label}
                    </div>
                  ))}
                </div>
              )}

              {/* 컬럼 헤더 - 날짜/주/월 */}
              <div className={cn(
                'flex bg-muted/30 sticky z-10',
                (viewMode === 'month' || viewMode === 'week') ? 'top-[30px]' : 'top-0'
              )}>
                {columns.map((col, idx) => (
                  <div
                    key={idx}
                    className={cn(
                      'flex-1 p-2 text-xs text-center border-r border-border last:border-r-0',
                      viewMode === 'day' && col.date.getDay() === 0 && 'text-red-500',
                      viewMode === 'day' && col.date.getDay() === 6 && 'text-blue-500'
                    )}
                  >
                    {col.label}
                  </div>
                ))}
              </div>

              {/* 프로젝트 행들 (가로선 없음) */}
              {projects.length === 0 ? (
                <div className="p-8 text-center text-muted-foreground">
                  표시할 프로젝트가 없습니다.
                </div>
              ) : (
                projects.map((project) => {
                  const barStyle = getBarStyle(project);
                  return (
                    <div
                      key={project.id}
                      className="relative h-12 hover:bg-muted/10 cursor-pointer"
                      onClick={() => !isScrolling && onProjectClick(project)}
                    >
                      {/* 그리드 세로선 */}
                      <div className="absolute inset-0 flex">
                        {columns.map((_, idx) => (
                          <div key={idx} className="flex-1 border-r border-border last:border-r-0" />
                        ))}
                      </div>

                      {/* 막대 - 프로젝트명 직접 표시 */}
                      {barStyle && (
                        <div
                          className="absolute top-1/2 -translate-y-1/2 h-7 rounded text-xs text-white flex items-center px-2 truncate shadow-sm"
                          style={barStyle}
                        >
                          <span className="truncate font-medium">
                            [{project.partnerName}] {project.siteName} {project.progressRate}%
                          </span>
                        </div>
                      )}
                    </div>
                  );
                })
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
