"use client";

import React, { useMemo, useRef } from "react";
import { cn } from "@/lib/utils";
import { Flame } from "lucide-react";
import { ScheduleItem, TimelineSchedulerConfig, ZoomLevel } from "../types";
import { statusOptions, dayLabels } from "../config";

interface ItemScheduleGroup {
  itemCode: string;
  itemName: string;
  hourlyCapacity: number;
  dailyCapacity: number;
  schedules: ScheduleItem[];
  totalPlanQty: number;
  totalCompletedQty: number;
  remainingQty: number;
  dueDates: { date: string; isUrgent: boolean }[];
}

interface ItemTimelineCardProps {
  group: ItemScheduleGroup;
  viewStartDate: Date;
  viewEndDate: Date;
  zoomLevel: ZoomLevel;
  cellWidth: number;
  config: TimelineSchedulerConfig;
  onScheduleClick?: (schedule: ScheduleItem) => void;
}

const toDateString = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;

const addDays = (d: Date, n: number) => {
  const r = new Date(d);
  r.setDate(r.getDate() + n);
  return r;
};

const diffDays = (a: Date, b: Date) =>
  Math.round((a.getTime() - b.getTime()) / (1000 * 60 * 60 * 24));

function generateDateCells(start: Date, end: Date) {
  const cells: { date: Date; label: string; dayLabel: string; isWeekend: boolean; isToday: boolean; dateStr: string }[] = [];
  const today = toDateString(new Date());
  let cur = new Date(start);
  while (cur <= end) {
    const d = new Date(cur);
    const dow = d.getDay();
    cells.push({
      date: d,
      label: String(d.getDate()),
      dayLabel: dayLabels[dow],
      isWeekend: dow === 0 || dow === 6,
      isToday: toDateString(d) === today,
      dateStr: toDateString(d),
    });
    cur = addDays(cur, 1);
  }
  return cells;
}

export function ItemTimelineCard({
  group,
  viewStartDate,
  viewEndDate,
  zoomLevel,
  cellWidth,
  config,
  onScheduleClick,
}: ItemTimelineCardProps) {
  const scrollRef = useRef<HTMLDivElement>(null);

  const dateCells = useMemo(
    () => generateDateCells(viewStartDate, viewEndDate),
    [viewStartDate, viewEndDate]
  );

  const totalWidth = dateCells.length * cellWidth;

  const dueDateSet = useMemo(() => {
    const set = new Set<string>();
    group.dueDates.forEach((d) => set.add(d.date));
    return set;
  }, [group.dueDates]);

  const urgentDateSet = useMemo(() => {
    const set = new Set<string>();
    group.dueDates.filter((d) => d.isUrgent).forEach((d) => set.add(d.date));
    return set;
  }, [group.dueDates]);

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

  const isUrgentItem = group.dueDates.some((d) => d.isUrgent);
  const hasRemaining = group.remainingQty > 0;

  return (
    <div className="rounded-lg border bg-background">
      {/* 품목 헤더 */}
      <div className="flex items-start justify-between border-b px-3 py-2 sm:px-4 sm:py-3">
        <div className="flex items-start gap-2">
          <input type="checkbox" className="mt-1 h-3.5 w-3.5 rounded border-border sm:h-4 sm:w-4" />
          <div>
            <p className="text-[10px] text-muted-foreground sm:text-xs">{group.itemCode}</p>
            <p className="text-xs font-semibold sm:text-sm">{group.itemName}</p>
          </div>
        </div>
        <div className="text-right text-[10px] text-muted-foreground sm:text-xs">
          <p>
            시간당: <span className="font-semibold text-foreground">{group.hourlyCapacity.toLocaleString()}</span> EA
          </p>
          <p>
            일일: <span className="font-semibold text-foreground">{group.dailyCapacity.toLocaleString()}</span> EA
          </p>
        </div>
      </div>

      {/* 타임라인 영역 */}
      <div ref={scrollRef} className="overflow-x-auto">
        <div style={{ width: totalWidth, minWidth: "100%" }}>
          {/* 날짜 헤더 */}
          <div className="flex border-b">
            {dateCells.map((cell) => {
              const isDueDate = dueDateSet.has(cell.dateStr);
              const isUrgentDate = urgentDateSet.has(cell.dateStr);
              return (
                <div
                  key={cell.dateStr}
                  className={cn(
                    "flex shrink-0 flex-col items-center justify-center border-r py-1",
                    cell.isWeekend && "bg-muted/30",
                    cell.isToday && "bg-primary/5",
                    isDueDate && "ring-2 ring-inset ring-destructive",
                    isUrgentDate && "bg-destructive/5"
                  )}
                  style={{ width: cellWidth }}
                >
                  <span className={cn(
                    "text-[10px] font-medium sm:text-xs",
                    cell.isToday && "text-primary",
                    cell.isWeekend && "text-destructive/70"
                  )}>
                    {cell.label}
                  </span>
                  <span className={cn(
                    "text-[8px] sm:text-[10px]",
                    cell.isToday && "text-primary",
                    cell.isWeekend && "text-destructive/50",
                    !cell.isToday && !cell.isWeekend && "text-muted-foreground"
                  )}>
                    {cell.dayLabel}
                  </span>
                </div>
              );
            })}
          </div>

          {/* 스케줄 바 영역 */}
          <div className="relative" style={{ height: 48 }}>
            {group.schedules.map((schedule) => {
              const schedStart = new Date(schedule.startDate);
              const schedEnd = new Date(schedule.endDate);

              const startOffset = diffDays(schedStart, viewStartDate);
              const endOffset = diffDays(schedEnd, viewStartDate);

              const left = Math.max(0, startOffset * cellWidth);
              const right = Math.min(totalWidth, (endOffset + 1) * cellWidth);
              const width = Math.max(cellWidth * 0.5, right - left);

              if (right < 0 || left > totalWidth) return null;

              const qty = Number(schedule.data?.plan_qty) || 0;
              const color = statusColor(schedule.status);

              return (
                <div
                  key={schedule.id}
                  className="absolute cursor-pointer rounded-md shadow-sm transition-shadow hover:shadow-md"
                  style={{
                    left,
                    top: 8,
                    width,
                    height: 32,
                    backgroundColor: color,
                  }}
                  onClick={() => onScheduleClick?.(schedule)}
                  title={`${schedule.title} (${schedule.startDate} ~ ${schedule.endDate})`}
                >
                  <div className="flex h-full items-center justify-center truncate px-1 text-[10px] font-medium text-white sm:text-xs">
                    {qty > 0 ? `${qty.toLocaleString()} EA` : schedule.title}
                  </div>
                </div>
              );
            })}

            {/* 납기일 마커 */}
            {group.dueDates.map((dueDate, idx) => {
              const d = new Date(dueDate.date);
              const offset = diffDays(d, viewStartDate);
              if (offset < 0 || offset > dateCells.length) return null;
              const left = offset * cellWidth + cellWidth / 2;
              return (
                <div
                  key={`due-${idx}`}
                  className="absolute top-0 bottom-0"
                  style={{ left, width: 0 }}
                >
                  <div className={cn(
                    "absolute top-0 h-full w-px",
                    dueDate.isUrgent ? "bg-destructive" : "bg-destructive/40"
                  )} />
                </div>
              );
            })}
          </div>
        </div>
      </div>

      {/* 하단 잔량 영역 */}
      <div className="flex items-center gap-2 border-t px-3 py-1.5 sm:px-4 sm:py-2">
        <input type="checkbox" className="h-3.5 w-3.5 rounded border-border sm:h-4 sm:w-4" />
        {hasRemaining && (
          <div className={cn(
            "flex items-center gap-1 rounded-md px-2 py-0.5 text-[10px] font-semibold sm:text-xs",
            isUrgentItem
              ? "bg-destructive/10 text-destructive"
              : "bg-warning/10 text-warning"
          )}>
            {isUrgentItem && <Flame className="h-3 w-3 sm:h-3.5 sm:w-3.5" />}
            {group.remainingQty.toLocaleString()} EA
          </div>
        )}
        {/* 스크롤 인디케이터 */}
        <div className="ml-auto flex-1">
          <div className="h-1 w-16 rounded-full bg-muted" />
        </div>
      </div>
    </div>
  );
}

/**
 * 스케줄 데이터를 품목별로 그룹화
 */
export function groupSchedulesByItem(schedules: ScheduleItem[]): ItemScheduleGroup[] {
  const grouped = new Map<string, ScheduleItem[]>();

  schedules.forEach((s) => {
    const key = s.data?.item_code || "unknown";
    if (!grouped.has(key)) grouped.set(key, []);
    grouped.get(key)!.push(s);
  });

  const result: ItemScheduleGroup[] = [];

  grouped.forEach((items, itemCode) => {
    const first = items[0];
    const hourlyCapacity = Number(first.data?.hourly_capacity) || 0;
    const dailyCapacity = Number(first.data?.daily_capacity) || 0;
    const totalPlanQty = items.reduce((sum, s) => sum + (Number(s.data?.plan_qty) || 0), 0);
    const totalCompletedQty = items.reduce((sum, s) => sum + (Number(s.data?.completed_qty) || 0), 0);

    const dueDates: { date: string; isUrgent: boolean }[] = [];
    const seenDueDates = new Set<string>();
    items.forEach((s) => {
      const dd = s.data?.due_date;
      if (dd) {
        const dateStr = typeof dd === "string" ? dd.split("T")[0] : "";
        if (dateStr && !seenDueDates.has(dateStr)) {
          seenDueDates.add(dateStr);
          const isUrgent = s.data?.priority === "urgent" || s.data?.priority === "high";
          dueDates.push({ date: dateStr, isUrgent });
        }
      }
    });

    result.push({
      itemCode,
      itemName: first.data?.item_name || first.title || itemCode,
      hourlyCapacity,
      dailyCapacity,
      schedules: items.sort(
        (a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()
      ),
      totalPlanQty,
      totalCompletedQty,
      remainingQty: totalPlanQty - totalCompletedQty,
      dueDates: dueDates.sort((a, b) => a.date.localeCompare(b.date)),
    });
  });

  return result.sort((a, b) => a.itemCode.localeCompare(b.itemCode));
}
