import React, { useState, useMemo } from "react";
import {
  FaUser,
  FaChevronDown,
  FaChevronRight,
  FaChevronLeft,
  FaChevronRight as FaArrowRight,
} from "react-icons/fa";
import { PsGanttTask } from "../../../types/ps";
import { mockEmployees } from "../../../mocks/mockEmployees";
import { mockProductionOrders } from "../../../mocks/mockProductionOrders";
import { mockWorkOrders } from "../../../mocks/mockWorkOrders";
import { mockWorkCenters } from "../../../mocks/mockWorkCenters";
import { PriorityEnum } from "../../../types/common";
import {
  getProductionOrderStatus,
  getWorkOrderStatus,
} from "../../../utils/erp";

interface PlanningGanttProps {
  workCenterId?: string;
}

export const PlanningGantt: React.FC<PlanningGanttProps> = ({
  workCenterId,
}) => {
  const getInitialExpandedItems = () => {
    const expandedItems = new Set<string>();
    const firstTwoOrders = mockProductionOrders.slice(0, 2);
    firstTwoOrders.forEach((order) => {
      expandedItems.add(`prod-${order.id}`);
      const orderWorkOrders = mockWorkOrders.filter(
        (wo) => wo.productionOrderId === order.id
      );
      orderWorkOrders.forEach((wo) => {
        expandedItems.add(`work-${wo.id}`);
      });
    });
    return expandedItems;
  };

  const [expandedItems, setExpandedItems] = useState<Set<string>>(
    getInitialExpandedItems()
  );
  const [selectedWorkCenter, setSelectedWorkCenter] = useState<string>(
    workCenterId || ""
  );
  const [viewMode, setViewMode] = useState<"day" | "week" | "month" | "year">(
    "week"
  );
  const [currentDate, setCurrentDate] = useState<Date>(new Date());

  const generateDateRange = () => {
    const startDate = new Date(currentDate);

    if (viewMode === "day") {
      const hours = [];
      for (let i = 0; i < 24; i++) {
        const hour = new Date(startDate);
        hour.setHours(i, 0, 0, 0);
        hours.push(hour);
      }
      return hours;
    } else if (viewMode === "week") {
      const weekStart = new Date(startDate);
      const dayOfWeek = weekStart.getDay();
      const daysToSubtract = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
      weekStart.setDate(weekStart.getDate() - daysToSubtract);
      weekStart.setHours(0, 0, 0, 0);

      const dates = [];
      for (let i = 0; i < 7; i++) {
        const date = new Date(weekStart);
        date.setDate(weekStart.getDate() + i);
        dates.push(date);
      }
      return dates;
    } else if (viewMode === "month") {
      const monthStart = new Date(
        currentDate.getFullYear(),
        currentDate.getMonth(),
        1
      );
      const daysInMonth = new Date(
        currentDate.getFullYear(),
        currentDate.getMonth() + 1,
        0
      ).getDate();

      const dates = [];
      for (let i = 0; i < daysInMonth; i++) {
        const date = new Date(monthStart);
        date.setDate(monthStart.getDate() + i);
        dates.push(date);
      }
      return dates;
    } else {
      const yearStart = new Date(currentDate.getFullYear(), 0, 1);
      const months = [];
      for (let i = 0; i < 12; i++) {
        const month = new Date(yearStart);
        month.setMonth(i);
        months.push(month);
      }
      return months;
    }
  };

  const dateRange = generateDateRange();

  const filteredData = useMemo(() => {
    const createGanttData = (): PsGanttTask[] => {
      return mockProductionOrders.map((order) => {
        const workOrders = mockWorkOrders
          .filter((wo) => wo.productionOrderId === order.id)
          .map((wo) => ({
            id: `work-${wo.id}`,
            name: wo.operation?.name || wo.workOrderNumber,
            type: "task" as const,
            startDate: wo.plannedStartDate,
            endDate: wo.plannedEndDate,
            progress:
              Math.round((wo.confirmedQuantity / wo.plannedQuantity) * 100) ||
              0,
            assignee: wo.assignedOperators[0]
              ? mockEmployees.find((e) => e.id === wo.assignedOperators[0])
              : undefined,
            status: getWorkOrderStatus(wo.status),
            priority: order.priority,
            level: 1,
            children: [],
            estimatedHours: wo.processTime / 60,
            hoursWorked: wo.actualProcessTime ? wo.actualProcessTime / 60 : 0,
          }));

        return {
          id: `prod-${order.id}`,
          name: `${order.orderNumber} - ${order.materials
            .map((m) => m.material?.name)
            .join(", ")}`,
          type: "project" as const,
          startDate: order.plannedStartDate,
          endDate: order.plannedEndDate,
          progress:
            order.confirmedQuantity && order.plannedQuantity
              ? Math.round(
                  (order.confirmedQuantity / order.plannedQuantity) * 100
                )
              : 0,
          status: getProductionOrderStatus(order.status),
          priority: order.priority,
          level: 0,
          children: workOrders,
        };
      });
    };

    const filterByWorkCenter = (tasks: PsGanttTask[]): PsGanttTask[] => {
      if (!selectedWorkCenter) return tasks;
      return tasks
        .map((task) => {
          if (
            task.type === "task" &&
            task.assignee?.id !== selectedWorkCenter
          ) {
            return null;
          }

          if (task.children) {
            const filteredChildren = filterByWorkCenter(task.children).filter(
              Boolean
            ) as PsGanttTask[];
            if (filteredChildren.length > 0) {
              return { ...task, children: filteredChildren };
            } else if (
              task.type === "task" &&
              task.assignee?.id === selectedWorkCenter
            ) {
              return task;
            }
            return null;
          }

          return task;
        })
        .filter(Boolean) as PsGanttTask[];
    };

    const allGanttTasks = createGanttData();
    return filterByWorkCenter(allGanttTasks);
  }, [selectedWorkCenter]);

  const toggleExpand = (id: string) => {
    const newExpanded = new Set(expandedItems);
    if (newExpanded.has(id)) {
      newExpanded.delete(id);
    } else {
      newExpanded.add(id);
    }
    setExpandedItems(newExpanded);
  };

  const getPriorityColor = (priority: PriorityEnum) => {
    switch (priority) {
      case PriorityEnum.High:
        return "text-red-600 bg-red-50 border-red-200";
      case PriorityEnum.Normal:
        return "text-blue-600 bg-blue-50 border-blue-200";
      case PriorityEnum.Low:
        return "text-green-600 bg-green-50 border-green-200";
      default:
        return "text-gray-600 bg-gray-50 border-gray-200";
    }
  };

  const navigatePrevious = () => {
    const newDate = new Date(currentDate);
    if (viewMode === "day") newDate.setDate(newDate.getDate() - 1);
    else if (viewMode === "week") newDate.setDate(newDate.getDate() - 7);
    else if (viewMode === "month") newDate.setMonth(newDate.getMonth() - 1);
    else newDate.setFullYear(newDate.getFullYear() - 1);
    setCurrentDate(newDate);
  };

  const navigateNext = () => {
    const newDate = new Date(currentDate);
    if (viewMode === "day") newDate.setDate(newDate.getDate() + 1);
    else if (viewMode === "week") newDate.setDate(newDate.getDate() + 7);
    else if (viewMode === "month") newDate.setMonth(newDate.getMonth() + 1);
    else newDate.setFullYear(newDate.getFullYear() + 1);
    setCurrentDate(newDate);
  };

  const navigateToday = () => {
    setCurrentDate(new Date());
  };

  const getCurrentDateInfo = () => {
    if (viewMode === "day") {
      return currentDate.toLocaleDateString("tr-TR", {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
      });
    } else if (viewMode === "week") {
      const weekStart = new Date(currentDate);
      const dayOfWeek = weekStart.getDay();
      const daysToSubtract = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
      weekStart.setDate(weekStart.getDate() - daysToSubtract);
      const weekEnd = new Date(weekStart);
      weekEnd.setDate(weekStart.getDate() + 6);
      return `${weekStart.toLocaleDateString("tr-TR", {
        day: "numeric",
        month: "short",
      })} - ${weekEnd.toLocaleDateString("tr-TR", {
        day: "numeric",
        month: "short",
        year: "numeric",
      })}`;
    } else if (viewMode === "month") {
      return currentDate.toLocaleDateString("tr-TR", {
        year: "numeric",
        month: "long",
      });
    } else {
      return currentDate.toLocaleDateString("tr-TR", { year: "numeric" });
    }
  };

  const calculateTaskPosition = (startDate: Date, endDate: Date) => {
    const chartStart = dateRange[0];
    const chartEnd = dateRange[dateRange.length - 1];
    const taskStart = new Date(startDate);
    const taskEnd = new Date(endDate);

    if (viewMode === "day") {
      const dayStart = new Date(chartStart);
      dayStart.setHours(0, 0, 0, 0);
      const dayEnd = new Date(chartStart);
      dayEnd.setHours(23, 59, 59, 999);
      if (taskEnd < dayStart || taskStart > dayEnd)
        return { left: "100%", width: "0%", isVisible: false };
      const startHour =
        taskStart > dayStart
          ? taskStart.getHours() + taskStart.getMinutes() / 60
          : 0;
      const endHour =
        taskEnd < dayEnd ? taskEnd.getHours() + taskEnd.getMinutes() / 60 : 24;
      const left = (startHour / 24) * 100;
      const width = Math.max(1, ((endHour - startHour) / 24) * 100);
      return { left: `${left}%`, width: `${width}%`, isVisible: true };
    } else if (viewMode === "week") {
      const weekStart = new Date(chartStart);
      const weekEnd = new Date(chartEnd);
      weekEnd.setHours(23, 59, 59, 999);
      if (taskEnd < weekStart || taskStart > weekEnd)
        return { left: "100%", width: "0%", isVisible: false };
      const startDay =
        taskStart > weekStart
          ? Math.floor(
              (taskStart.getTime() - weekStart.getTime()) /
                (1000 * 60 * 60 * 24)
            )
          : 0;
      const endDay =
        taskEnd < weekEnd
          ? Math.ceil(
              (taskEnd.getTime() - weekStart.getTime()) / (1000 * 60 * 60 * 24)
            )
          : 7;
      const left = (startDay / 7) * 100;
      const width = Math.max(1, ((endDay - startDay) / 7) * 100);
      return { left: `${left}%`, width: `${width}%`, isVisible: true };
    } else if (viewMode === "month") {
      const monthStart = new Date(chartStart);
      const monthEnd = new Date(chartEnd);
      monthEnd.setHours(23, 59, 59, 999);
      if (taskEnd < monthStart || taskStart > monthEnd)
        return { left: "100%", width: "0%", isVisible: false };
      const daysInMonth = dateRange.length;
      const startDay =
        taskStart > monthStart
          ? Math.floor(
              (taskStart.getTime() - monthStart.getTime()) /
                (1000 * 60 * 60 * 24)
            )
          : 0;
      const endDay =
        taskEnd < monthEnd
          ? Math.ceil(
              (taskEnd.getTime() - monthStart.getTime()) / (1000 * 60 * 60 * 24)
            )
          : daysInMonth;
      const left = (startDay / daysInMonth) * 100;
      const width = Math.max(1, ((endDay - startDay) / daysInMonth) * 100);
      return { left: `${left}%`, width: `${width}%`, isVisible: true };
    } else {
      const yearStart = new Date(chartStart);
      const yearEnd = new Date(chartEnd);
      yearEnd.setMonth(11, 31);
      yearEnd.setHours(23, 59, 59, 999);
      if (taskEnd < yearStart || taskStart > yearEnd)
        return { left: "100%", width: "0%", isVisible: false };
      const startMonth = taskStart > yearStart ? taskStart.getMonth() : 0;
      const endMonth = taskEnd < yearEnd ? taskEnd.getMonth() + 1 : 12;
      const left = (startMonth / 12) * 100;
      const width = Math.max(1, ((endMonth - startMonth) / 12) * 100);
      return { left: `${left}%`, width: `${width}%`, isVisible: true };
    }
  };

  const renderTask = (task: PsGanttTask): React.ReactNode => {
    const hasChildren = task.children && task.children.length > 0;
    const isExpanded = expandedItems.has(task.id);
    const indent = task.level * 20;

    return (
      <React.Fragment key={task.id}>
        <div className="flex items-center border-b border-gray-100 hover:bg-gray-50 min-h-[36px]">
          {/* Task Info */}
          <div className="w-1/3 sm:w-1/4 p-1 border-r border-gray-200">
            <div
              className="flex items-center"
              style={{ paddingLeft: `${Math.min(indent, 30)}px` }}
            >
              {hasChildren && (
                <button
                  onClick={() => toggleExpand(task.id)}
                  className="mr-1 p-0.5 hover:bg-gray-200 rounded"
                >
                  {isExpanded ? (
                    <FaChevronDown className="h-2.5 w-2.5" />
                  ) : (
                    <FaChevronRight className="h-2.5 w-2.5" />
                  )}
                </button>
              )}
              {!hasChildren && <div className="w-3 sm:w-5"></div>}

              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-1 sm:gap-2">
                  <span
                    className={`font-medium text-xs truncate ${
                      task.type === "project"
                        ? "text-blue-900 font-semibold"
                        : "text-gray-900"
                    }`}
                    title={task.name}
                  >
                    {task.name}
                  </span>
                  <span
                    className={`px-1 py-0 text-[10px] border rounded flex-shrink-0 hidden sm:inline ${getPriorityColor(
                      task.priority
                    )}`}
                  >
                    {task.priority}
                  </span>
                </div>

                {task.type === "task" && task.assignee && (
                  <div className="flex items-center gap-1 mt-0.5 text-xs text-gray-600">
                    <FaUser className="h-2 w-2 flex-shrink-0" />
                    <span className="truncate text-xs">
                      {task.assignee.firstName} {task.assignee.lastName}
                    </span>
                    {task.hoursWorked && task.estimatedHours && (
                      <span className="text-xs bg-gray-100 px-1 py-0.5 rounded flex-shrink-0 hidden md:inline">
                        {task.hoursWorked}h / {task.estimatedHours}h
                      </span>
                    )}
                  </div>
                )}

                <div className="mt-1 text-xs text-gray-500 truncate hidden sm:block">
                  {task.startDate.toLocaleDateString("tr-TR")} -{" "}
                  {task.endDate.toLocaleDateString("tr-TR")}
                </div>
              </div>
            </div>
          </div>

          {/* Gantt Chart */}
          <div className="w-2/3 sm:w-3/4 p-1 relative">
            <div className="relative h-6 bg-gray-100 rounded">
              {(() => {
                const position = calculateTaskPosition(
                  task.startDate,
                  task.endDate
                );

                if (task.type === "task" && position.isVisible) {
                  return (
                    <div
                      className={`absolute h-5 mt-0.5 rounded shadow-sm group cursor-pointer border border-white border-opacity-20`}
                      style={{ left: position.left, width: position.width }}
                      title={`${task.name} - ${task.progress}% tamamlandı`}
                    >
                      <div
                        className="h-full bg-black bg-opacity-15 rounded-lg relative overflow-hidden"
                        style={{ width: `${task.progress}%` }}
                      >
                        <div className="absolute inset-0 bg-white bg-opacity-20"></div>
                      </div>
                      <div className="absolute inset-0 flex items-center justify-center text-white text-[10px] font-bold drop-shadow-sm z-10">
                        {task.progress}%
                      </div>
                      <div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white text-xs rounded py-1 px-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap z-20 hidden sm:block">
                        <div className="font-semibold">{task.name}</div>
                        <div className="mt-1">
                          İlerleme: {task.progress}% tamamlandı
                        </div>
                        <div>
                          Planlanan Başlangıç:{" "}
                          {task.startDate.toLocaleDateString("tr-TR")}
                        </div>
                        <div>
                          Planlanan Bitiş:{" "}
                          {task.endDate.toLocaleDateString("tr-TR")}
                        </div>
                        <div className="absolute top-full left-1/2 transform -translate-x-1/2 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-800"></div>
                      </div>
                    </div>
                  );
                }

                if (task.type !== "task" && position.isVisible) {
                  return (
                    <div
                      className="absolute h-2 mt-2 bg-gradient-to-r from-gray-400 to-gray-600 rounded-full group cursor-pointer shadow-sm border border-white border-opacity-30"
                      style={{ left: position.left, width: position.width }}
                      title={`${task.name}`}
                    >
                      <div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white text-xs rounded py-1 px-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap z-20 hidden sm:block">
                        <div className="font-semibold">{task.name}</div>
                        <div>
                          Planlanan Başlangıç:{" "}
                          {task.startDate.toLocaleDateString("tr-TR")}
                        </div>
                        <div>
                          Planlanan Bitiş:{" "}
                          {task.endDate.toLocaleDateString("tr-TR")}
                        </div>
                        <div className="absolute top-full left-1/2 transform -translate-x-1/2 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-800"></div>
                      </div>
                    </div>
                  );
                }

                return null;
              })()}
            </div>
          </div>
        </div>

        {hasChildren &&
          isExpanded &&
          task.children?.map((child) => renderTask(child))}
      </React.Fragment>
    );
  };

  return (
    <>
      <div className="mb-3 mt-2">
        <div className="flex items-center gap-3">
          <div>
            <h2 className="text-xl font-bold text-gray-900">
              Planlama Gantt Şeması
            </h2>
            <p className="text-sm text-gray-600 mt-1">
              Üretim ve iş emirlerinizi zaman çizelgesinde yönetin.
            </p>
          </div>
        </div>
      </div>

      <div className="bg-white rounded-lg shadow-sm border h-full flex flex-col">
        <div className="p-2 border-b border-gray-200 flex-shrink-0">
          <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
            <div className="flex items-center justify-center gap-2">
              <button
                onClick={navigatePrevious}
                className="p-1.5 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
              >
                <FaChevronLeft className="h-4 w-4" />
              </button>
              <div className="text-sm font-semibold text-gray-900 min-w-[180px] text-center">
                {getCurrentDateInfo()}
              </div>
              <button
                onClick={navigateNext}
                className="p-1.5 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
              >
                <FaArrowRight className="h-4 w-4" />
              </button>
              <button
                onClick={navigateToday}
                className="px-2 py-1 text-xs bg-blue-600 text-white hover:bg-blue-700 rounded-lg transition-colors"
              >
                Bugün
              </button>
            </div>

            <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-2">
              <select
                value={selectedWorkCenter}
                onChange={(e) => setSelectedWorkCenter(e.target.value)}
                className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full sm:w-auto"
              >
                <option value="">Tüm İş Merkezleri</option>
                {mockWorkCenters.map((wc) => (
                  <option key={wc.id} value={wc.id}>
                    {wc.name}
                  </option>
                ))}
              </select>

              <select
                value={viewMode}
                onChange={(e) =>
                  setViewMode(
                    e.target.value as "day" | "week" | "month" | "year"
                  )
                }
                className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full sm:w-auto"
              >
                <option value="day">Günlük</option>
                <option value="week">Haftalık</option>
                <option value="month">Aylık</option>
                <option value="year">Yıllık</option>
              </select>
            </div>
          </div>
        </div>

        <div className="flex border-b border-gray-200 flex-shrink-0">
          <div className="w-1/3 sm:w-1/4 p-2 border-r border-gray-200 bg-gray-50 font-semibold text-xs">
            Üretim Emri / İş Emri
          </div>
          <div className="w-2/3 sm:w-3/4 p-2 bg-gray-50">
            <div className="flex justify-between text-xs font-semibold">
              {dateRange.map((date) => (
                <div
                  key={date.toISOString()}
                  className="text-center min-w-0 flex-1"
                >
                  <div className="truncate">
                    {viewMode === "day"
                      ? date.toLocaleTimeString("tr-TR", {
                          hour: "2-digit",
                          minute: "2-digit",
                        })
                      : viewMode === "week"
                      ? date.toLocaleDateString("tr-TR", { day: "2-digit" })
                      : viewMode === "year"
                      ? date.toLocaleDateString("tr-TR", { month: "short" })
                      : date.toLocaleDateString("tr-TR", { day: "2-digit" })}
                  </div>
                  {viewMode !== "day" && viewMode !== "year" && (
                    <div className="text-xs text-gray-500 hidden sm:block">
                      {date.toLocaleDateString("tr-TR", { weekday: "short" })}
                    </div>
                  )}
                  {viewMode === "year" && (
                    <div className="text-xs text-gray-500 hidden sm:block">
                      {date.getFullYear()}
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="flex-1 overflow-auto">
          {filteredData.map((task) => renderTask(task))}
        </div>
      </div>
    </>
  );
};
