import { useRef } from 'react'
import { GanttTimerangePicker } from './gantt-timerange-picker'

// Gantt header component rendering the timeline scale
export const GanttTimeline = ({ header }: { header: any }) => {
  const cellOpts = header.column.columnDef.meta?.cell
  const containerRef = useRef<HTMLDivElement>(null)
  if (!cellOpts) {
    return null
  }
  const ts = cellOpts.dateRangeFrom ?? cellOpts.timelineStart
  const te = cellOpts.dateRangeTo ?? cellOpts.timelineEnd
  if (!(ts instanceof Date) || !(te instanceof Date)) {
    return null
  }
  const timelineStartMs = ts.getTime()
  const timelineEndMs = te.getTime()
  if (timelineEndMs <= timelineStartMs) {
    return null
  }
  const firstFullYear = ts.getFullYear() + 1
  const totalYears = te.getFullYear() - ts.getFullYear() + 1

  const scale = containerRef.current?.getBoundingClientRect().width
    ? containerRef.current.getBoundingClientRect().width / (totalYears ?? 1)
    : 1
  const showMonths = scale / 12 >= 5

  const timelineDurationMs = timelineEndMs - timelineStartMs
  const firstYearPartialMs = new Date(firstFullYear, 0, 1).getTime() - timelineStartMs
  const lastYearPartialMs = timelineEndMs - new Date(te.getFullYear(), 0, 1).getTime()

  const firstMonthPartialMs = new Date(ts.getFullYear(), ts.getMonth() + 1, 1).getTime() - timelineStartMs
  const lastMonthPartialMs = timelineEndMs - new Date(te.getFullYear(), te.getMonth(), 1).getTime()

  return (
    <>
      <div className="absolute right-8 top-1/2 z-10 -translate-y-1/2">
        <GanttTimerangePicker
          initialDateFrom={cellOpts.dateRangeFrom ?? undefined}
          initialDateTo={cellOpts.dateRangeTo ?? undefined}
          onRangeChange={cellOpts.onRangeChange ?? undefined}
          timelineStart={cellOpts.timelineStart}
          timelineEnd={cellOpts.timelineEnd}
        />
      </div>
      <div ref={containerRef} className="pointer-events-none absolute left-0 right-0 bottom-0 z-0 h-3 flex px-1">
        {Array.from({ length: totalYears }, (_, i) => firstFullYear + i - 1).map((year, index) => (
          /* distribute space between years with flex-grow except for first and last as they might only be partial */
          <div
            key={year}
            className="h-full relative flex grow border-l border-neutral-300 dark:border-neutral-700 first:border-none first:grow-0 last:grow-0 overflow-hidden"
            style={
              // index == 0: first year, index == totalYears -1: last year
              index == 0 || index == totalYears - 1
                ? { width: `${((index == 0 ? firstYearPartialMs : lastYearPartialMs) / timelineDurationMs) * 100}%` }
                : undefined
            }
          >
            {showMonths && (
              /* first month with calculated width as it might only be partial */
              <div className="absolute bottom-0 left-0 right-0 flex h-1.5 w-full">
                {index == 0 && ts.getMonth() < 11 && (
                  <div
                    className="h-full border-r border-dashed border-neutral-300 dark:border-neutral-700"
                    style={{ width: `${(firstMonthPartialMs / firstYearPartialMs) * 100}%` }}
                  />
                )}
                {/* distribute rest of space between months with flex-grow */}
                {Array.from({
                  length: (index == totalYears - 1 ? te.getMonth() : 12) - (index == 0 ? ts.getMonth() + 1 : 0),
                }).map((_, monthIndex) => (
                  <div
                    key={`${year}-${(index == 0 ? ts.getMonth() + 1 : 0) + monthIndex}`}
                    className="grow h-full border-r border-dashed border-neutral-300 dark:border-neutral-700 last:border-0"
                  />
                ))}
                {/* last month with calculated width as it might only be partial */}
                {index == totalYears - 1 && te.getMonth() > 0 && (
                  <div className="h-full" style={{ width: `${(lastMonthPartialMs / lastYearPartialMs) * 100}%` }} />
                )}
              </div>
            )}

            <span className="ps-0.5 -mt-px text-xs text-neutral-500 dark:text-neutral-400 select-none z-1">{year}</span>
          </div>
        ))}
      </div>
    </>
  )
}
