"use client";

import { useMemo, useState } from "react";

type PeakTimesChartRow = {
  period: string;
  label: string;
  bookedHours: number;
  capacityHours: number;
  baseAvailableHours: number;
  holidayHoursDeduction: number;
  absenceDayEquivalent: number;
  absenceHoursDeduction: number;
  utilizationPct: number;
  remainingHours: number;
  overbookedHours: number;
  isCurrentPeriod: boolean;
  calendarContextCount: number;
  calendarLocations: Array<{
    countryCode: string | null;
    countryName: string | null;
    federalState: string | null;
    metroCityName: string | null;
    resourceCount: number;
    effectiveAvailableHours: number;
  }>;
};

interface PeakTimesChartProps {
  rows: PeakTimesChartRow[];
  selectedPeriod: string | null;
  onSelectedPeriodChange?: (period: string) => void;
}

function formatHours(value: number): string {
  return new Intl.NumberFormat("de-DE", {
    minimumFractionDigits: 0,
    maximumFractionDigits: 1,
  }).format(value);
}

function formatDayEquivalent(value: number): string {
  return Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1);
}

function formatLocation(input: PeakTimesChartRow["calendarLocations"][number]): string {
  const parts = [input.countryCode ?? input.countryName, input.federalState, input.metroCityName]
    .filter((part): part is string => Boolean(part));
  return parts.length > 0 ? parts.join(" / ") : "No calendar context";
}

function utilizationBarTone(utilizationPct: number): string {
  if (utilizationPct > 100) return "bg-red-500";
  if (utilizationPct > 75) return "bg-emerald-500";
  if (utilizationPct >= 50) return "bg-amber-400";
  return "bg-rose-400";
}

function utilizationTextTone(utilizationPct: number): string {
  if (utilizationPct > 100) return "text-red-600 dark:text-red-300";
  if (utilizationPct > 75) return "text-emerald-600 dark:text-emerald-300";
  if (utilizationPct >= 50) return "text-amber-600 dark:text-amber-300";
  return "text-rose-600 dark:text-rose-300";
}

export default function PeakTimesChart({
  rows,
  selectedPeriod,
  onSelectedPeriodChange,
}: PeakTimesChartProps) {
  const [hoveredPeriod, setHoveredPeriod] = useState<string | null>(null);

  const fallbackPeriod = selectedPeriod && rows.some((row) => row.period === selectedPeriod)
    ? selectedPeriod
    : rows[0]?.period ?? null;
  const activePeriod = hoveredPeriod ?? fallbackPeriod;
  const activeRow = useMemo(
    () => rows.find((row) => row.period === activePeriod) ?? rows[0] ?? null,
    [activePeriod, rows],
  );
  const chartMaxPct = useMemo(() => {
    const maxUtilization = Math.max(100, ...rows.map((row) => row.utilizationPct));
    return Math.max(120, Math.ceil(maxUtilization / 20) * 20);
  }, [rows]);
  const tickValues = useMemo(() => {
    const base = [0, 50, 100];
    return chartMaxPct > 100 ? [...base, chartMaxPct] : base;
  }, [chartMaxPct]);
  const referenceLineBottom = (100 / chartMaxPct) * 100;

  if (rows.length === 0) {
    return (
      <div className="flex h-full items-center justify-center rounded-[22px] border border-dashed border-slate-200 bg-slate-50/80 text-sm text-slate-400 dark:border-slate-700 dark:bg-slate-900/40">
        No allocation data in the selected horizon.
      </div>
    );
  }

  return (
    <div className="flex h-full min-h-[15rem] flex-col rounded-[22px] border border-slate-200/80 bg-[linear-gradient(180deg,rgba(255,255,255,0.98),rgba(248,250,252,0.96))] p-3 shadow-sm dark:border-slate-700/70 dark:bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(15,23,42,0.98))]">
      <div className="flex flex-wrap items-center justify-between gap-2 border-b border-slate-200/70 pb-2 dark:border-slate-700/60">
        <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-slate-400">
          Overall Utilization
        </div>

        {activeRow ? (
          <div className="min-w-0 text-right">
            <div className={`truncate text-sm font-semibold ${utilizationTextTone(activeRow.utilizationPct)}`}>
              {activeRow.label} · {activeRow.utilizationPct}%
            </div>
            <div className="truncate text-[11px] text-slate-500 dark:text-slate-400">
              {formatHours(activeRow.bookedHours)}h / {formatHours(activeRow.capacityHours)}h
            </div>
          </div>
        ) : null}
      </div>

      <div className="mt-3 flex min-h-[12rem] flex-1 gap-2">
        <div className="flex w-8 shrink-0 flex-col justify-between pb-6 text-right text-[9px] font-medium text-slate-400">
          {[...tickValues].reverse().map((tick) => (
            <span key={tick}>{tick}%</span>
          ))}
        </div>

        <div className="relative min-w-0 flex-1">
          <div className="pointer-events-none absolute inset-0 bottom-6">
            {[...tickValues].reverse().map((tick) => {
              const bottom = (tick / chartMaxPct) * 100;
              return (
                <div
                  key={tick}
                  className="absolute left-0 right-0 border-t border-dashed border-slate-200/80 dark:border-slate-700/50"
                  style={{ bottom: `${bottom}%` }}
                />
              );
            })}

            <div
              className="absolute left-0 right-0 border-t border-slate-300/90 dark:border-slate-500/80"
              style={{ bottom: `${referenceLineBottom}%` }}
            />
          </div>

          <div
            className="grid h-full items-end gap-1.5 pb-6 sm:gap-2"
            style={{ gridTemplateColumns: `repeat(${rows.length}, minmax(0, 1fr))` }}
          >
            {rows.map((row) => {
              const height = Math.min((row.utilizationPct / chartMaxPct) * 100, 100);
              const isActive = row.period === activePeriod;
              const isPinned = row.period === fallbackPeriod;

              return (
                <button
                  key={row.period}
                  type="button"
                  className="group flex h-full min-w-0 flex-col items-center rounded-2xl px-1 text-left transition-colors"
                  title={[
                    `${row.label}: ${row.utilizationPct}% utilization`,
                    `${formatHours(row.bookedHours)}h booked`,
                    `${formatHours(row.capacityHours)}h effective capacity`,
                    `${formatHours(row.baseAvailableHours)}h base`,
                    `${formatHours(row.holidayHoursDeduction)}h holidays`,
                    `${formatHours(row.absenceHoursDeduction)}h absences (${formatDayEquivalent(row.absenceDayEquivalent)}d)`,
                    `${row.calendarContextCount} calendar base${row.calendarContextCount === 1 ? "" : "s"}`,
                    ...row.calendarLocations.slice(0, 3).map((location) =>
                      `${formatLocation(location)}: ${location.resourceCount}x, ${formatHours(location.effectiveAvailableHours)}h capacity`),
                    `${formatHours(row.remainingHours)}h free`,
                    `${formatHours(row.overbookedHours)}h overbooked`,
                  ].join(", ")}
                  onMouseEnter={() => setHoveredPeriod(row.period)}
                  onMouseLeave={() => setHoveredPeriod((current) => (current === row.period ? null : current))}
                  onClick={() => onSelectedPeriodChange?.(row.period)}
                  style={{
                    backgroundColor: isPinned
                      ? "rgba(14, 165, 233, 0.08)"
                      : isActive
                        ? "rgba(148, 163, 184, 0.08)"
                        : "transparent",
                  }}
                >
                  <div className="relative flex min-h-0 flex-1 w-full items-end justify-center px-0.5">
                    <div className="relative h-full w-full max-w-[34px] sm:max-w-[42px]">
                      <div className="absolute inset-x-0 bottom-0 h-full rounded-t-xl bg-slate-100 dark:bg-slate-800/80" />
                      <div
                        className={`absolute inset-x-0 bottom-0 rounded-t-xl transition-all duration-150 ${utilizationBarTone(row.utilizationPct)} ${
                          isActive ? "opacity-100" : "opacity-80 group-hover:opacity-100"
                        }`}
                        style={{ height: `${Math.max(height, row.utilizationPct > 0 ? 6 : 0)}%` }}
                      />
                    </div>
                  </div>

                  <div className="mt-2 min-w-0 shrink-0">
                    <div className="truncate text-center text-[10px] font-semibold uppercase tracking-[0.08em] text-slate-500 dark:text-slate-400">
                      {row.label}
                    </div>
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}
