"use client";

import { useState } from "react";
import {
  DOMAIN_COLORS,
  DOMAIN_LABELS,
} from "~/components/analytics/computation-graph/domain-colors";
import { useComputationGraphData } from "~/components/analytics/computation-graph/useComputationGraphData";
import ComputationGraph2D from "~/components/analytics/ComputationGraph2D";
import ComputationGraph3D from "~/components/analytics/ComputationGraph3D";

type Dimension = "2d" | "3d";

interface ResourceHolidayMeta {
  date: string;
  name: string;
  scope: string;
  calendarName: string | null;
}

interface ResourceFactorMeta {
  weeklyAvailability?: Record<string, number>;
  baseWorkingDays?: number;
  effectiveWorkingDays?: number;
  baseAvailableHours?: number;
  effectiveAvailableHours?: number;
  publicHolidayCount?: number;
  publicHolidayWorkdayCount?: number;
  publicHolidayHoursDeduction?: number;
  absenceDayCount?: number;
  absenceHoursDeduction?: number;
  chargeableHours?: number;
  utilizationPct?: number;
}

interface ResourceGraphMeta {
  resourceName?: string;
  resourceEid?: string;
  month?: string;
  countryCode?: string | null;
  countryName?: string | null;
  federalState?: string | null;
  metroCityName?: string | null;
  resolvedHolidays?: ResourceHolidayMeta[];
  factors?: ResourceFactorMeta;
}

function formatNumber(value: number | undefined, digits = 1): string {
  if (typeof value !== "number" || Number.isNaN(value)) {
    return "—";
  }
  return new Intl.NumberFormat("de-DE", {
    minimumFractionDigits: digits,
    maximumFractionDigits: digits,
  }).format(value);
}

export default function ComputationGraphClient() {
  const state = useComputationGraphData();
  const [dimension, setDimension] = useState<Dimension>("2d");

  const {
    viewMode, setViewMode,
    resourceId, setResourceId,
    month, setMonth,
    projectId, setProjectId,
    resources, projects,
    isLoading,
    activeDomains,
    graphData,
    rawData,
    highlightedNodes, setHighlightedNodes,
    domainFilter, toggleDomain,
  } = state;

  const resourceMeta = viewMode === "resource"
    ? (rawData?.meta as ResourceGraphMeta | undefined)
    : undefined;
  const resourceFactors = resourceMeta?.factors;
  const weeklyAvailabilityEntries: Array<[string, number | undefined]> = resourceFactors?.weeklyAvailability
    ? [
      ["Mo", resourceFactors.weeklyAvailability.monday],
      ["Di", resourceFactors.weeklyAvailability.tuesday],
      ["Mi", resourceFactors.weeklyAvailability.wednesday],
      ["Do", resourceFactors.weeklyAvailability.thursday],
      ["Fr", resourceFactors.weeklyAvailability.friday],
      ["Sa", resourceFactors.weeklyAvailability.saturday],
      ["So", resourceFactors.weeklyAvailability.sunday],
    ]
    : [];
  const weeklyAvailability = resourceFactors?.weeklyAvailability
    ? weeklyAvailabilityEntries
      .filter((entry): entry is [string, number] => typeof entry[1] === "number" && entry[1] > 0)
      .map(([label, hours]) => `${label} ${formatNumber(hours, 1)}h`)
      .join(" · ")
    : "—";
  const topHolidays = resourceMeta?.resolvedHolidays?.slice(0, 6) ?? [];

  return (
    <div className="flex h-[calc(100vh-4rem)] flex-col">
      {/* ── Header Bar ── */}
      <div className="flex flex-wrap items-center gap-3 border-b border-zinc-200 bg-white px-4 py-3 dark:border-zinc-700 dark:bg-zinc-900">
        {/* 2D / 3D Toggle */}
        <div className="flex rounded-lg border border-zinc-300 dark:border-zinc-600">
          <button
            onClick={() => setDimension("2d")}
            className={`px-3 py-1.5 text-sm font-medium transition-colors ${
              dimension === "2d"
                ? "bg-zinc-800 text-white dark:bg-zinc-200 dark:text-zinc-900"
                : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            } rounded-l-lg`}
          >
            2D
          </button>
          <button
            onClick={() => setDimension("3d")}
            className={`px-3 py-1.5 text-sm font-medium transition-colors ${
              dimension === "3d"
                ? "bg-zinc-800 text-white dark:bg-zinc-200 dark:text-zinc-900"
                : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            } rounded-r-lg`}
          >
            3D
          </button>
        </div>

        {/* View Mode Toggle */}
        <div className="flex rounded-lg border border-zinc-300 dark:border-zinc-600">
          <button
            onClick={() => setViewMode("resource")}
            className={`px-3 py-1.5 text-sm font-medium transition-colors ${
              viewMode === "resource"
                ? "bg-blue-600 text-white"
                : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            } rounded-l-lg`}
          >
            Resource View
          </button>
          <button
            onClick={() => setViewMode("project")}
            className={`px-3 py-1.5 text-sm font-medium transition-colors ${
              viewMode === "project"
                ? "bg-blue-600 text-white"
                : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            } rounded-r-lg`}
          >
            Project View
          </button>
        </div>

        {/* Selectors */}
        {viewMode === "resource" ? (
          <>
            <select
              value={resourceId}
              onChange={(e) => setResourceId(e.target.value)}
              className="rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-200"
            >
              <option value="">Select Resource...</option>
              {resources.map((r: { id: string; displayName: string; eid: string }) => (
                <option key={r.id} value={r.id}>
                  {r.displayName} ({r.eid})
                </option>
              ))}
            </select>
            <input
              type="month"
              value={month}
              onChange={(e) => setMonth(e.target.value)}
              className="rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-200"
            />
          </>
        ) : (
          <select
            value={projectId}
            onChange={(e) => setProjectId(e.target.value)}
            className="rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-200"
          >
            <option value="">Select Project...</option>
            {(Array.isArray(projects) ? projects : []).map((p: { id: string; name: string; shortCode?: string | null }) => (
              <option key={p.id} value={p.id}>
                {p.shortCode ? `${p.shortCode} — ` : ""}{p.name}
              </option>
            ))}
          </select>
        )}

        {/* Meta info */}
        {graphData.nodes.length > 0 && (
          <span className="ml-auto text-xs text-zinc-500">
            {graphData.nodes.length} nodes, {graphData.links.length} links
          </span>
        )}

        {/* Clear highlight */}
        {highlightedNodes && (
          <button
            onClick={() => setHighlightedNodes(null)}
            className="rounded bg-zinc-200 px-2 py-1 text-xs text-zinc-700 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-300"
          >
            Clear highlight
          </button>
        )}
      </div>

      {/* ── Main Area ── */}
      <div className="relative flex flex-1 overflow-hidden">
        {/* Domain Filter Sidebar */}
        <div className="flex w-48 flex-col gap-1 border-r border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-700 dark:bg-zinc-900">
          <span className="mb-1 text-xs font-semibold uppercase text-zinc-500">Domains</span>
          {activeDomains.map((domain) => (
            <button
              key={domain}
              onClick={() => toggleDomain(domain)}
              className={`flex items-center gap-2 rounded px-2 py-1 text-left text-sm transition-colors ${
                domainFilter.has(domain)
                  ? "text-zinc-400 line-through"
                  : "text-zinc-700 dark:text-zinc-300"
              } hover:bg-zinc-200 dark:hover:bg-zinc-800`}
            >
              <span
                className="inline-block h-3 w-3 rounded-full"
                style={{
                  backgroundColor: domainFilter.has(domain) ? "#9ca3af" : DOMAIN_COLORS[domain],
                }}
              />
              {DOMAIN_LABELS[domain]}
            </button>
          ))}
        </div>

        {/* Graph View */}
        <div className="flex-1 overflow-hidden">
          {isLoading ? (
            <div className="flex h-full items-center justify-center text-zinc-500">
              Loading computation graph...
            </div>
          ) : dimension === "2d" ? (
            <ComputationGraph2D state={state} />
          ) : (
            <ComputationGraph3D state={state} />
          )}
        </div>

        {viewMode === "resource" && resourceMeta && (
          <aside className="w-[24rem] overflow-y-auto border-l border-zinc-200 bg-white/90 p-4 dark:border-zinc-700 dark:bg-zinc-950/90">
            <div className="space-y-4">
              <section className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-900">
                <div className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Bezugsgroessen</div>
                <div className="mt-2 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
                  {resourceMeta.resourceName ?? "Resource"}
                </div>
                <div className="text-sm text-zinc-500">{resourceMeta.resourceEid ?? "—"} · {resourceMeta.month ?? month}</div>
                <div className="mt-3 grid grid-cols-1 gap-2 text-sm text-zinc-700 dark:text-zinc-300">
                  <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                    <div className="text-xs uppercase text-zinc-500">Land</div>
                    <div>{resourceMeta.countryName ?? resourceMeta.countryCode ?? "—"}{resourceMeta.countryCode ? ` (${resourceMeta.countryCode})` : ""}</div>
                  </div>
                  <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                    <div className="text-xs uppercase text-zinc-500">Bundesland / Region</div>
                    <div>{resourceMeta.federalState ?? "—"}</div>
                  </div>
                  <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                    <div className="text-xs uppercase text-zinc-500">Ort / Metro</div>
                    <div>{resourceMeta.metroCityName ?? "—"}</div>
                  </div>
                  <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                    <div className="text-xs uppercase text-zinc-500">Wochenverfuegbarkeit</div>
                    <div>{weeklyAvailability}</div>
                  </div>
                </div>
              </section>

              <section className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-900">
                <div className="flex items-center justify-between">
                  <div className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Feiertagsbasis</div>
                  <div className="text-xs text-zinc-500">
                    {resourceFactors?.publicHolidayCount ?? 0} Feiertage, {resourceFactors?.publicHolidayWorkdayCount ?? 0} wirksam
                  </div>
                </div>
                <div className="mt-3 space-y-2">
                  {topHolidays.length > 0 ? topHolidays.map((holiday) => (
                    <div
                      key={`${holiday.date}-${holiday.name}`}
                      className="rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm dark:border-zinc-800 dark:bg-zinc-950"
                    >
                      <div className="font-medium text-zinc-900 dark:text-zinc-100">{holiday.name}</div>
                      <div className="text-xs text-zinc-500">
                        {holiday.date} · {holiday.scope} · {holiday.calendarName ?? "Kalender"}
                      </div>
                    </div>
                  )) : (
                    <div className="rounded-lg border border-dashed border-zinc-200 px-3 py-2 text-sm text-zinc-500 dark:border-zinc-800">
                      Keine aufgeloesten Feiertage im gewaehlten Monat.
                    </div>
                  )}
                </div>
              </section>

              <section className="rounded-xl border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-900">
                <div className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Herleitung</div>
                <div className="mt-3 space-y-2">
                  <div className="rounded-lg bg-white px-3 py-2 text-sm dark:bg-zinc-950">
                    <div className="text-xs uppercase text-zinc-500">SAH Formel</div>
                    <div className="font-medium text-zinc-900 dark:text-zinc-100">
                      {formatNumber(resourceFactors?.baseAvailableHours)}h - {formatNumber(resourceFactors?.publicHolidayHoursDeduction)}h - {formatNumber(resourceFactors?.absenceHoursDeduction)}h = {formatNumber(resourceFactors?.effectiveAvailableHours)}h
                    </div>
                  </div>
                  <div className="grid grid-cols-2 gap-2 text-sm">
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Basistage</div>
                      <div>{formatNumber(resourceFactors?.baseWorkingDays, 0)}</div>
                    </div>
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Effektive Tage</div>
                      <div>{formatNumber(resourceFactors?.effectiveWorkingDays, 0)}</div>
                    </div>
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Feiertagsabzug</div>
                      <div>{formatNumber(resourceFactors?.publicHolidayHoursDeduction)}h</div>
                    </div>
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Abwesenheitsabzug</div>
                      <div>{formatNumber(resourceFactors?.absenceHoursDeduction)}h</div>
                    </div>
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Chargeable Hours</div>
                      <div>{formatNumber(resourceFactors?.chargeableHours)}h</div>
                    </div>
                    <div className="rounded-lg bg-white px-3 py-2 dark:bg-zinc-950">
                      <div className="text-xs uppercase text-zinc-500">Auslastung</div>
                      <div>{formatNumber(resourceFactors?.utilizationPct)}%</div>
                    </div>
                  </div>
                </div>
              </section>
            </div>
          </aside>
        )}
      </div>
    </div>
  );
}
