"use client";

import {
  ArrowDown,
  ArrowUp,
  Atom,
  Bolt,
  Boxes,
  ChevronDown,
  CircleGauge,
  Factory,
  FlaskConical,
  Gauge,
  Network,
  Pickaxe,
  Zap,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react";

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  BELT_TYPES,
  beltCapacityPerSecond,
  calculateBeltLoad,
  resolveBeltLoad,
  type BeltId,
  type BeltStackSize,
} from "@/app/lib/belts";
import { calculateEnergy, FUSION_BLOCKS } from "@/app/lib/energy";
import {
  CHAIN_MACHINE_GROUPS,
  DEFAULT_MACHINE_PRIORITIES,
  DEFAULT_UNLOCKED_MACHINE_IDS,
  type MachinePreferenceGroup,
} from "@/app/lib/chain-machines";
import { moduleIsAllowed, toDisplayRate, unitLabel } from "@/app/lib/calculator";
import {
  buildFactoryTotals,
  type FactoryResourceTotal,
  type FactoryTotalsSnapshot,
  mostUsedRateUnit,
} from "@/app/lib/factory-totals";
import {
  MACHINES,
  QUALITY_BY_ID,
  RECIPE_BY_ID,
  iconFor,
  machinesForRecipe,
} from "@/app/lib/factorio-data";
import { localizedName, tr } from "@/app/lib/i18n";
import {
  DEFAULT_MINING_DRILL_ID,
  MINING_DRILLS,
  miningSourceForBaseline,
} from "@/app/lib/mining";
import { calculateScience, LABS, SCIENCE_RECIPE } from "@/app/lib/science";
import type {
  ChainOverride,
  EnergyInput,
  EnergySourceSelection,
  EnergyTechnology,
  Locale,
  LogisticsResult,
  LogisticsSettings,
  ModuleFamily,
  MiningDrillId,
  ProductionChainNode,
  ProductionChainResult,
  QualityId,
  RateUnit,
  ChainMasterSettings,
} from "@/app/lib/types";
import { FactorioIcon } from "./factorio-icon";
import {
  ExpandableSection,
  CollapsiblePanel,
  BeaconCountSelect,
  FieldLabel,
  GeometryDesign,
  MaterialRow,
  MetricCard,
  ModuleConfigurator,
  type ModuleConfig,
  QualitySelect,
  SectionTitle,
  SmartNumberInput,
  UnitSelect,
  formatMw,
  formatNumber,
  formatPower,
  resolvedModules,
} from "./calculator-widgets";

const selectClass = "h-10 w-full border-white/10 bg-[#17191b] text-zinc-100";

function SummaryKpi({
  label,
  value,
  tone = "cyan",
  className = "",
}: {
  label: string;
  value: React.ReactNode;
  tone?: "orange" | "cyan" | "green" | "purple";
  className?: string;
}) {
  return (
    <span
      className={`summary-kpi ${className}`}
      data-kpi-tone={tone}
    >
      <small>{label}</small>
      <strong>{value}</strong>
    </span>
  );
}

function moduleItemId(family: ModuleFamily, tier: 1 | 2 | 3): string {
  return `${family}-module${tier === 1 ? "" : `-${tier}`}`;
}

function InserterSettingsFields({
  settings,
  onChange,
  locale,
}: {
  settings: LogisticsSettings;
  onChange: (next: LogisticsSettings) => void;
  locale: Locale;
}) {
  return (
    <div className="grid gap-2 sm:grid-cols-2">
      <div>
        <FieldLabel>{tr(locale, "inserter")}</FieldLabel>
        <Select
          value={settings.inserterId}
          onValueChange={(inserterId) =>
            onChange({
              ...settings,
              inserterId: inserterId as LogisticsSettings["inserterId"],
            })
          }
        >
          <SelectTrigger className={selectClass}>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {[
              "inserter",
              "fast-inserter",
              "bulk-inserter",
              "stack-inserter",
            ].map((id) => (
              <SelectItem key={id} value={id}>
                <span className="flex items-center gap-2">
                  <FactorioIcon src={iconFor(id)} alt="" size="sm" />
                  {localizedName(id, locale, "entity")}
                </span>
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
      <div>
        <FieldLabel>{tr(locale, "inserterQuality")}</FieldLabel>
        <QualitySelect
          value={settings.inserterQuality}
          onChange={(inserterQuality) =>
            onChange({
              ...settings,
              inserterQuality: inserterQuality as QualityId,
            })
          }
          locale={locale}
        />
      </div>
      <div>
        <FieldLabel>{tr(locale, "capacityResearch")}</FieldLabel>
        <SmartNumberInput
          min={0}
          max={12}
          value={settings.capacityBonus}
          onValueChange={(capacityBonus) =>
            onChange({ ...settings, capacityBonus })
          }
        />
      </div>
      <div>
        <FieldLabel>{tr(locale, "handoff")}</FieldLabel>
        <Select
          value={settings.handoff}
          onValueChange={(handoff) =>
            onChange({
              ...settings,
              handoff: handoff as LogisticsSettings["handoff"],
            })
          }
        >
          <SelectTrigger className={selectClass}>
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {[
              "belt-machine",
              "container-machine",
              "machine-belt",
              "machine-container",
            ].map((id) => (
              <SelectItem key={id} value={id}>
                {id.replace("-", " → ")}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
    </div>
  );
}

export function LogisticsPanel({
  result,
  settings,
  onChange,
  locale,
}: {
  result: LogisticsResult;
  settings: LogisticsSettings;
  onChange: (next: LogisticsSettings) => void;
  locale: Locale;
}) {
  const solidFlows = result.flows.filter((flow) => flow.type === "item");
  const requiredInputInserters = solidFlows
    .filter((flow) => flow.direction === "input")
    .reduce((sum, flow) => sum + (flow.totalInserters ?? 0), 0);
  const requiredOutputInserters = solidFlows
    .filter((flow) => flow.direction === "output")
    .reduce((sum, flow) => sum + (flow.totalInserters ?? 0), 0);
  return (
    <ExpandableSection
      title={tr(locale, "logistics")}
      icons={[iconFor(settings.inserterId)]}
      open={false}
    >
      <div className="grid gap-2 sm:grid-cols-4">
        <div>
          <FieldLabel>{tr(locale, "inserter")}</FieldLabel>
          <Select
            value={settings.inserterId}
            onValueChange={(v) =>
              onChange({
                ...settings,
                inserterId: v as LogisticsSettings["inserterId"],
              })
            }
          >
            <SelectTrigger className={selectClass}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {[
                "inserter",
                "fast-inserter",
                "bulk-inserter",
                "stack-inserter",
              ].map((id) => (
                <SelectItem key={id} value={id}>
                  <span className="flex items-center gap-2">
                    <FactorioIcon src={iconFor(id)} alt="" size="sm" />
                    {localizedName(id, locale, "entity")}
                  </span>
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div>
          <FieldLabel>{tr(locale, "inserterQuality")}</FieldLabel>
          <QualitySelect
            value={settings.inserterQuality}
            onChange={(v) =>
              onChange({ ...settings, inserterQuality: v as QualityId })
            }
            locale={locale}
          />
        </div>
        <div>
          <FieldLabel>{tr(locale, "capacityResearch")}</FieldLabel>
          <SmartNumberInput
            min={0}
            max={12}
            value={settings.capacityBonus}
            onValueChange={(capacityBonus) =>
              onChange({ ...settings, capacityBonus })
            }
          />
        </div>
        <div>
          <FieldLabel>{tr(locale, "handoff")}</FieldLabel>
          <Select
            value={settings.handoff}
            onValueChange={(v) =>
              onChange({
                ...settings,
                handoff: v as LogisticsSettings["handoff"],
              })
            }
          >
            <SelectTrigger className={selectClass}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {[
                "belt-machine",
                "container-machine",
                "machine-belt",
                "machine-container",
              ].map((id) => (
                <SelectItem key={id} value={id}>
                  {id.replace("-", " → ")}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>
      <div className="grid gap-2 sm:grid-cols-2">
        {[
          ["input", tr(locale, "inputLoad"), requiredInputInserters],
          ["output", tr(locale, "outputLoad"), requiredOutputInserters],
        ].map(([direction, label, count]) => (
          <div
            key={String(direction)}
            className="inserter-total-card flex items-center gap-3 rounded-xl border border-[#f7a72d]/35 bg-[#f7a72d]/8 p-3"
          >
            <FactorioIcon src={iconFor(settings.inserterId)} alt="" size="lg" />
            <div className="min-w-0 flex-1">
              <p className="text-[10px] uppercase tracking-wider text-[#d7a95f]">
                {label} · {tr(locale, "insertersRequired")}
              </p>
              <p className="whitespace-normal break-words text-xs text-zinc-300">
                {localizedName(settings.inserterId, locale, "entity")}
              </p>
            </div>
            <strong className="font-mono text-2xl text-[#f7a72d]">
              {formatNumber(Number(count), locale, 0)} ×
            </strong>
          </div>
        ))}
      </div>
      <div className="grid gap-2 lg:grid-cols-2">
        {result.flows.map((flow) => (
          <div
            key={`${flow.direction}:${flow.type}:${flow.id}`}
            className="rounded-lg border border-white/7 bg-[#151719] p-3"
          >
            <div className="flex items-center gap-2">
              <FactorioIcon src={flow.icon} alt="" size="md" />
              <div className="min-w-0 flex-1">
                <p className="whitespace-normal break-words text-xs font-medium leading-tight">
                  {localizedName(flow.id, locale, flow.type)}
                </p>
                <p className="font-mono text-[9px] uppercase text-zinc-600">
                  {flow.direction === "input"
                    ? tr(locale, "inputLoad")
                    : tr(locale, "outputLoad")}
                </p>
              </div>
              <span className="font-mono text-xs">
                {formatNumber(flow.perMachineMax, locale)}/s
              </span>
            </div>
            <div className="mt-2 grid grid-cols-2 gap-2 text-[10px] text-zinc-500">
              <span>
                {tr(locale, "perMachine")}:{" "}
                {formatNumber(flow.perMachineMin, locale)}–
                {formatNumber(flow.perMachineMax, locale)}/s
              </span>
              <span className={flow.type === "item" ? "rounded-md border border-[#f7a72d]/25 bg-[#f7a72d]/7 px-2 py-1 font-semibold text-[#f7c16f]" : ""}>
                {flow.type === "fluid"
                  ? `${flow.pumps ?? 0} × ${localizedName("pump", locale, "entity")}`
                  : `${flow.insertersPerMachine ?? 0} × ${localizedName(settings.inserterId, locale, "entity")} ${tr(locale, "perMachine")} · Σ ${flow.totalInserters ?? 0}`}
              </span>
            </div>
            {flow.warning ? (
              <p className="mt-2 text-[10px] text-[#e5a12b]">
                {localizedName(flow.id, locale, flow.type)} ·{" "}
                {formatNumber(flow.perMachineMax, locale)}/s &gt; 240/s
              </p>
            ) : null}
          </div>
        ))}
      </div>
      <p className="text-[10px] text-zinc-600">
        {tr(locale, "power")}: {formatPower(result.electricKw, locale)}
      </p>
    </ExpandableSection>
  );
}

function ChainSourceRow({
  node,
  locale,
  onOverride,
}: {
  node: ProductionChainResult["rawSources"][number];
  locale: Locale;
  onOverride: (key: string, patch: Partial<ChainOverride>) => void;
}) {
  const miningModules = (node.modules ?? []).filter(
    (selection): selection is NonNullable<typeof selection> => Boolean(selection),
  );
  const miningModule = miningModules[0];
  const qualityOutputs = (node.outputAmounts ?? []).filter(
    (entry): entry is typeof entry & { quality: QualityId } =>
      Boolean(entry.quality) && entry.amount > 1e-12,
  );
  return (
    <div className="chain-source-row ml-4 flex flex-wrap items-center gap-3 rounded-lg border border-dashed bg-[#101214] p-3">
      <FactorioIcon src={node.icon} alt="" size="md" />
      <div className="min-w-0 flex-1">
        <p className="whitespace-normal break-words text-xs leading-tight">
          {localizedName(node.id, locale, node.type)}
        </p>
        <p className="font-mono text-[9px] text-zinc-600">
          {node.entityId
            ? localizedName(node.entityId, locale, "entity")
            : tr(locale, "rawSource")}{" "}
          · {formatNumber(node.entities, locale)} ·{" "}
          {formatNumber(node.ratePerSecond, locale)}/s
          {node.requiredQuality
            ? ` · ${localizedName(node.requiredQuality, locale, "quality")}`
            : ""}
        </p>
        {node.moduleSlots !== undefined ? (
          <p className="mt-1 flex min-w-0 flex-wrap items-center gap-1.5 text-[10px] text-[#d3b4ff]">
            <FactorioIcon
              src={
                miningModule
                  ? iconFor(moduleItemId(miningModule.family, miningModule.tier))
                  : iconFor(node.entityId ?? "big-mining-drill")
              }
              alt=""
              size="sm"
            />
            <span className="whitespace-normal break-words">
              {miningModule
                ? `${miningModules.length}/${node.moduleSlots} ${tr(locale, "occupiedSlots")} · ${localizedName(
                    moduleItemId(miningModule.family, miningModule.tier),
                    locale,
                    "item",
                  )} · ${localizedName(miningModule.quality, locale, "quality")}`
                : `0/${node.moduleSlots} ${tr(locale, "occupiedSlots")}`}
              {node.qualityChance
                ? ` · ${tr(locale, "miningQualityChance")} ${formatNumber(
                    node.qualityChance * 100,
                    locale,
                    2,
                  )}%`
                : ""}
            </span>
          </p>
        ) : null}
      </div>
      {node.electricKw ? (
        <span className="font-mono text-[10px] text-[#69c5df]">
          {formatPower(node.electricKw, locale)}
        </span>
      ) : null}
      <label className="flex shrink-0 items-center gap-1.5 text-[9px] text-zinc-500">
        <input
          type="checkbox"
          checked={node.includeEnergy}
          onChange={(e) =>
            onOverride(node.key, { includeEnergy: e.target.checked })
          }
        />
        {tr(locale, "energy")}
      </label>
      {qualityOutputs.length > 1 ? (
        <div className="flex w-full flex-wrap gap-1.5 border-t border-white/6 pt-2">
          {qualityOutputs.map((entry) => {
            const quality = QUALITY_BY_ID.get(entry.quality);
            return (
              <span
                key={entry.quality}
                className="rounded-md border bg-black/15 px-2 py-1 font-mono text-[9px]"
                style={{
                  borderColor: `${quality?.color ?? "#888"}55`,
                  color: quality?.color,
                }}
              >
                {localizedName(entry.quality, locale, "quality")} · {formatNumber(entry.amount, locale)}/s
              </span>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}
function ChainRecipeNode({
  node,
  locale,
  overrides,
  master,
  qualityMode,
  onOverride,
}: {
  node: ProductionChainNode;
  locale: Locale;
  overrides: Record<string, ChainOverride>;
  master: ChainMasterSettings;
  qualityMode: boolean;
  onOverride: (key: string, patch: Partial<ChainOverride>) => void;
}) {
  const override = overrides[node.key] ?? {};
  const qualitySafeBeacon =
    qualityMode && (override.beaconMode ?? master.beaconMode) === "quality-safe";
  const routes = node.product.recipeIds
    .map((id) => RECIPE_BY_ID.get(id))
    .filter(Boolean);
  const machines = machinesForRecipe(node.recipe);
  const productOutput = node.result.outputs.find(
    (flow) => flow.id === node.product.id && flow.type === node.product.type,
  );
  const inheritedFamily = master.machineModuleFamilies.find((family) =>
    moduleIsAllowed(
      {
        family,
        tier: master.machineModuleTier,
        quality: master.machineModuleQuality,
      },
      node.machine,
      node.recipe,
    ),
  );
  const selectedMachineModuleTier =
    override.machineModuleTier ?? master.machineModuleTier;
  const selectedBeaconModuleTier =
    override.beaconModuleTier ?? master.beaconModuleTier;
  return (
    <CollapsiblePanel
      className="chain-node collapsible-panel ml-3 rounded-xl border bg-[#121416]"
      data-chain-depth={Math.min(node.depth, 3)}
      defaultOpen={node.depth < 2}
    >
      <summary className="collapsible-summary list-none p-3">
        <div className="summary-leading flex min-w-0 items-center gap-3">
          <FactorioIcon src={node.product.icon} alt="" size="lg" />
          <div className="min-w-0 flex-1">
            <p className="whitespace-normal break-words text-sm font-medium leading-tight">
              {localizedName(node.product.id, locale, node.product.type)}
            </p>
            <p className="font-mono text-[9px] text-zinc-600">
              {formatNumber(node.ratePerSecond, locale)}/s
              {node.requiredQuality
                ? ` · ${localizedName(node.requiredQuality, locale, "quality")}`
                : ""}{" "}
              ·{" "}
              {formatNumber(node.result.machinesToBuild, locale)} ×{" "}
              {localizedName(node.machine.id, locale, "entity")} ·{" "}
              <span className="text-[#69c5df]">{formatPower(node.electricKw, locale)}</span>
            </p>
          </div>
        </div>
        <span className="summary-trailing">
          <label
            className="flex shrink-0 items-center gap-1.5 text-[9px] text-zinc-500"
            onClick={(e) => e.stopPropagation()}
          >
            <input
              type="checkbox"
              checked={node.includeEnergy}
              onChange={(e) =>
                onOverride(node.key, { includeEnergy: e.target.checked })
              }
            />
            {tr(locale, "energy")}
          </label>
          <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-600 transition" />
        </span>
      </summary>
      <div className="chain-node-body border-t p-3">
        <Tabs defaultValue="setup">
          <TabsList className="mb-3 grid h-11 grid-cols-3 border border-[#f7a72d]/25 bg-[#17191b] p-1 shadow-[0_0_16px_rgba(247,167,45,.05)]">
            <TabsTrigger value="setup" className="border border-transparent text-[10px] data-[state=active]:border-[#f7a72d]/35 data-[state=active]:bg-[#f7a72d]/10 data-[state=active]:text-[#f7a72d]">
              {tr(locale, "nodeSetup")}
            </TabsTrigger>
            <TabsTrigger value="modules" className="border border-transparent text-[10px] data-[state=active]:border-[#69c5df]/35 data-[state=active]:bg-[#69c5df]/10 data-[state=active]:text-[#a8e8f7]">
              {tr(locale, "nodeModules")}
            </TabsTrigger>
            <TabsTrigger value="logistics" className="border border-transparent text-[10px] data-[state=active]:border-[#74b768]/35 data-[state=active]:bg-[#74b768]/10 data-[state=active]:text-[#b9e2b3]">
              {tr(locale, "logistics")}
            </TabsTrigger>
          </TabsList>
          <TabsContent value="setup" className="grid gap-2 sm:grid-cols-3">
            <div>
              <FieldLabel>{tr(locale, "recipeRoute")}</FieldLabel>
              <Select
                value={node.recipe.id}
                onValueChange={(v) =>
                  onOverride(node.key, { recipeId: v, machineId: undefined })
                }
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {routes.map(
                    (route) =>
                      route && (
                        <SelectItem key={route.id} value={route.id}>
                          <span className="flex items-center gap-2">
                            <FactorioIcon src={route.icon} alt="" size="sm" />
                            {localizedName(route.id, locale, "recipe")}
                          </span>
                        </SelectItem>
                      ),
                  )}
                </SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "productionMachine")}</FieldLabel>
              <Select
                value={node.machine.id}
                onValueChange={(v) => onOverride(node.key, { machineId: v })}
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {machines.map((machine) => (
                    <SelectItem key={machine.id} value={machine.id}>
                      <span className="flex items-center gap-2">
                        <FactorioIcon src={machine.icon} alt="" size="sm" />
                        {localizedName(machine.id, locale, "entity")}
                      </span>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "machineQuality")}</FieldLabel>
              <QualitySelect
                value={override.machineQuality ?? master.machineQuality}
                onChange={(v) =>
                  onOverride(node.key, { machineQuality: v as QualityId })
                }
                locale={locale}
              />
            </div>
          </TabsContent>
          <TabsContent value="modules" className="grid gap-3 sm:grid-cols-2">
            <div className="rounded-lg border border-white/7 p-3">
              <FieldLabel>{tr(locale, "machineModules")}</FieldLabel>
              <Select
                value={override.machineModuleFamily ?? inheritedFamily ?? "none"}
                onValueChange={(v) =>
                  onOverride(node.key, {
                    machineModuleFamily:
                      v as ChainOverride["machineModuleFamily"],
                  })
                }
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {(
                    [
                      "none",
                      "productivity",
                      "speed",
                      "quality",
                      "efficiency",
                    ] as const
                  ).map((family) => (
                    <SelectItem key={family} value={family}>
                      {family === "none"
                        ? "—"
                        : localizedName(
                            moduleItemId(family, selectedMachineModuleTier),
                            locale,
                            "item",
                          )}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <div className="mt-2 grid grid-cols-2 gap-2">
                <Select
                  value={String(override.machineModuleTier ?? master.machineModuleTier)}
                  onValueChange={(v) =>
                    onOverride(node.key, {
                      machineModuleTier: Number(v) as 1 | 2 | 3,
                    })
                  }
                >
                  <SelectTrigger className={selectClass}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {[1, 2, 3].map((t) => (
                      <SelectItem key={t} value={String(t)}>
                        T{t}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <QualitySelect
                  value={override.machineModuleQuality ?? master.machineModuleQuality}
                  onChange={(v) =>
                    onOverride(node.key, {
                      machineModuleQuality: v as QualityId,
                    })
                  }
                  locale={locale}
                />
              </div>
            </div>
            <div className="rounded-lg border border-white/7 p-3">
              <label className="mb-2 flex items-center gap-2 text-xs">
                <input
                  type="checkbox"
                  checked={override.beaconEnabled ?? master.beaconEnabled}
                  onChange={(e) =>
                    onOverride(node.key, {
                      beaconEnabled: e.target.checked,
                      ...(e.target.checked && qualitySafeBeacon &&
                      (override.beaconCount ?? master.beaconCount) === 0
                        ? { beaconCount: 1 }
                        : {}),
                    })
                  }
                />
                {tr(locale, "beacons")}
              </label>
              {qualityMode ? (
                <div className="mb-3">
                <div className="grid grid-cols-2 rounded-lg border border-white/8 bg-[#17191b] p-1">
                  <button
                    type="button"
                    onClick={() =>
                      onOverride(node.key, {
                        beaconMode: "quality-safe",
                        beaconCount:
                          (override.beaconEnabled ?? master.beaconEnabled)
                            ? 1
                            : Math.min(1, override.beaconCount ?? master.beaconCount),
                      })
                    }
                    className={`rounded px-2 py-2 text-[10px] ${qualitySafeBeacon ? "bg-[#303439] text-[#b987ff]" : "text-zinc-500"}`}
                  >
                    {tr(locale, "qualityBeaconMode")}
                  </button>
                  <button
                    type="button"
                    onClick={() => onOverride(node.key, { beaconMode: "standard" })}
                    className={`rounded px-2 py-2 text-[10px] ${!qualitySafeBeacon ? "bg-[#303439] text-[#f7a72d]" : "text-zinc-500"}`}
                  >
                    {tr(locale, "manualBeaconLayout")}
                  </button>
                </div>
                <p className="mt-2 rounded-md border border-[#b987ff]/18 bg-[#b987ff]/5 px-2 py-1.5 font-mono text-[9px] text-[#d3b4ff]">
                  {(override.beaconEnabled ?? master.beaconEnabled) &&
                  (override.beaconModuleFamily ?? master.beaconModuleFamily) !== "none"
                    ? qualitySafeBeacon
                      ? "1/2"
                      : "2/2"
                    : "0/2"}{" "}
                  {tr(locale, "occupiedSlots")} · {tr(locale, "slotsPerBeacon")}
                </p>
                </div>
              ) : null}
              <div className="grid grid-cols-3 gap-2">
                <BeaconCountSelect
                  value={override.beaconCount ?? master.beaconCount}
                  maximum={qualitySafeBeacon ? 1 : node.machine.maxBeacons}
                  disabled={!(override.beaconEnabled ?? master.beaconEnabled)}
                  onChange={(beaconCount) =>
                    onOverride(node.key, { beaconCount })
                  }
                />
                <Select
                  value={override.beaconModuleFamily ?? master.beaconModuleFamily}
                  disabled={!(override.beaconEnabled ?? master.beaconEnabled)}
                  onValueChange={(v) =>
                    onOverride(node.key, {
                      beaconModuleFamily:
                        v as ChainOverride["beaconModuleFamily"],
                    })
                  }
                >
                  <SelectTrigger className={selectClass}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="speed">
                      <span className="flex items-center gap-2">
                        <FactorioIcon
                          src={iconFor(
                            moduleItemId("speed", selectedBeaconModuleTier),
                          )}
                          alt=""
                          size="sm"
                        />
                        {localizedName(
                          moduleItemId("speed", selectedBeaconModuleTier),
                          locale,
                          "item",
                        )}
                      </span>
                    </SelectItem>
                    <SelectItem value="efficiency">
                      <span className="flex items-center gap-2">
                        <FactorioIcon
                          src={iconFor(
                            moduleItemId(
                              "efficiency",
                              selectedBeaconModuleTier,
                            ),
                          )}
                          alt=""
                          size="sm"
                        />
                        {localizedName(
                          moduleItemId(
                            "efficiency",
                            selectedBeaconModuleTier,
                          ),
                          locale,
                          "item",
                        )}
                      </span>
                    </SelectItem>
                    <SelectItem value="none">—</SelectItem>
                  </SelectContent>
                </Select>
                <QualitySelect
                  value={override.beaconQuality ?? master.beaconQuality}
                  onChange={(v) =>
                    onOverride(node.key, { beaconQuality: v as QualityId })
                  }
                  locale={locale}
                  disabled={!(override.beaconEnabled ?? master.beaconEnabled)}
                />
              </div>
              <div className="mt-2 grid grid-cols-2 gap-2">
                <Select
                  value={String(override.beaconModuleTier ?? master.beaconModuleTier)}
                  disabled={!(override.beaconEnabled ?? master.beaconEnabled)}
                  onValueChange={(v) =>
                    onOverride(node.key, {
                      beaconModuleTier: Number(v) as 1 | 2 | 3,
                    })
                  }
                >
                  <SelectTrigger className={selectClass}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {[1, 2, 3].map((tier) => (
                      <SelectItem key={tier} value={String(tier)}>
                        T{tier}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <QualitySelect
                  value={override.beaconModuleQuality ?? master.beaconModuleQuality}
                  onChange={(v) =>
                    onOverride(node.key, {
                      beaconModuleQuality: v as QualityId,
                    })
                  }
                  locale={locale}
                  disabled={!(override.beaconEnabled ?? master.beaconEnabled)}
                />
              </div>
            </div>
          </TabsContent>
          <TabsContent value="logistics">
            <div className="rounded-xl border border-[#74b768]/20 bg-[#101312] p-3">
              <InserterSettingsFields
                settings={node.logisticsSettings}
                locale={locale}
                onChange={(next) =>
                  onOverride(node.key, {
                    inserterId: next.inserterId,
                    inserterQuality: next.inserterQuality,
                    inserterCapacityBonus: next.capacityBonus,
                    inserterHandoff: next.handoff,
                  })
                }
              />
              <div className="mt-3 flex items-center gap-3 rounded-lg border border-[#f7a72d]/18 bg-[#f7a72d]/6 p-3">
                <FactorioIcon
                  src={iconFor(node.logisticsSettings.inserterId)}
                  alt=""
                  size="md"
                />
                <div>
                  <p className="text-xs font-semibold text-[#f3c675]">
                    {tr(locale, "insertersRequired")}
                  </p>
                  <p className="font-mono text-[11px] text-zinc-300">
                    {formatNumber(
                      node.logistics.flows.reduce(
                        (sum, flow) => sum + (flow.totalInserters ?? 0),
                        0,
                      ),
                      locale,
                      0,
                    )}{" "}
                    × {localizedName(
                      node.logisticsSettings.inserterId,
                      locale,
                      "entity",
                    )}
                  </p>
                </div>
              </div>
            </div>
          </TabsContent>
        </Tabs>
        {qualityMode && productOutput && productOutput.amounts.length > 1 ? (
          <div className="mt-3 rounded-lg border border-[#b987ff]/20 bg-[#b987ff]/5 p-2">
            <p className="mb-2 font-mono text-[9px] uppercase tracking-wider text-[#b987ff]">
              {tr(locale, "expectedOutputs")}
            </p>
            <MaterialRow flow={productOutput} unit="s" locale={locale} />
          </div>
        ) : null}
        <div className="mt-3 space-y-2">
          {node.inputs.map((child, index) =>
            child.kind === "source" ? (
              <ChainSourceRow
                key={`s${index}:${child.id}`}
                node={child}
                locale={locale}
                onOverride={onOverride}
              />
            ) : (
              <ChainRecipeNode
                key={child.key}
                node={child}
                locale={locale}
                overrides={overrides}
                master={master}
                qualityMode={qualityMode}
                onOverride={onOverride}
              />
            ),
          )}
        </div>
      </div>
    </CollapsiblePanel>
  );
}

function chainProcessGroups(chains: ProductionChainResult[]) {
  const groups = new Map<
    string,
    {
      product: ProductionChainNode["product"];
      nodes: ProductionChainNode[];
      options: Array<{
        recipe: ProductionChainNode["recipe"];
        machine: ProductionChainNode["machine"];
      }>;
    }
  >();
  function visit(node: ProductionChainNode) {
    let group = groups.get(node.productKey);
    if (!group) {
      const options = new Map<
        string,
        {
          recipe: ProductionChainNode["recipe"];
          machine: ProductionChainNode["machine"];
        }
      >();
      for (const recipeId of node.product.recipeIds) {
        const recipe = RECIPE_BY_ID.get(recipeId);
        if (!recipe) continue;
        for (const machine of machinesForRecipe(recipe))
          options.set(`${recipe.id}:${machine.id}`, { recipe, machine });
      }
      group = {
        product: node.product,
        nodes: [],
        options: [...options.values()],
      };
      groups.set(node.productKey, group);
    }
    group.nodes.push(node);
    for (const child of node.inputs)
      if (child.kind === "recipe") visit(child);
  }
  for (const chain of chains)
    for (const child of chain.root.inputs)
      if (child.kind === "recipe") visit(child);
  return [...groups.values()]
    .filter((group) => group.options.length > 1)
    .sort((a, b) => a.product.name.localeCompare(b.product.name));
}

export function ChainMasterPanel({
  master,
  locale,
  qualityMode,
  chains = [],
  global = false,
  onChange,
}: {
  master: ChainMasterSettings;
  locale: Locale;
  qualityMode: boolean;
  chains?: ProductionChainResult[];
  global?: boolean;
  onChange: (patch: Partial<ChainMasterSettings>) => void;
}) {
  const families: ModuleFamily[] = [
    "productivity",
    "speed",
    "quality",
    "efficiency",
  ];
  const processGroups = useMemo(() => chainProcessGroups(chains), [chains]);
  const miningModuleFamily =
    master.miningModuleFamily ?? (qualityMode ? "quality" : "none");
  const miningModuleTier = master.miningModuleTier ?? 3;
  const miningModuleQuality = master.miningModuleQuality ?? "normal";
  const miningSetup = miningSourceForBaseline(
    "item:iron-ore",
    2.5,
    master.miningDrillId ?? DEFAULT_MINING_DRILL_ID,
    {
      family: miningModuleFamily,
      tier: miningModuleTier,
      quality: miningModuleQuality,
    },
  );
  const unlockedIds = master.unlockedMachineIds ?? DEFAULT_UNLOCKED_MACHINE_IDS;
  const unlocked = new Set(unlockedIds);
  const priorities = master.machinePriorities ?? DEFAULT_MACHINE_PRIORITIES;
  const groupLabelKey: Record<MachinePreferenceGroup, Parameters<typeof tr>[1]> = {
    crafting: "machineGroupCrafting",
    smelting: "machineGroupSmelting",
    fluids: "machineGroupFluids",
    biology: "machineGroupBiology",
    processing: "machineGroupProcessing",
  };
  const movePriority = (
    groupId: MachinePreferenceGroup,
    machineId: string,
    direction: -1 | 1,
  ) => {
    const current = [...(priorities[groupId] ?? [])];
    const index = current.indexOf(machineId);
    const target = index + direction;
    if (index < 0 || target < 0 || target >= current.length) return;
    [current[index], current[target]] = [current[target], current[index]];
    onChange({
      machinePriorities: { ...priorities, [groupId]: current },
      preferredMachineId: "auto",
    });
  };
  return (
    <CollapsiblePanel
      className="hierarchy-panel collapsible-panel chain-master-panel rounded-xl border-2 border-[#f7a72d]/30 bg-[#161719] shadow-[0_0_20px_rgba(247,167,45,.06)]"
      defaultOpen={global}
    >
      <summary className="collapsible-summary dashboard-summary list-none p-4">
        <div className="summary-leading flex min-w-0 items-center gap-3">
          <FactorioIcon src={iconFor("solar-system-edge")} alt="" size="lg" />
          <div className="min-w-0 flex-1">
            <p className="text-sm font-semibold text-[#f7c16f]">
              {tr(locale, global ? "globalChainMaster" : "chainMaster")}
            </p>
            <p className="text-[10px] text-zinc-500">
              {tr(
                locale,
                global ? "applyAllActiveChains" : "applyEntireChain",
              )}
            </p>
          </div>
        </div>
        <span className="summary-trailing">
          <SummaryKpi
            label={tr(locale, "modulePriority")}
            value="PROD › SPEED › QUALITY › EFFICIENCY"
            tone="orange"
            className="priority-kpi"
          />
          <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
        </span>
      </summary>
      <div className="grid gap-4 border-t border-white/8 p-4 xl:grid-cols-3">
        <div className="space-y-3 rounded-xl border border-white/9 bg-[#111315] p-3">
          <div className="grid gap-2 sm:grid-cols-2">
            <div className="sm:col-span-2">
              <FieldLabel>{tr(locale, "machinePriority")}</FieldLabel>
              <Select
                value={master.preferredMachineId}
                onValueChange={(preferredMachineId) =>
                  onChange({ preferredMachineId })
                }
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="auto">{tr(locale, "automatic")}</SelectItem>
                  {MACHINES.filter(
                    (machine) =>
                      machine.energyKind !== "passive" && unlocked.has(machine.id),
                  )
                    .map((machine) => (
                      <SelectItem key={machine.id} value={machine.id}>
                        <span className="flex items-center gap-2">
                          <FactorioIcon src={machine.icon} alt="" size="sm" />
                          {localizedName(machine.id, locale, "entity")}
                        </span>
                      </SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "machineQuality")}</FieldLabel>
              <QualitySelect
                value={master.machineQuality}
                onChange={(value) =>
                  onChange({ machineQuality: value as QualityId })
                }
                locale={locale}
              />
            </div>
          </div>
          <div className="space-y-3 rounded-xl border border-[#b987ff]/28 bg-[#15121a] p-3">
            <div className="flex items-start gap-2">
              <Pickaxe className="mt-0.5 size-4 shrink-0 text-[#b987ff]" />
              <div>
                <p className="text-xs font-semibold text-[#d3b4ff]">
                  {tr(locale, "miningAndRawQuality")}
                </p>
                <p className="mt-0.5 text-[9px] leading-relaxed text-zinc-500">
                  {tr(locale, qualityMode ? "qualityMiningHint" : "miningDrillHint")}
                </p>
              </div>
            </div>
            <div className="grid gap-2 sm:grid-cols-2">
              <div className="sm:col-span-2">
                <FieldLabel>{tr(locale, "miningDrill")}</FieldLabel>
                <Select
                  value={master.miningDrillId ?? DEFAULT_MINING_DRILL_ID}
                  onValueChange={(miningDrillId) =>
                    onChange({ miningDrillId: miningDrillId as MiningDrillId })
                  }
                >
                  <SelectTrigger className={selectClass}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {MINING_DRILLS.map((drill) => (
                      <SelectItem key={drill.id} value={drill.id}>
                        <span className="flex items-center gap-2">
                          <FactorioIcon src={iconFor(drill.id)} alt="" size="sm" />
                          {localizedName(drill.id, locale, "entity")} · {drill.moduleSlots} {tr(locale, "slots")}
                        </span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="sm:col-span-2">
                <FieldLabel>{tr(locale, "miningModules")}</FieldLabel>
                <Select
                  value={miningModuleFamily}
                  disabled={!miningSetup.drill.moduleSlots}
                  onValueChange={(miningModuleFamily) =>
                    onChange({
                      miningModuleFamily:
                        miningModuleFamily as ChainMasterSettings["miningModuleFamily"],
                    })
                  }
                >
                  <SelectTrigger className={selectClass}>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">—</SelectItem>
                    {families.map((family) => (
                      <SelectItem key={family} value={family}>
                        <span className="flex items-center gap-2">
                          <FactorioIcon
                            src={iconFor(moduleItemId(family, miningModuleTier))}
                            alt=""
                            size="sm"
                          />
                          {localizedName(
                            moduleItemId(family, miningModuleTier),
                            locale,
                            "item",
                          )}
                        </span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div>
                <FieldLabel>{tr(locale, "tier")}</FieldLabel>
                <Select
                  value={String(miningModuleTier)}
                  disabled={!miningSetup.drill.moduleSlots || miningModuleFamily === "none"}
                  onValueChange={(value) =>
                    onChange({ miningModuleTier: Number(value) as 1 | 2 | 3 })
                  }
                >
                  <SelectTrigger className={selectClass}><SelectValue /></SelectTrigger>
                  <SelectContent>{[1, 2, 3].map((tier) => <SelectItem key={tier} value={String(tier)}>T{tier}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div>
                <FieldLabel>{tr(locale, "moduleQuality")}</FieldLabel>
                <QualitySelect
                  value={miningModuleQuality}
                  onChange={(value) =>
                    onChange({ miningModuleQuality: value as QualityId })
                  }
                  locale={locale}
                  disabled={!miningSetup.drill.moduleSlots || miningModuleFamily === "none"}
                />
              </div>
            </div>
            <div className="flex min-w-0 flex-wrap items-center gap-2 rounded-lg border border-[#b987ff]/18 bg-[#0f1012] p-2 text-[10px] text-zinc-400">
              <FactorioIcon src={iconFor(miningSetup.drill.id)} alt="" size="sm" />
              <span className="whitespace-normal break-words">
                {localizedName(miningSetup.drill.id, locale, "entity")}
                {miningModuleFamily === "none" || !miningSetup.drill.moduleSlots
                  ? ` · 0 ${tr(locale, "miningModules")}`
                  : ` · ${miningSetup.drill.moduleSlots} × ${localizedName(
                      moduleItemId(miningModuleFamily, miningModuleTier),
                      locale,
                      "item",
                    )} · ${localizedName(miningModuleQuality, locale, "quality")}`}
                {miningSetup.qualityChance > 0
                  ? ` · ${tr(locale, "miningQualityChance")} ${formatNumber(
                      miningSetup.qualityChance * 100,
                      locale,
                      2,
                    )}%`
                  : ""}
              </span>
            </div>
          </div>
          <FieldLabel>{tr(locale, "modulePriority")}</FieldLabel>
          <div className="grid grid-cols-2 gap-2">
            {families.map((family) => {
              const active = master.machineModuleFamilies.includes(family);
              return (
                <button
                  type="button"
                  key={family}
                  onClick={() =>
                    onChange({
                      machineModuleFamilies: active
                        ? master.machineModuleFamilies.filter(
                            (candidate) => candidate !== family,
                          )
                        : [...master.machineModuleFamilies, family],
                    })
                  }
                  className={`flex items-center gap-2 rounded-lg border p-2 text-left text-xs ${active ? "border-[#f7a72d]/50 bg-[#f7a72d]/10" : "border-white/8 bg-[#17191b]"}`}
                >
                  <FactorioIcon
                    src={iconFor(moduleItemId(family, master.machineModuleTier))}
                    alt=""
                    size="md"
                  />
                  <span className="whitespace-normal break-words leading-tight">
                    {localizedName(
                      moduleItemId(family, master.machineModuleTier),
                      locale,
                      "item",
                    )}
                  </span>
                </button>
              );
            })}
          </div>
          <div className="grid grid-cols-2 gap-2">
            <div>
              <FieldLabel>{tr(locale, "tier")}</FieldLabel>
              <Select
                value={String(master.machineModuleTier)}
                onValueChange={(value) =>
                  onChange({ machineModuleTier: Number(value) as 1 | 2 | 3 })
                }
              >
                <SelectTrigger className={selectClass}><SelectValue /></SelectTrigger>
                <SelectContent>{[1, 2, 3].map((tier) => <SelectItem key={tier} value={String(tier)}>T{tier}</SelectItem>)}</SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "moduleQuality")}</FieldLabel>
              <QualitySelect value={master.machineModuleQuality} onChange={(value) => onChange({ machineModuleQuality: value as QualityId })} locale={locale} />
            </div>
          </div>
        </div>
        <div className="space-y-3 rounded-xl border border-white/9 bg-[#111315] p-3">
          <label className="flex items-center gap-2 text-xs font-medium">
            <input type="checkbox" checked={master.beaconEnabled} onChange={(event) => onChange({ beaconEnabled: event.target.checked, ...(event.target.checked && qualityMode && master.beaconMode === "quality-safe" && master.beaconCount === 0 ? { beaconCount: 1 } : {}) })} />
            <FactorioIcon src={iconFor("beacon")} alt="" size="sm" />
            {tr(locale, "beacons")}
          </label>
          {qualityMode ? (
            <div>
            <div className="grid grid-cols-2 rounded-lg border border-white/8 bg-[#17191b] p-1">
              <button
                type="button"
                onClick={() =>
                  onChange({
                    beaconMode: "quality-safe",
                    beaconCount: master.beaconEnabled
                      ? 1
                      : Math.min(1, master.beaconCount),
                  })
                }
                className={`rounded px-2 py-2 text-[10px] ${master.beaconMode === "quality-safe" ? "bg-[#303439] text-[#b987ff]" : "text-zinc-500"}`}
              >
                {tr(locale, "qualityBeaconMode")}
              </button>
              <button
                type="button"
                onClick={() => onChange({ beaconMode: "standard" })}
                className={`rounded px-2 py-2 text-[10px] ${master.beaconMode === "standard" ? "bg-[#303439] text-[#f7a72d]" : "text-zinc-500"}`}
              >
                {tr(locale, "manualBeaconLayout")}
              </button>
            </div>
            {master.beaconMode === "quality-safe" ? (
              <p className="mt-2 text-[9px] leading-relaxed text-zinc-500">
                {tr(locale, "qualitySafeBeacon")}
              </p>
            ) : null}
            <p className="mt-2 rounded-md border border-[#b987ff]/18 bg-[#b987ff]/5 px-2 py-1.5 font-mono text-[9px] text-[#d3b4ff]">
              {master.beaconEnabled && master.beaconModuleFamily !== "none"
                ? master.beaconMode === "quality-safe"
                  ? "1/2"
                  : "2/2"
                : "0/2"}{" "}
              {tr(locale, "occupiedSlots")} · {tr(locale, "slotsPerBeacon")}
            </p>
            </div>
          ) : null}
          <div className="grid grid-cols-2 gap-2">
            <div>
              <FieldLabel detail={`max ${qualityMode && master.beaconMode === "quality-safe" ? 1 : 16}`}>{tr(locale, "activePerMachine")}</FieldLabel>
              <BeaconCountSelect value={master.beaconCount} maximum={qualityMode && master.beaconMode === "quality-safe" ? 1 : 16} disabled={!master.beaconEnabled} onChange={(beaconCount) => onChange({ beaconCount })} />
            </div>
            <div>
              <FieldLabel>{tr(locale, "beaconQuality")}</FieldLabel>
              <QualitySelect value={master.beaconQuality} onChange={(value) => onChange({ beaconQuality: value as QualityId })} locale={locale} disabled={!master.beaconEnabled} />
            </div>
          </div>
          <div className="grid grid-cols-3 gap-2">
            <div>
              <FieldLabel>{tr(locale, "beaconModules")}</FieldLabel>
              <Select value={master.beaconModuleFamily} disabled={!master.beaconEnabled} onValueChange={(value) => onChange({ beaconModuleFamily: value as ChainMasterSettings["beaconModuleFamily"] })}>
                <SelectTrigger className={selectClass}><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="speed"><span className="flex items-center gap-2"><FactorioIcon src={iconFor(moduleItemId("speed", master.beaconModuleTier))} alt="" size="sm" />{localizedName(moduleItemId("speed", master.beaconModuleTier), locale, "item")}</span></SelectItem>
                  <SelectItem value="efficiency"><span className="flex items-center gap-2"><FactorioIcon src={iconFor(moduleItemId("efficiency", master.beaconModuleTier))} alt="" size="sm" />{localizedName(moduleItemId("efficiency", master.beaconModuleTier), locale, "item")}</span></SelectItem>
                  <SelectItem value="none">—</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "tier")}</FieldLabel>
              <Select value={String(master.beaconModuleTier)} disabled={!master.beaconEnabled} onValueChange={(value) => onChange({ beaconModuleTier: Number(value) as 1 | 2 | 3 })}>
                <SelectTrigger className={selectClass}><SelectValue /></SelectTrigger>
                <SelectContent>{[1, 2, 3].map((tier) => <SelectItem key={tier} value={String(tier)}>T{tier}</SelectItem>)}</SelectContent>
              </Select>
            </div>
            <div>
              <FieldLabel>{tr(locale, "moduleQuality")}</FieldLabel>
              <QualitySelect value={master.beaconModuleQuality} onChange={(value) => onChange({ beaconModuleQuality: value as QualityId })} locale={locale} disabled={!master.beaconEnabled} />
            </div>
          </div>
        </div>
        <div className="space-y-3 rounded-xl border border-[#74b768]/18 bg-[#101312] p-3">
          <div className="flex items-center gap-2">
            <FactorioIcon src={iconFor(master.inserterId)} alt="" size="md" />
            <div>
              <p className="text-xs font-semibold text-[#b9e2b3]">
                {tr(locale, "logistics")}
              </p>
              <p className="text-[10px] leading-snug text-zinc-500">
                {tr(locale, "chainInserterHint")}
              </p>
            </div>
          </div>
          <InserterSettingsFields
            settings={{
              inserterId: master.inserterId,
              inserterQuality: master.inserterQuality,
              capacityBonus: master.inserterCapacityBonus,
              handoff: master.inserterHandoff,
            }}
            locale={locale}
            onChange={(next) =>
              onChange({
                inserterId: next.inserterId,
                inserterQuality: next.inserterQuality,
                inserterCapacityBonus: next.capacityBonus,
                inserterHandoff: next.handoff,
              })
            }
          />
        </div>
      </div>
      <CollapsiblePanel
        className="collapsible-panel mx-4 mb-4 rounded-xl border-2 border-[#69c5df]/22 bg-[#101416]"
        defaultOpen={global}
      >
        <summary className="collapsible-summary list-none p-3.5">
          <span className="summary-leading">
            <strong className="block text-sm text-[#a8e8f7]">
              {tr(locale, "machineResearchAndPriority")}
            </strong>
            <span className="mt-0.5 block text-[10px] leading-relaxed text-zinc-500">
              {tr(locale, "machineResearchAndPriorityHint")}
            </span>
          </span>
          <span className="summary-trailing">
            <span className="badge-muted">
              {unlockedIds.length}/{DEFAULT_UNLOCKED_MACHINE_IDS.length}
            </span>
            <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
          </span>
        </summary>
        <div className="space-y-4 border-t border-white/8 p-3.5">
          <div>
            <FieldLabel>{tr(locale, "unlockedMachines")}</FieldLabel>
            <div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-4">
              {MACHINES.filter(
                (machine) => machine.energyKind !== "passive",
              ).map((machine) => {
                const enabled = unlocked.has(machine.id);
                return (
                  <button
                    type="button"
                    key={machine.id}
                    onClick={() => {
                      const nextIds = enabled
                        ? unlockedIds.filter((id) => id !== machine.id)
                        : [...unlockedIds, machine.id];
                      const processMachineChoices = Object.fromEntries(
                        Object.entries(master.processMachineChoices ?? {}).filter(
                          ([, choice]) => nextIds.includes(choice.machineId),
                        ),
                      );
                      onChange({
                        unlockedMachineIds: nextIds,
                        processMachineChoices,
                        preferredMachineId:
                          master.preferredMachineId === machine.id
                            ? "auto"
                            : master.preferredMachineId,
                      });
                    }}
                    className={`flex min-w-0 items-center gap-2 rounded-lg border px-2.5 py-2 text-left text-xs transition ${
                      enabled
                        ? "border-[#74b768]/38 bg-[#74b768]/9 text-zinc-200"
                        : "border-white/7 bg-[#111315] text-zinc-600 opacity-70"
                    }`}
                  >
                    <FactorioIcon src={machine.icon} alt="" size="sm" />
                    <span className="min-w-0 flex-1 whitespace-normal break-words leading-tight">
                      {localizedName(machine.id, locale, "entity")}
                    </span>
                    <span className="font-mono text-[9px]">
                      {enabled ? tr(locale, "enabled") : tr(locale, "disabled")}
                    </span>
                  </button>
                );
              })}
            </div>
          </div>
          <div>
            <FieldLabel>{tr(locale, "machineHierarchy")}</FieldLabel>
            <div className="grid gap-2 lg:grid-cols-2 2xl:grid-cols-3">
              {CHAIN_MACHINE_GROUPS.map((group) => {
                const ordered = priorities[group.id] ?? group.machineIds;
                return (
                  <div
                    key={group.id}
                    className="rounded-xl border border-[#c17bd5]/18 bg-[#111315] p-3"
                  >
                    <p className="mb-2 text-xs font-semibold text-[#d4a9df]">
                      {tr(locale, groupLabelKey[group.id])}
                    </p>
                    <div className="space-y-1.5">
                      {ordered.map((machineId, index) => {
                        const machine = MACHINES.find(
                          (candidate) => candidate.id === machineId,
                        );
                        if (!machine) return null;
                        const enabled = unlocked.has(machine.id);
                        return (
                          <div
                            key={machine.id}
                            className={`flex items-center gap-2 rounded-lg border px-2 py-1.5 ${
                              enabled
                                ? "border-white/9 bg-[#17191b]"
                                : "border-white/5 bg-[#0d0f10] opacity-45"
                            }`}
                          >
                            <span className="w-4 font-mono text-[9px] text-zinc-600">
                              {index + 1}
                            </span>
                            <FactorioIcon src={machine.icon} alt="" size="sm" />
                            <span className="min-w-0 flex-1 whitespace-normal break-words text-[11px]">
                              {localizedName(machine.id, locale, "entity")}
                            </span>
                            <button
                              type="button"
                              disabled={index === 0}
                              onClick={() => movePriority(group.id, machine.id, -1)}
                              className="rounded p-1 text-zinc-500 hover:bg-white/5 hover:text-[#a8e8f7] disabled:opacity-20"
                              aria-label={tr(locale, "movePriorityUp")}
                            >
                              <ArrowUp className="size-3" />
                            </button>
                            <button
                              type="button"
                              disabled={index === ordered.length - 1}
                              onClick={() => movePriority(group.id, machine.id, 1)}
                              className="rounded p-1 text-zinc-500 hover:bg-white/5 hover:text-[#a8e8f7] disabled:opacity-20"
                              aria-label={tr(locale, "movePriorityDown")}
                            >
                              <ArrowDown className="size-3" />
                            </button>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </CollapsiblePanel>
      {processGroups.length ? (
        <CollapsiblePanel className="collapsible-panel border-t border-white/8 p-4">
          <summary className="collapsible-summary mb-3 list-none rounded-xl border border-[#69c5df]/16 bg-[#101416] p-3">
            <div className="summary-leading">
              <p className="text-sm font-semibold text-[#a8e8f7]">
                {tr(locale, "subprocessMachines")}
              </p>
              <p className="text-[10px] text-zinc-500">
                {tr(locale, "subprocessMachineHint")}
              </p>
            </div>
            <span className="summary-trailing">
              <span className="badge-muted">{processGroups.length}</span>
              <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
            </span>
          </summary>
          <div className="grid gap-2 xl:grid-cols-2">
            {processGroups.map((group) => {
              const availableOptions = group.options.filter(({ machine }) =>
                unlocked.has(machine.id),
              );
              const configuredChoice =
                master.processMachineChoices?.[group.product.key];
              const choice = availableOptions.some(
                ({ recipe, machine }) =>
                  configuredChoice?.recipeId === recipe.id &&
                  configuredChoice.machineId === machine.id,
              )
                ? configuredChoice
                : undefined;
              const value = choice
                ? `${choice.recipeId}:${choice.machineId}`
                : "auto";
              return (
                <div
                  key={group.product.key}
                  className="rounded-xl border border-[#69c5df]/18 bg-[#111315] p-3"
                >
                  <div className="mb-2 flex items-center gap-2">
                    <FactorioIcon src={group.product.icon} alt="" size="md" />
                    <span className="whitespace-normal break-words text-xs font-medium">
                      {localizedName(
                        group.product.id,
                        locale,
                        group.product.type,
                      )}
                    </span>
                  </div>
                  <Select
                    value={value}
                    onValueChange={(next) => {
                      const processMachineChoices = {
                        ...(master.processMachineChoices ?? {}),
                      };
                      if (next === "auto")
                        delete processMachineChoices[group.product.key];
                      else {
                        const option = group.options.find(
                          ({ recipe, machine }) =>
                            `${recipe.id}:${machine.id}` === next,
                        );
                        if (option)
                          processMachineChoices[group.product.key] = {
                            recipeId: option.recipe.id,
                            machineId: option.machine.id,
                          };
                      }
                      onChange({ processMachineChoices });
                    }}
                  >
                    <SelectTrigger className={selectClass}>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="auto">
                        {tr(locale, "automatic")}
                      </SelectItem>
                      {availableOptions.map(({ recipe, machine }) => (
                        <SelectItem
                          key={`${recipe.id}:${machine.id}`}
                          value={`${recipe.id}:${machine.id}`}
                        >
                          <span className="flex items-center gap-2">
                            <FactorioIcon src={machine.icon} alt="" size="sm" />
                            <span className="whitespace-normal">
                              {localizedName(machine.id, locale, "entity")} ·{" "}
                              {localizedName(recipe.id, locale, "recipe")}
                            </span>
                          </span>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              );
            })}
          </div>
        </CollapsiblePanel>
      ) : null}
    </CollapsiblePanel>
  );
}

export function ProductionChainPanel({
  chain,
  locale,
  overrides,
  master,
  qualityMode,
  onMaster,
  onOverride,
}: {
  chain: ProductionChainResult;
  locale: Locale;
  overrides: Record<string, ChainOverride>;
  master: ChainMasterSettings;
  qualityMode: boolean;
  onMaster: (patch: Partial<ChainMasterSettings>) => void;
  onOverride: (key: string, patch: Partial<ChainOverride>) => void;
}) {
  return (
    <ExpandableSection
      title={tr(locale, "productionChain")}
      icons={[chain.root.product.icon]}
      open
    >
      <div className="grid gap-2 sm:grid-cols-3">
        <MetricCard
          icon={<Network className="size-4" />}
          label={tr(locale, "chainPower")}
          value={formatPower(Math.max(0, chain.includedElectricKw - chain.root.electricKw), locale)}
          detail={`Σ ${formatPower(Math.max(0, chain.totalElectricKw - chain.root.electricKw), locale)}`}
        />
        <MetricCard
          icon={<Pickaxe className="size-4" />}
          label={tr(locale, "rawSource")}
          value={String(chain.rawSources.length)}
        />
        <MetricCard
          icon={<Boxes className="size-4" />}
          label={tr(locale, "fullChain")}
          value={localizedName(
            chain.root.product.id,
            locale,
            chain.root.product.type,
          )}
        />
      </div>
      <ChainMasterPanel
        master={master}
        locale={locale}
        qualityMode={qualityMode}
        chains={[chain]}
        onChange={onMaster}
      />
      <div className="space-y-2">
        {chain.root.inputs.map((node, index) =>
          node.kind === "source" ? (
            <ChainSourceRow key={`root-source:${node.key}:${index}`} node={node} locale={locale} onOverride={onOverride} />
          ) : (
            <ChainRecipeNode key={node.key} node={node} locale={locale} overrides={overrides} master={master} qualityMode={qualityMode} onOverride={onOverride} />
          ),
        )}
      </div>
    </ExpandableSection>
  );
}

function BeltThroughputPanel({
  materials,
  snapshots,
  unit,
  locale,
}: {
  materials: FactoryResourceTotal[];
  snapshots: FactoryTotalsSnapshot[];
  unit: RateUnit;
  locale: Locale;
}) {
  const [beltId, setBeltId] = useState<BeltId>("transport-belt");
  const [stackSize, setStackSize] = useState<BeltStackSize>(1);
  const [splitSharedStreams, setSplitSharedStreams] = useState(true);
  const itemMaterials = materials.filter(
    (material) => material.type === "item" && material.total > 1e-12,
  );
  const capacity = beltCapacityPerSecond(beltId, stackSize);
  const beltSettingsByTarget = new Map(
    snapshots.flatMap((snapshot) =>
      snapshot.beltSettings
        ? [[snapshot.id, snapshot.beltSettings] as const]
        : [],
    ),
  );

  return (
    <CollapsiblePanel data-totals-section="belts" className="collapsible-panel rounded-xl border-2 border-[#f7a72d]/30 bg-[#14120f]" defaultOpen>
      <summary className="collapsible-summary factory-totals-section-summary list-none p-4">
        <div className="summary-leading flex min-w-0 items-center gap-2.5">
          <span
            className="flex size-10 shrink-0 items-center justify-center rounded-lg border border-[#f7a72d]/40 bg-[#0d0f10]"
          >
            <FactorioIcon src={iconFor(beltId)} alt="" size="md" />
          </span>
          <div>
            <h3 className="text-base font-semibold text-[#f3c675]">
              {tr(locale, "beltThroughput")}
            </h3>
            <p className="max-w-2xl text-xs leading-relaxed text-zinc-500">
              {tr(locale, "beltThroughputHint")}
            </p>
          </div>
        </div>
        <span className="summary-trailing">
          <SummaryKpi
            label={tr(locale, "beltCapacity")}
            value={`${formatNumber(toDisplayRate(capacity, unit), locale)}${unitLabel(unit)}`}
            tone="orange"
          />
          <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
        </span>
      </summary>
      <div className="border-t border-white/7 p-4">

      <div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
        <div>
          <FieldLabel>{tr(locale, "beltType")}</FieldLabel>
          <Select value={beltId} onValueChange={(value) => setBeltId(value as BeltId)}>
            <SelectTrigger className={selectClass}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {BELT_TYPES.map((belt) => (
                <SelectItem key={belt.id} value={belt.id}>
                  <span className="flex items-center gap-2">
                    <FactorioIcon src={iconFor(belt.id)} alt="" size="sm" />
                    {localizedName(belt.id, locale, "entity")}
                  </span>
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div>
          <FieldLabel>{tr(locale, "beltStacking")}</FieldLabel>
          <Select
            value={String(stackSize)}
            onValueChange={(value) =>
              setStackSize(Number(value) as BeltStackSize)
            }
          >
            <SelectTrigger className={selectClass}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="1">1× · {tr(locale, "unstacked")}</SelectItem>
              <SelectItem value="2">2× · {tr(locale, "stackInserterLevel")}</SelectItem>
              <SelectItem value="3">3× · {tr(locale, "beltCapacityOne")}</SelectItem>
              <SelectItem value="4">4× · {tr(locale, "beltCapacityTwo")}</SelectItem>
            </SelectContent>
          </Select>
        </div>
        <label className="stream-split-control flex min-h-16 cursor-pointer items-center justify-between gap-3 rounded-lg border-2 border-[#69c5df]/42 bg-[#101416] px-3 py-2.5">
          <span className="flex min-w-0 items-start gap-2.5">
            <span className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg border border-[#69c5df]/35 bg-[#69c5df]/10 text-[#a8e8f7]">
              <Network className="size-4" />
            </span>
            <span className="min-w-0">
            <strong className="block text-xs font-medium text-[#a8e8f7]">
              {tr(locale, "splitSharedStreams")}
            </strong>
            <span className="mt-1 block text-[9px] leading-relaxed text-zinc-600">
              {tr(locale, "splitSharedStreamsHint")}
            </span>
            </span>
          </span>
          <input
            type="checkbox"
            checked={splitSharedStreams}
            onChange={(event) => setSplitSharedStreams(event.target.checked)}
          />
        </label>
      </div>

      <div className="mt-3 grid gap-2 2xl:grid-cols-2">
        {itemMaterials.map((material, materialIndex) => {
          const streams = splitSharedStreams
            ? material.contributions.map((contribution) => ({
                key: contribution.targetId,
                rate: contribution.amountPerSecond,
                product: contribution.product,
              }))
            : [{ key: "combined", rate: material.total, product: undefined }];
          return (
            <CollapsiblePanel
              data-totals-entry="belt-material"
              key={`${material.type}:${material.id}`}
              className="rounded-xl border-2 bg-[#101112]"
              style={{
                borderColor: [
                  "rgba(247,167,45,.24)",
                  "rgba(105,197,223,.24)",
                  "rgba(116,183,104,.24)",
                  "rgba(193,123,213,.24)",
                ][materialIndex % 4],
              }}
              defaultOpen
            >
              <summary className="collapsible-summary list-none p-3">
                <div className="summary-leading min-w-0">
                  <MaterialRow flow={material} unit={unit} locale={locale} />
                </div>
                <span className="summary-trailing">
                  <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-600 transition" />
                </span>
              </summary>
              <div className="space-y-1.5 px-3 pb-3">
                {streams.map((stream) => {
                  const targetBelt = beltSettingsByTarget.get(stream.key);
                  const selectedBeltId = targetBelt?.beltId ?? beltId;
                  const selectedStackSize = targetBelt?.beltStackSize ?? stackSize;
                  const load = targetBelt
                    ? resolveBeltLoad(
                        stream.rate,
                        selectedBeltId,
                        selectedStackSize,
                        targetBelt.autoUpgradeBelt,
                      )
                    : {
                        ...calculateBeltLoad(
                          stream.rate,
                          selectedBeltId,
                          selectedStackSize,
                        ),
                        requestedBeltId: selectedBeltId,
                        effectiveBeltId: selectedBeltId,
                        overloaded: false,
                        automaticallyUpgraded: false,
                      };
                  const totalUtilization = load.beltsRequired
                    ? (load.exactBelts / load.beltsRequired) * 100
                    : 0;
                  return (
                    <div
                      key={stream.key}
                      className="grid gap-2 rounded-lg border border-[#69c5df]/13 bg-[#17191b] px-3 py-2.5 sm:grid-cols-[minmax(0,1fr)_auto_minmax(150px,auto)_minmax(170px,auto)] sm:items-center"
                    >
                      <span className="flex min-w-0 items-center gap-2 text-xs text-zinc-300">
                        {stream.product ? (
                          <FactorioIcon src={stream.product.icon} alt="" size="sm" />
                        ) : (
                          <Boxes className="size-4 shrink-0 text-zinc-600" />
                        )}
                        <span className="whitespace-normal break-words">
                          {stream.product
                            ? localizedName(
                                stream.product.id,
                                locale,
                                stream.product.type,
                              )
                            : tr(locale, "combinedStream")}
                        </span>
                      </span>
                      <span className="font-mono text-xs text-zinc-500">
                        {formatNumber(toDisplayRate(stream.rate, unit), locale)}
                        {unitLabel(unit)}
                      </span>
                      <span className={`flex items-center gap-2 rounded-md border bg-[#f7a72d]/7 px-2.5 py-1.5 ${load.overloaded ? "border-[#e65d4f] shadow-[0_0_0_1px_rgba(230,93,79,.28)]" : "border-[#f7a72d]/22"}`}>
                        <FactorioIcon src={iconFor(load.effectiveBeltId)} alt="" size="md" />
                        <span>
                          <strong className="block font-mono text-sm text-[#f3c675]">
                            {load.beltsRequired} ×
                          </strong>
                          <small className="block text-[9px] text-zinc-600">
                            {load.automaticallyUpgraded
                              ? `${localizedName(selectedBeltId, locale, "entity")} → ${localizedName(load.effectiveBeltId, locale, "entity")}`
                              : tr(locale, "beltsRequired")}
                          </small>
                        </span>
                      </span>
                      <span className="rounded-md border border-[#69c5df]/18 bg-[#69c5df]/7 px-2.5 py-1.5 text-[11px] text-zinc-500">
                        <strong className="font-mono text-[#a8e8f7]">
                          {formatNumber(totalUtilization, locale, 1)}%
                        </strong>{" "}
                        {tr(locale, "totalBeltLoad")}
                        <span className="mt-0.5 block text-[9px] text-zinc-600">
                          {formatNumber(load.exactBelts, locale)} {tr(locale, "beltEquivalents")} · {formatNumber(load.lastBeltUtilization * 100, locale, 1)}% {tr(locale, "lastBeltLoad")}
                        </span>
                      </span>
                    </div>
                  );
                })}
              </div>
            </CollapsiblePanel>
          );
        })}
      </div>
      </div>
    </CollapsiblePanel>
  );
}

export function FactoryTotalsPanel({
  snapshots,
  locale,
}: {
  snapshots: FactoryTotalsSnapshot[];
  locale: Locale;
}) {
  const [unitOverride, setUnitOverride] = useState<{
    signature: string;
    unit: RateUnit;
  } | null>(null);
  const totals = useMemo(() => buildFactoryTotals(snapshots), [snapshots]);
  const targetUnits = snapshots.map((snapshot) => snapshot.input.unit);
  const dominantUnit = mostUsedRateUnit(targetUnits);
  const unitPreference = (["s", "min", "h"] as const)
    .map(
      (candidate) =>
        `${candidate}:${targetUnits.filter((unit) => unit === candidate).length}`,
    )
    .concat(dominantUnit)
    .join("|");
  const unit =
    unitOverride?.signature === unitPreference
      ? unitOverride.unit
      : dominantUnit;
  const buildGroups = useMemo(
    () =>
      (["source", "machine", "module", "beacon", "inserter"] as const)
        .map((kind) => ({
          kind,
          items: totals.buildItems.filter((item) => item.kind === kind),
        }))
        .filter((group) => group.items.length),
    [totals.buildItems],
  );
  if (!snapshots.length) return null;
  return (
    <CollapsiblePanel className="factory-totals collapsible-panel panel-card border-2 border-[#69c5df]/38" defaultOpen>
      <summary className="collapsible-summary dashboard-summary factory-totals-summary list-none p-4">
        <div className="summary-leading flex min-w-0 items-center gap-3">
          <span className="flex size-11 items-center justify-center rounded-xl border border-[#69c5df]/30 bg-[#69c5df]/10 text-[#a8e8f7]">
            <Boxes className="size-5" />
          </span>
          <div>
            <h2 className="text-lg font-semibold text-[#c7eff8]">
              {tr(locale, "factoryTotals")}
            </h2>
            <p className="text-xs leading-relaxed text-zinc-500">
              {tr(locale, "factoryTotalsHint")}
            </p>
          </div>
        </div>
        <span className="summary-trailing">
          <SummaryKpi
            label={tr(locale, "unit")}
            value={unitLabel(unit)}
            tone="cyan"
          />
          <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
        </span>
      </summary>
      <div className="factory-totals-body space-y-4 border-t border-[#69c5df]/16 p-4">
        <div className="totals-toolbar rounded-xl border-2 border-[#69c5df]/24 bg-[#101416] p-3">
          <div className="selected-throughput-strip">
            {snapshots.map((snapshot, index) => (
              <span
                key={snapshot.id}
                className="selected-throughput-kpi"
                data-kpi-tone={(["orange", "cyan", "green", "purple"] as const)[index % 4]}
              >
                <FactorioIcon src={snapshot.product.icon} alt="" size="md" />
                <span className="min-w-0">
                  <small>
                    {localizedName(
                      snapshot.product.id,
                      locale,
                      snapshot.product.type,
                    )}
                  </small>
                  <strong>
                    {formatNumber(
                      toDisplayRate(
                        snapshot.result.ratePerSecond,
                        snapshot.input.unit,
                      ),
                      locale,
                    )}
                    {unitLabel(snapshot.input.unit)}
                  </strong>
                </span>
              </span>
            ))}
          </div>
          <div className="totals-unit-picker">
            <FieldLabel>{tr(locale, "unit")}</FieldLabel>
          <UnitSelect
            value={unit}
            onChange={(next) =>
              setUnitOverride({ signature: unitPreference, unit: next })
            }
          />
          </div>
        </div>
        <CollapsiblePanel data-totals-section="resources" className="collapsible-panel rounded-xl border-2 border-[#74b768]/28 bg-[#101312]" defaultOpen>
          <summary className="collapsible-summary factory-totals-section-summary list-none p-4">
            <div className="summary-leading flex min-w-0 items-center gap-2.5">
              <span className="flex size-10 shrink-0 items-center justify-center rounded-lg border border-[#74b768]/28 bg-[#74b768]/9">
                <Pickaxe className="size-5 text-[#a8dca0]" />
              </span>
              <h3 className="text-base font-semibold text-[#a8dca0]">
                {tr(locale, "combinedResources")}
              </h3>
            </div>
            <span className="summary-trailing">
              <SummaryKpi label="Σ" value={totals.resources.length} tone="green" />
              <ChevronDown className="details-chevron size-4 text-zinc-500 transition" />
            </span>
          </summary>
          <div className="space-y-2 border-t border-white/7 px-4 pb-4 pt-3">
            {totals.resources.map((resource) => (
              <CollapsiblePanel
                data-totals-entry="resource"
                key={`${resource.type}:${resource.id}`}
                className="rounded-xl border border-white/7 bg-[#151719]"
                defaultOpen
              >
                <summary className="collapsible-summary list-none p-3">
                  <div className="summary-leading min-w-0">
                    <MaterialRow flow={resource} unit={unit} locale={locale} />
                  </div>
                  <span className="summary-trailing">
                    <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-600 transition" />
                  </span>
                </summary>
                <div className="flex flex-wrap gap-1.5 border-t border-white/6 px-4 pb-3 pt-2">
                  {resource.contributions.map((contribution) => (
                    <span
                      key={contribution.targetId}
                      className="flex items-center gap-2 rounded-lg border border-white/8 bg-[#0d0f10] px-2.5 py-1.5 text-[11px] text-zinc-500"
                      title={localizedName(
                        contribution.product.id,
                        locale,
                        contribution.product.type,
                      )}
                    >
                      <FactorioIcon
                        src={contribution.product.icon}
                        alt=""
                        size="sm"
                      />
                      <span className="text-zinc-300">
                        {localizedName(
                          contribution.product.id,
                          locale,
                          contribution.product.type,
                        )}
                      </span>
                      <span className="font-mono">
                        {formatNumber(
                          toDisplayRate(contribution.amountPerSecond, unit),
                          locale,
                        )}
                        {unitLabel(unit)}
                      </span>
                      <span className="text-zinc-700">
                        {tr(
                          locale,
                          contribution.fullChain
                            ? "fullChain"
                            : "directInputs",
                        )}
                      </span>
                    </span>
                  ))}
                </div>
              </CollapsiblePanel>
            ))}
          </div>
        </CollapsiblePanel>
        <CollapsiblePanel data-totals-section="processes" className="collapsible-panel rounded-xl border-2 border-[#c17bd5]/28 bg-[#121013]" defaultOpen>
          <summary className="collapsible-summary factory-totals-section-summary list-none p-4">
            <div className="summary-leading flex min-w-0 items-center gap-2.5">
              <span className="flex size-10 shrink-0 items-center justify-center rounded-lg border border-[#c17bd5]/28 bg-[#c17bd5]/9">
                <Factory className="size-5 text-[#d4a9df]" />
              </span>
              <h3 className="text-base font-semibold text-[#d4a9df]">
                {tr(locale, "productionProcesses")}
              </h3>
            </div>
            <span className="summary-trailing">
              <SummaryKpi label="Σ" value={totals.processes.length} tone="purple" />
              <ChevronDown className="details-chevron size-4 text-zinc-500 transition" />
            </span>
          </summary>
          <div className="space-y-2 border-t border-white/7 px-4 pb-4 pt-3">
            {totals.processes.map((process) => (
              <CollapsiblePanel
                data-totals-entry="process"
                key={process.key}
                className="rounded-xl border border-white/7 bg-[#151719]"
                defaultOpen
              >
                <summary className="collapsible-summary list-none p-4">
                  <div className="summary-leading flex min-w-0 items-center gap-3">
                    <FactorioIcon src={process.product.icon} alt="" size="lg" />
                    <div className="min-w-0 flex-1">
                    <p className="whitespace-normal break-words text-sm font-medium">
                      {localizedName(
                        process.product.id,
                        locale,
                        process.product.type,
                      )}
                    </p>
                    <p className="whitespace-normal break-words font-mono text-[11px] text-zinc-600">
                      {localizedName(process.recipe.id, locale, "recipe")} ·{" "}
                      {localizedName(process.machineQuality, locale, "quality")}
                    </p>
                    <p className="mt-1 font-mono text-xs text-[#a8e8f7]">
                      Σ {formatNumber(
                        toDisplayRate(process.ratePerSecond, unit),
                        locale,
                      )}
                      {unitLabel(unit)}
                    </p>
                    </div>
                  </div>
                  <span className="summary-trailing">
                    <span className="flex shrink-0 items-center gap-2 rounded-lg border border-[#c17bd5]/24 bg-[#c17bd5]/7 px-3 py-2">
                      <FactorioIcon src={process.machine.icon} alt="" size="md" />
                      <span className="text-right">
                        <strong className="block font-mono text-lg text-[#d4a9df]">
                          {formatNumber(process.machinesToBuild, locale, 0)} ×
                        </strong>
                        <span className="block max-w-40 whitespace-normal text-[11px] leading-tight text-zinc-500">
                          {localizedName(process.machine.id, locale, "entity")}
                        </span>
                      </span>
                    </span>
                    <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-600 transition" />
                  </span>
                </summary>
                <div className="grid gap-1.5 border-t border-white/6 px-4 pb-4 pt-3">
                  {process.contributions.map((contribution) => (
                    <div
                      key={contribution.targetId}
                      className="rounded-lg border border-white/8 bg-[#0d0f10] px-3 py-2.5 text-[11px] text-zinc-500"
                    >
                      <div className="flex flex-wrap items-center gap-1.5">
                        <FactorioIcon
                          src={contribution.product.icon}
                          alt=""
                          size="sm"
                        />
                        <span className="text-zinc-300">
                          {localizedName(
                            contribution.product.id,
                            locale,
                            contribution.product.type,
                          )}
                        </span>
                        <span className="font-mono text-[#d4a9df]">
                          {formatNumber(
                            contribution.machinesToBuild ?? 0,
                            locale,
                            0,
                          )}{" "}
                          × · {formatNumber(
                            toDisplayRate(contribution.amountPerSecond, unit),
                            locale,
                          )}
                          {unitLabel(unit)}
                        </span>
                      </div>
                      {contribution.inserterLoads?.length ? (
                        <div className="mt-2 grid gap-2 border-t border-white/6 pt-2">
                          {contribution.inserterLoads.map((load) => {
                            const machines = Math.max(
                              1,
                              contribution.machinesToBuild ?? 1,
                            );
                            const total = load.inputTotal + load.outputTotal;
                            return (
                              <div
                                key={`${load.inserterId}:${load.inserterQuality}`}
                                className="inserter-total-card rounded-xl border-2 border-[#f7a72d]/28 bg-[#f7a72d]/7 p-3 text-[11px] text-zinc-500"
                              >
                                <div className="flex flex-wrap items-center gap-2">
                                  <FactorioIcon src={iconFor(load.inserterId)} alt="" size="md" />
                                  <strong className="font-medium text-[#f3c675]">
                                    {localizedName(load.inserterId, locale, "entity")}
                                  </strong>
                                  <span>{localizedName(load.inserterQuality, locale, "quality")}</span>
                                  <span className="ml-auto rounded-lg border border-[#f7a72d]/30 bg-[#0d0f10] px-3 py-1.5">
                                    <strong className="font-mono text-base text-[#f3c675]">
                                      Σ {formatNumber(total, locale, 0)}
                                    </strong>{" "}
                                    {tr(locale, "insertersRequired")}
                                  </span>
                                </div>
                                <div className="mt-2 flex flex-wrap gap-2">
                                  <span className="rounded-md border border-[#74b768]/22 bg-[#74b768]/7 px-2 py-1 font-mono text-[#b9e2b3]">
                                    {formatNumber(load.inputTotal / machines, locale, 2)} {tr(locale, "inShort")}
                                  </span>
                                  <span className="rounded-md border border-[#69c5df]/22 bg-[#69c5df]/7 px-2 py-1 font-mono text-[#a8e8f7]">
                                    {formatNumber(load.outputTotal / machines, locale, 2)} {tr(locale, "outShort")}
                                  </span>
                                  <span className="self-center text-[9px] text-zinc-600">
                                    {tr(locale, "perMachine")}
                                  </span>
                                </div>
                                <div className="mt-2 grid gap-2 md:grid-cols-2">
                                  <div className="rounded-lg border border-[#74b768]/16 bg-[#101312] p-2">
                                    <span className="mb-1.5 block text-[9px] uppercase tracking-wider text-[#a8dca0]">
                                      {tr(locale, "inputs")}
                                    </span>
                                    <div className="flex flex-wrap gap-1.5">
                                      {load.inputFlows.map((flow) => (
                                        <span key={flow.id} className="flex items-center gap-1.5 rounded-md border border-white/7 bg-[#17191b] px-2 py-1">
                                          <FactorioIcon src={flow.icon} alt="" size="sm" />
                                          <strong className="font-mono text-zinc-200">{formatNumber(flow.count, locale, 0)} ×</strong>
                                          <span className="whitespace-normal text-zinc-500">{localizedName(flow.id, locale, "item")}</span>
                                        </span>
                                      ))}
                                    </div>
                                  </div>
                                  <div className="rounded-lg border border-[#69c5df]/16 bg-[#101416] p-2">
                                    <span className="mb-1.5 block text-[9px] uppercase tracking-wider text-[#a8e8f7]">
                                      {tr(locale, "outputs")}
                                    </span>
                                    <div className="flex flex-wrap gap-1.5">
                                      {load.outputFlows.map((flow) => (
                                        <span key={flow.id} className="flex items-center gap-1.5 rounded-md border border-white/7 bg-[#17191b] px-2 py-1">
                                          <FactorioIcon src={flow.icon} alt="" size="sm" />
                                          <strong className="font-mono text-zinc-200">{formatNumber(flow.count, locale, 0)} ×</strong>
                                          <span className="whitespace-normal text-zinc-500">{localizedName(flow.id, locale, "item")}</span>
                                        </span>
                                      ))}
                                    </div>
                                  </div>
                                </div>
                              </div>
                            );
                          })}
                        </div>
                      ) : null}
                    </div>
                  ))}
                </div>
              </CollapsiblePanel>
            ))}
          </div>
        </CollapsiblePanel>
      <BeltThroughputPanel
        materials={totals.materials}
        snapshots={snapshots}
        unit={unit}
        locale={locale}
      />
      <CollapsiblePanel data-totals-section="construction" className="collapsible-panel rounded-xl border-2 border-[#74b768]/28 bg-[#101312]" defaultOpen>
        <summary className="collapsible-summary factory-totals-section-summary list-none p-4">
          <div className="summary-leading flex min-w-0 items-center gap-2.5">
            <span className="flex size-10 items-center justify-center rounded-lg border border-[#74b768]/28 bg-[#74b768]/9">
              <Factory className="size-5 text-[#a8dca0]" />
            </span>
            <div>
              <h3 className="text-base font-semibold text-[#b9e2b3]">
                {tr(locale, "constructionSummary")}
              </h3>
              <p className="text-xs text-zinc-500">
                {tr(locale, "constructionSummaryHint")}
              </p>
            </div>
          </div>
          <span className="summary-trailing">
            <SummaryKpi label="Σ" value={totals.buildItems.length} tone="green" />
            <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-500 transition" />
          </span>
        </summary>
        <div className="space-y-2 border-t border-white/7 p-4">
          {buildGroups.map((group) => {
            const labelKey = `buildKind${group.kind[0].toUpperCase()}${group.kind.slice(1)}` as Parameters<typeof tr>[1];
            return (
              <CollapsiblePanel
                data-totals-entry="construction-group"
                key={group.kind}
                className="rounded-xl border border-[#74b768]/16 bg-[#111315]"
                defaultOpen
              >
                <summary className="collapsible-summary list-none p-3">
                  <span className="summary-leading flex min-w-0 items-center gap-2">
                    <FactorioIcon src={group.items[0].icon} alt="" size="md" />
                    <strong className="text-xs font-semibold text-[#b9e2b3]">
                      {tr(locale, labelKey)}
                    </strong>
                  </span>
                  <span className="summary-trailing">
                    <span className="badge-muted">{group.items.length}</span>
                    <ChevronDown className="details-chevron size-4 shrink-0 text-zinc-600 transition" />
                  </span>
                </summary>
                <div className="grid gap-2 border-t border-white/6 p-3 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
                  {group.items.map((item) => {
                    const quality = QUALITY_BY_ID.get(item.quality)!;
                    const nameKind = item.kind === "module" ? "item" : "entity";
                    return (
                      <div
                        key={item.key}
                        className="flex items-center gap-3 rounded-xl border border-white/8 bg-[#151719] p-3"
                      >
                        <span className="relative shrink-0">
                          <FactorioIcon src={item.icon} alt="" size="lg" />
                          {item.quality !== "normal" ? (
                            <FactorioIcon
                              src={quality.icon}
                              alt=""
                              size="sm"
                              className="absolute -bottom-1 -right-1 size-4 rounded-full bg-[#0d0f10]"
                            />
                          ) : null}
                        </span>
                        <span className="min-w-0 flex-1">
                          <strong className="block whitespace-normal break-words text-xs text-zinc-200">
                            {localizedName(item.id, locale, nameKind)}
                          </strong>
                          <small className="mt-0.5 block text-[9px] uppercase tracking-wider text-zinc-600">
                            {tr(locale, labelKey)}
                            {item.quality !== "normal"
                              ? ` · ${localizedName(item.quality, locale, "quality")}`
                              : ""}
                          </small>
                        </span>
                        <strong className="shrink-0 rounded-lg border border-[#74b768]/22 bg-[#74b768]/8 px-2.5 py-1.5 font-mono text-base text-[#b9e2b3]">
                          {formatNumber(item.amount, locale, 0)} ×
                        </strong>
                      </div>
                    );
                  })}
                </div>
              </CollapsiblePanel>
            );
          })}
        </div>
      </CollapsiblePanel>
      </div>
    </CollapsiblePanel>
  );
}

const defaultModule: ModuleConfig = {
  mode: "auto",
  families: ["productivity"],
  tier: 3,
  quality: "normal",
  manual: [],
};
const defaultBeacon: ModuleConfig = {
  mode: "auto",
  families: ["speed"],
  tier: 3,
  quality: "normal",
  manual: [],
};
export function ScienceWorkspace({
  locale,
  onEnergy,
  energySelection,
  onEnergyToggle,
}: {
  locale: Locale;
  onEnergy: (source: EnergySourceSelection) => void;
  energySelection?: EnergySourceSelection;
  onEnergyToggle: (
    id: string,
    field: "includeDirect" | "includeChain",
    value: boolean,
  ) => void;
}) {
  const [labId, setLabId] = useState<"lab" | "biolab">("biolab");
  const [labQuality, setLabQuality] = useState<QualityId>("normal");
  const [packQuality, setPackQuality] = useState<QualityId>("normal");
  const [mode, setMode] = useState<"actual" | "effective">("effective");
  const [amount, setAmount] = useState(60);
  const [unit, setUnit] = useState<RateUnit>("min");
  const [outputUnit, setOutputUnit] = useState<RateUnit>("min");
  const [machineConfig, setMachineConfig] =
    useState<ModuleConfig>(defaultModule);
  const [beaconConfig, setBeaconConfig] = useState<ModuleConfig>(defaultBeacon);
  const [beaconEnabled, setBeaconEnabled] = useState(true);
  const [beaconCount, setBeaconCount] = useState(8);
  const [biolabBeaconMode, setBiolabBeaconMode] = useState<
    "optimized" | "manual"
  >("optimized");
  const [beaconQuality, setBeaconQuality] = useState<QualityId>("normal");
  const [includeEnergy, setIncludeEnergy] = useState(false);
  const lab = LABS[labId];
  const machineModules = useMemo(
    () =>
      resolvedModules(machineConfig, lab.moduleSlots, lab, SCIENCE_RECIPE),
    [lab, machineConfig],
  );
  const beaconModules = useMemo(
    () => resolvedModules(beaconConfig, 2, lab, SCIENCE_RECIPE, true),
    [beaconConfig, lab],
  );
  const result = useMemo(
    () =>
      calculateScience({
        labId,
        labQuality,
        packQuality,
        mode,
        amountPerMinute:
          amount * (unit === "s" ? 60 : unit === "min" ? 1 : 1 / 60),
        machineModules,
        beaconEnabled,
        beaconCount,
        biolabBeaconMode,
        beaconModules,
        beaconQuality,
      }),
    [
      labId,
      labQuality,
      packQuality,
      mode,
      amount,
      unit,
      machineModules,
      beaconEnabled,
      beaconCount,
      biolabBeaconMode,
      beaconModules,
      beaconQuality,
    ],
  );
  useEffect(
    () =>
      onEnergy({
        id: "science",
        label: tr(locale, "science"),
        icon: lab.icon,
        directKw: result.electricKw,
        chainKw: 0,
        includeDirect: includeEnergy,
        includeChain: false,
        mode: "science",
      }),
    [includeEnergy, result.electricKw, lab.icon, locale, onEnergy],
  );
  const rateInSelectedUnit = (perMinute: number) =>
    perMinute *
    (outputUnit === "s" ? 1 / 60 : outputUnit === "min" ? 1 : 60);
  const selectedUnitLabel =
    outputUnit === "s" ? "/s" : outputUnit === "min" ? "/min" : "/h";
  return (
    <div className="workspace-grid">
      <aside className="workspace-settings">
        <section className="panel-card">
          <SectionTitle
            number="01"
            title={tr(locale, "labType")}
            icons={[iconFor("lab"), iconFor("biolab")]}
          />
          <div className="grid grid-cols-[1fr_1fr_88px] gap-2">
            {(["lab", "biolab"] as const).map((id) => (
              <button
                type="button"
                key={id}
                onClick={() => setLabId(id)}
                className={`flex items-center gap-2 rounded-xl border p-3 ${labId === id ? "border-[#f7a72d]/55 bg-[#f7a72d]/10" : "border-white/8 bg-[#17191b]"}`}
              >
                <FactorioIcon src={LABS[id].icon} alt="" size="lg" />
                <span className="text-xs">
                  {localizedName(id, locale, "entity")}
                </span>
              </button>
            ))}
          </div>
          <div className="mt-3 grid grid-cols-2 gap-2">
            <div>
              <FieldLabel>{tr(locale, "machineQuality")}</FieldLabel>
              <QualitySelect
                value={labQuality}
                onChange={(v) => setLabQuality(v as QualityId)}
                locale={locale}
              />
            </div>
            <div>
              <FieldLabel>{tr(locale, "packQuality")}</FieldLabel>
              <QualitySelect
                value={packQuality}
                onChange={(v) => setPackQuality(v as QualityId)}
                locale={locale}
              />
            </div>
          </div>
        </section>
        <section className="panel-card target-rate-focus">
          <SectionTitle
            number="02"
            title={tr(locale, "targetRate")}
            icons={[iconFor("automation-science-pack")]}
          />
          <div className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_88px] gap-2">
            <Select
              value={mode}
              onValueChange={(v) => setMode(v as "actual" | "effective")}
            >
              <SelectTrigger className={selectClass}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="actual">
                  {tr(locale, "scienceSupplyMode")}
                </SelectItem>
                <SelectItem value="effective">
                  {tr(locale, "scienceTargetMode")}
                </SelectItem>
              </SelectContent>
            </Select>
            <SmartNumberInput
              min={0}
              value={amount}
              onValueChange={setAmount}
            />
            <UnitSelect value={unit} onChange={setUnit} />
          </div>
          <label className="mt-3 flex items-center justify-between rounded-lg border border-white/7 bg-[#17191b] p-3 text-xs">
            <span>{tr(locale, "includeEnergy")}</span>
            <input
              type="checkbox"
              checked={energySelection?.includeDirect ?? includeEnergy}
              onChange={(e) => {
                setIncludeEnergy(e.target.checked);
                onEnergyToggle("science", "includeDirect", e.target.checked);
              }}
            />
          </label>
        </section>
        <section className="panel-card">
          <SectionTitle
            number="03"
            title={tr(locale, "modules")}
            icons={["productivity", "speed"].map((f) =>
              iconFor(`${f}-module-3`),
            )}
          />
          <ModuleConfigurator
            title={tr(locale, "machineModules")}
            locale={locale}
            slots={lab.moduleSlots}
            machine={lab}
            recipe={SCIENCE_RECIPE}
            config={machineConfig}
            onChange={setMachineConfig}
            allowedFamilies={["productivity", "speed"]}
          />
        </section>
        <section className="panel-card">
          <SectionTitle
            number="04"
            title={tr(locale, "beacons")}
            icons={[iconFor("beacon")]}
          />
          <label className="mb-3 flex items-center gap-2 text-xs">
            <input
              type="checkbox"
              checked={beaconEnabled}
              onChange={(e) => setBeaconEnabled(e.target.checked)}
            />
            {beaconEnabled ? tr(locale, "enabled") : tr(locale, "disabled")}
          </label>
          {labId === "biolab" ? (
            <>
              <div className="mb-3 grid grid-cols-2 rounded-lg border border-white/8 bg-[#17191b] p-1">
                <button
                  type="button"
                  onClick={() => setBiolabBeaconMode("optimized")}
                  className={`rounded py-2 text-xs ${biolabBeaconMode === "optimized" ? "bg-[#303439] text-[#f7a72d]" : "text-zinc-500"}`}
                >
                  {tr(locale, "optimizedLayout")}
                </button>
                <button
                  type="button"
                  onClick={() => setBiolabBeaconMode("manual")}
                  className={`rounded py-2 text-xs ${biolabBeaconMode === "manual" ? "bg-[#303439] text-[#f7a72d]" : "text-zinc-500"}`}
                >
                  {tr(locale, "manual")}
                </button>
              </div>
              {biolabBeaconMode === "manual" ? (
                <div>
                  <FieldLabel detail="max 16">
                    {tr(locale, "activePerMachine")}
                  </FieldLabel>
                  <BeaconCountSelect
                    value={beaconCount}
                    maximum={16}
                    disabled={!beaconEnabled}
                    onChange={setBeaconCount}
                  />
                </div>
              ) : null}
            </>
          ) : (
            <div>
              <FieldLabel detail="max 12">
                {tr(locale, "activePerMachine")}
              </FieldLabel>
              <BeaconCountSelect
                value={beaconCount}
                maximum={12}
                disabled={!beaconEnabled}
                onChange={setBeaconCount}
              />
            </div>
          )}
          <div className="mt-3">
            <FieldLabel>{tr(locale, "beaconQuality")}</FieldLabel>
            <QualitySelect
              value={beaconQuality}
              onChange={(v) => setBeaconQuality(v as QualityId)}
              locale={locale}
            />
          </div>
          <div className="mt-3">
            <ModuleConfigurator
              title={tr(locale, "beaconModules")}
              locale={locale}
              slots={2}
              machine={lab}
              recipe={SCIENCE_RECIPE}
              beacon
              config={beaconConfig}
              onChange={setBeaconConfig}
              allowedFamilies={["speed", "efficiency"]}
            />
          </div>
        </section>
      </aside>
      <section className="workspace-results">
        <div className="result-hero">
          <div className="flex items-center gap-4">
            <FactorioIcon src={lab.icon} alt="" size="xl" />
            <div>
              <p className="eyebrow">{tr(locale, "science")}</p>
              <h2 className="text-2xl font-semibold">
                {localizedName(lab.id, locale, "entity")}
              </h2>
            </div>
          </div>
          <div className="shrink-0">
            <FieldLabel>
              {tr(locale, "outputs")} · {tr(locale, "unit")}
            </FieldLabel>
            <UnitSelect value={outputUnit} onChange={setOutputUnit} />
          </div>
        </div>
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
          <MetricCard
            icon={<FlaskConical className="size-4" />}
            label={tr(locale, "actualSpm")}
            value={`${formatNumber(rateInSelectedUnit(result.actualSpm), locale)}${selectedUnitLabel}`}
          />
          <MetricCard
            icon={<Atom className="size-4" />}
            label={tr(locale, "effectiveSpm")}
            value={`${formatNumber(rateInSelectedUnit(result.effectiveSpm), locale)}${selectedUnitLabel}`}
          />
          <MetricCard
            icon={<Factory className="size-4" />}
            label={tr(locale, "machinesRequired")}
            value={String(result.labsToBuild)}
            detail={`${formatNumber(result.labsTheoretical, locale)} ${tr(locale, "theoretical")} · ${formatNumber(rateInSelectedUnit(result.actualCapacityPerLab), locale)}${selectedUnitLabel} ${tr(locale, "perLab")}`}
          />
          <MetricCard
            icon={<Zap className="size-4" />}
            label={tr(locale, "power")}
            value={formatPower(result.electricKw, locale)}
          />
        </div>
        <div className="notice-info">
          <span>
            <strong>
              {tr(locale, "researchPerPack")}: {formatNumber(result.effectivePerPack, locale)}×
            </strong>
            <br />
            {tr(locale, "scienceSpeedNote")}
          </span>
        </div>
        <GeometryDesign
          layout={result.beaconLayout}
          machine={lab}
          locale={locale}
        />
      </section>
    </div>
  );
}

export function EnergyWorkspace({
  locale,
  sources,
  onToggle,
}: {
  locale: Locale;
  sources: EnergySourceSelection[];
  onToggle: (
    id: string,
    field: "includeDirect" | "includeChain",
    value: boolean,
  ) => void;
}) {
  const [inputMode, setInputMode] = useState<"manual" | "imported">("imported");
  const [manualMw, setManualMw] = useState(100);
  const [technology, setTechnology] = useState<EnergyTechnology>("fusion");
  const [quality, setQuality] = useState<QualityId>("normal");
  const [reserve, setReserve] = useState(0);
  const [planet, setPlanet] = useState<EnergyInput["planet"]>("nauvis");
  const [nuclearWidth, setNuclearWidth] = useState(2);
  const [nuclearHeight, setNuclearHeight] = useState(2);
  const [fusionMode, setFusionMode] = useState<"demand" | "fixed">("demand");
  const [fusionReactors, setFusionReactors] = useState<1 | 2 | 3 | 4>(1);
  const [steamGenerator, setSteamGenerator] =
    useState<NonNullable<EnergyInput["steamGenerator"]>>("steam-turbine");
  const importedKw = useMemo(
    () =>
      sources.reduce(
        (sum, source) =>
          sum +
          (source.includeDirect ? source.directKw : 0) +
          (source.includeChain ? source.chainKw : 0),
        0,
      ),
    [sources],
  );
  const targetMw = inputMode === "manual" ? manualMw : importedKw / 1000;
  const result = useMemo(
    () =>
      calculateEnergy({
        targetMw,
        technology,
        quality,
        reservePercent: reserve,
        planet,
        nuclearWidth,
        nuclearHeight,
        fusionMode,
        fusionReactors,
        steamGenerator,
      }),
    [
      targetMw,
      technology,
      quality,
      reserve,
      planet,
      nuclearWidth,
      nuclearHeight,
      fusionMode,
      fusionReactors,
      steamGenerator,
    ],
  );
  const localizedNotes =
    technology === "steam"
      ? [
          tr(locale, "steamFuelNote"),
          `1 × ${localizedName("boiler", locale, "entity")} → ${steamGenerator === "steam-engine" ? 2 : 1} × ${localizedName(steamGenerator, locale, "entity")} · 165 °C`,
        ]
      : technology === "solar"
        ? [
            tr(locale, "solarAverageNote"),
            tr(locale, "solarScalingNote"),
            tr(locale, "solarOrientation"),
          ]
        : technology === "nuclear"
          ? [tr(locale, "nuclearNeighborNote"), tr(locale, "nuclearOrientation")]
          : technology === "heating-tower"
            ? [tr(locale, "heatingEfficiencyNote"), tr(locale, "heatingOrientation")]
            : [
                ...(fusionMode === "demand"
                  ? [tr(locale, "fusionDemandNote")]
                  : []),
                tr(locale, "fusionCoolantNote"),
                tr(locale, "fusionOrientation"),
              ];
  return (
    <div className="workspace-grid">
      <aside className="workspace-settings">
        <section className="panel-card">
          <SectionTitle
            number="01"
            title={tr(locale, "targetDemand")}
            icons={[iconFor("substation")]}
          />
          <div className="grid grid-cols-2 rounded-lg border border-white/8 bg-[#17191b] p-1">
            {(["imported", "manual"] as const).map((mode) => (
              <button
                type="button"
                key={mode}
                onClick={() => setInputMode(mode)}
                className={`rounded py-2 text-xs ${inputMode === mode ? "bg-[#303439] text-[#f7a72d]" : "text-zinc-500"}`}
              >
                {tr(locale, mode === "imported" ? "importedLoads" : "manualMw")}
              </button>
            ))}
          </div>
          {inputMode === "manual" ? (
            <div className="mt-3">
              <FieldLabel>MW</FieldLabel>
              <SmartNumberInput
                min={0}
                step={10}
                value={manualMw}
                onValueChange={setManualMw}
              />
            </div>
          ) : (
            <div className="mt-3 space-y-2">
              <p className="font-mono text-lg text-[#69c5df]">
                {formatPower(importedKw, locale)}
              </p>
              {sources.map((source) => (
                <div
                  key={source.id}
                  className="rounded-lg border border-white/7 bg-[#151719] p-3"
                >
                  <div className="flex items-center gap-2">
                    <FactorioIcon src={source.icon} alt="" size="md" />
                    <span className="min-w-0 flex-1 whitespace-normal break-words text-xs leading-tight">
                      {source.label}
                    </span>
                  </div>
                  <label className="mt-2 flex items-center justify-between text-[10px] text-zinc-500">
                    <span>
                      {tr(locale, "directPower")} ·{" "}
                      {formatPower(source.directKw, locale)}
                    </span>
                    <input
                      type="checkbox"
                      checked={source.includeDirect}
                      onChange={(e) =>
                        onToggle(source.id, "includeDirect", e.target.checked)
                      }
                    />
                  </label>
                  {source.chainKw > 0 ? (
                    <label className="mt-1 flex items-center justify-between text-[10px] text-zinc-500">
                      <span>
                        {tr(locale, "chainPower")} ·{" "}
                        {formatPower(source.chainKw, locale)}
                      </span>
                      <input
                        type="checkbox"
                        checked={source.includeChain}
                        onChange={(e) =>
                          onToggle(source.id, "includeChain", e.target.checked)
                        }
                      />
                    </label>
                  ) : null}
                </div>
              ))}
            </div>
          )}
        </section>
        <section className="panel-card">
          <SectionTitle
            number="02"
            title={tr(locale, "technology")}
            icons={[
              iconFor("steam-engine"),
              iconFor("solar-panel"),
              iconFor("nuclear-reactor"),
              iconFor("fusion-reactor"),
            ]}
          />
          <Select
            value={technology}
            onValueChange={(v) => {
              const next = v as EnergyTechnology;
              setTechnology(next);
              if (next === "steam") setSteamGenerator("steam-engine");
              if (next === "nuclear" || next === "heating-tower")
                setSteamGenerator("steam-turbine");
            }}
          >
            <SelectTrigger className={selectClass}>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {(
                [
                  "steam",
                  "solar",
                  "nuclear",
                  "heating-tower",
                  "fusion",
                ] as EnergyTechnology[]
              ).map((id) => (
                <SelectItem key={id} value={id}>
                  {tr(locale, id === "heating-tower" ? "heatingTower" : id)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <div className="mt-3 grid grid-cols-2 gap-2">
            <div>
              <FieldLabel>{tr(locale, "machineQuality")}</FieldLabel>
              <QualitySelect
                value={quality}
                onChange={(v) => setQuality(v as QualityId)}
                locale={locale}
              />
            </div>
            <div>
              <FieldLabel>{tr(locale, "reserve")} %</FieldLabel>
              <SmartNumberInput min={0} step={5} value={reserve} onValueChange={setReserve} />
            </div>
          </div>
          {technology === "steam" ||
          technology === "nuclear" ||
          technology === "heating-tower" ? (
            <div className="mt-3">
              <FieldLabel>{tr(locale, "steamConsumer")}</FieldLabel>
              <Select
                value={steamGenerator}
                onValueChange={(value) =>
                  setSteamGenerator(
                    value as NonNullable<EnergyInput["steamGenerator"]>,
                  )
                }
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {(["steam-engine", "steam-turbine"] as const).map((id) => (
                    <SelectItem key={id} value={id}>
                      <span className="flex items-center gap-2">
                        <FactorioIcon src={iconFor(id)} alt="" size="sm" />
                        {localizedName(id, locale, "entity")}
                      </span>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {technology !== "steam" && steamGenerator === "steam-engine" ? (
                <div className="notice-warning mt-2">
                  {tr(locale, "highTemperatureLoss")}
                </div>
              ) : null}
            </div>
          ) : null}
          {technology === "solar" ? (
            <div className="mt-3">
              <FieldLabel>{tr(locale, "planet")}</FieldLabel>
              <Select
                value={planet}
                onValueChange={(v) => setPlanet(v as EnergyInput["planet"])}
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {[
                    "nauvis",
                    "vulcanus",
                    "gleba",
                    "fulgora",
                    "aquilo",
                    "space",
                  ].map((id) => (
                    <SelectItem key={id} value={id}>
                      {localizedName(id, locale, "space")}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          ) : null}
          {technology === "nuclear" ? (
            <div className="mt-3 space-y-3">
              <div className="grid grid-cols-4 gap-1">
                {([[1,1],[2,1],[2,2],[2,4]] as const).map(([width,height]) => <button type="button" key={`${width}x${height}`} onClick={() => { setNuclearWidth(width); setNuclearHeight(height); }} className={`rounded-lg border px-2 py-2 font-mono text-[10px] ${nuclearWidth===width&&nuclearHeight===height?"border-[#f7a72d]/55 bg-[#f7a72d]/10 text-[#f7a72d]":"border-white/8 bg-[#17191b] text-zinc-500"}`}>{width}×{height}</button>)}
              </div>
              <div className="grid grid-cols-2 gap-2">
                <div><FieldLabel>{tr(locale,"width")} · X</FieldLabel><SmartNumberInput min={1} max={8} value={nuclearWidth} onValueChange={(value)=>setNuclearWidth(Math.floor(value))} /></div>
                <div><FieldLabel>{tr(locale,"height")} · Y</FieldLabel><SmartNumberInput min={1} max={8} value={nuclearHeight} onValueChange={(value)=>setNuclearHeight(Math.floor(value))} /></div>
              </div>
              <div className="notice-info"><span><strong>{nuclearWidth*nuclearHeight} × {localizedName("nuclear-reactor",locale,"entity")}</strong><br />{tr(locale,"neighborLinks")}: {nuclearWidth*Math.max(0,nuclearHeight-1)+nuclearHeight*Math.max(0,nuclearWidth-1)} · {tr(locale,"nuclearNeighborNote")}</span></div>
            </div>
          ) : null}
          {technology === "fusion" ? (
            <div className="mt-3 space-y-3">
              <Select
                value={fusionMode}
                onValueChange={(v) => setFusionMode(v as "demand" | "fixed")}
              >
                <SelectTrigger className={selectClass}>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="demand">
                    {tr(locale, "demandSizing")}
                  </SelectItem>
                  <SelectItem value="fixed">
                    {tr(locale, "fixedBlock")}
                  </SelectItem>
                </SelectContent>
              </Select>
              <div>
                <FieldLabel>{tr(locale, "reactorBlock")}</FieldLabel>
                <div className="grid grid-cols-4 gap-1">
                  {([1, 2, 3, 4] as const).map((count) => (
                    <button
                      type="button"
                      key={count}
                      onClick={() => setFusionReactors(count)}
                      className={`rounded-lg border p-2 text-xs ${fusionReactors === count ? "border-[#f7a72d]/55 bg-[#f7a72d]/10" : "border-white/8 bg-[#17191b]"}`}
                    >
                      <span className="flex items-center justify-center gap-1">
                        <FactorioIcon
                          src={iconFor("fusion-reactor")}
                          alt=""
                          size="sm"
                        />
                        <strong>{count}</strong>
                      </span>
                      <span className="mt-1 flex items-center justify-center gap-1 font-mono text-[8px] text-zinc-600">
                        <FactorioIcon
                          src={iconFor("fusion-generator")}
                          alt=""
                          size="sm"
                        />
                        {FUSION_BLOCKS[count].generators}
                      </span>
                    </button>
                  ))}
                </div>
              </div>
            </div>
          ) : null}
        </section>
      </aside>
      <section className="workspace-results">
        <div className="result-hero">
          <div>
            <p className="eyebrow">
              {technology === "fusion" && fusionMode === "fixed"
                ? tr(locale, "fixedBlock")
                : tr(locale, "targetDemand")}
            </p>
            <h2 className="text-3xl font-semibold">
              {technology === "fusion" && fusionMode === "fixed"
                ? `${fusionReactors} × ${localizedName("fusion-reactor", locale, "entity")}`
                : formatMw(targetMw, locale)}
            </h2>
          </div>
          <FactorioIcon
            src={iconFor(
              technology === "steam"
                ? "steam-engine"
                : technology === "solar"
                  ? "solar-panel"
                  : technology === "nuclear"
                    ? "nuclear-reactor"
                    : technology === "heating-tower"
                      ? "heating-tower"
                      : "fusion-reactor",
            )}
            alt=""
            size="xl"
          />
        </div>
        <div className="grid gap-3 sm:grid-cols-3">
          <MetricCard
            icon={<Bolt className="size-4" />}
            label={tr(locale, "grossOutput")}
            value={formatMw(result.grossMw, locale)}
          />
          <MetricCard
            icon={<Zap className="size-4" />}
            label={tr(locale, "netOutput")}
            value={formatMw(result.netMw, locale)}
          />
          <MetricCard
            icon={<CircleGauge className="size-4" />}
            label={tr(locale, "reserve")}
            value={`${reserve}%`}
          />
        </div>
        {result.fusion ? (
          <div className="grid gap-3 sm:grid-cols-4">
            <MetricCard
              icon={<Atom className="size-4" />}
              label={localizedName("fusion-reactor", locale, "entity")}
              value={String(result.fusion.reactors)}
              detail={`${result.fusion.blocks} ${tr(locale, "blocks")}`}
            />
            <MetricCard
              icon={<Gauge className="size-4" />}
              label={localizedName("fusion-generator", locale, "entity")}
              value={String(result.fusion.generators)}
            />
            <MetricCard
              icon={<Bolt className="size-4" />}
              label={tr(locale, "internalDemand")}
              value={formatMw(result.fusion.internalMw, locale)}
            />
            <MetricCard
              icon={
                <FactorioIcon
                  src={iconFor("fusion-power-cell")}
                  alt=""
                  size="sm"
                />
              }
              label={localizedName("fusion-power-cell", locale, "item")}
              value={`${formatNumber(result.fusion.cellsPerSecond, locale, 5)}/s`}
            />
          </div>
        ) : null}
        <div className="grid gap-3 lg:grid-cols-2">
          <div className="panel-card">
            <h3 className="mb-3 text-sm font-semibold">
              {tr(locale, "entities")}
            </h3>
            <div className="space-y-2">
              {result.entities.map((entry) => (
                <div
                  key={entry.id}
                  className="flex items-center gap-3 rounded-lg border border-white/7 bg-[#151719] p-3"
                >
                  <FactorioIcon src={entry.icon} alt="" size="lg" />
                  <div className="min-w-0 flex-1">
                    <p className="whitespace-normal break-words text-sm leading-tight">
                      {localizedName(entry.id, locale, "entity")}
                    </p>
                    {entry.detail ? (
                      <p className="text-[10px] text-zinc-600">
                        {entry.detail}
                      </p>
                    ) : null}
                  </div>
                  <strong className="font-mono">
                    {formatNumber(entry.amount, locale)}
                  </strong>
                </div>
              ))}
            </div>
          </div>
          <div className="panel-card">
            <h3 className="mb-3 text-sm font-semibold">
              {tr(locale, "fuelAndFluids")}
            </h3>
            <div className="space-y-2">
              {result.inputs.map((entry) => (
                <div
                  key={entry.id}
                  className="flex items-center gap-3 rounded-lg border border-white/7 bg-[#151719] p-3"
                >
                  <FactorioIcon src={entry.icon} alt="" size="lg" />
                  <span className="min-w-0 flex-1 whitespace-normal break-words text-sm leading-tight">
                    {localizedName(
                      entry.id,
                      locale,
                      entry.id.includes("water") ||
                        entry.id.includes("fluoroketone")
                        ? "fluid"
                        : "item",
                    )}
                  </span>
                  <strong className="font-mono">
                    {formatNumber(entry.perSecond, locale, 5)}/s
                  </strong>
                </div>
              ))}
            </div>
          </div>
        </div>
        {result.blueprint ? <GeometryDesign layout={result.blueprint} locale={locale} title={`${tr(locale,"geometryCheck")} · ${tr(locale,"energyBlueprint")}`} subtitle={tr(locale,"energyLayoutNote")} /> : null}
        <div className="space-y-2">
          {localizedNotes.map((note, index) => (
            <div key={index} className="notice-info">
              {note}
            </div>
          ))}
        </div>
      </section>
    </div>
  );
}
