﻿"use client";

import Link from "next/link";
import { useParams, useSearchParams } from "next/navigation";
import { FormEvent, useEffect, useMemo, useState } from "react";
import {
  createConsumer,
  deleteConsumer,
  getProject,
  listConsumers,
  listDistributionBoards,
  listProjectDevices,
  listRooms,
  updateConsumer,
} from "../../../../frontend/utils/api";
import type {
  ConsumerWithCalculatedValues,
  CreateConsumerInput,
  DistributionBoardDto,
  ProjectDeviceDto,
  ProjectDto,
  RoomDto,
} from "../../../../frontend/types";
import {
  cableCrossSectionOptions,
  cableTypeOptions,
  consumerGroupOptions,
  deviceTypeOptions,
  phaseTypeOptions,
  protectionCharacteristicOptions,
  protectionTypeOptions,
  tradeOrCostGroupOptions,
} from "../../../../shared/constants/consumer-option-lists";

interface SlotState {
  boardId: string;
  selectedConsumerIds: string[];
}

interface QuickCreateFormState {
  name: string;
  roomId: string;
  quantity: string;
  installedPowerPerUnitKw: string;
  demandFactor: string;
  totalPowerKw: string;
  addCount: string;
}

type SortField = "name" | "circuitNumber" | "quantity" | "installedPowerPerUnitKw" | "demandFactor" | "demandPowerKw";
type SortDirection = "asc" | "desc";

interface ListFilterState {
  query: string;
  sortField: SortField;
  sortDirection: SortDirection;
}

interface BulkEditState {
  quantity: string;
  installedPowerPerUnitKw: string;
  demandFactor: string;
}

type ColumnKey =
  | "selection"
  | "circuitNumber"
  | "description"
  | "name"
  | "projectDevice"
  | "deviceLink"
  | "room"
  | "floor"
  | "category"
  | "deviceType"
  | "phaseType"
  | "tradeOrCostGroup"
  | "group"
  | "protectionType"
  | "protectionRatedCurrent"
  | "protectionCharacteristic"
  | "cableType"
  | "cableCrossSection"
  | "comment"
  | "quantity"
  | "installedPowerPerUnitKw"
  | "installedPowerKw"
  | "demandFactor"
  | "demandPowerKw"
  | "voltageV"
  | "phaseCount"
  | "powerFactor"
  | "currentA"
  | "note"
  | "actions";

const defaultSlots: SlotState[] = [
  { boardId: "", selectedConsumerIds: [] },
  { boardId: "", selectedConsumerIds: [] },
  { boardId: "", selectedConsumerIds: [] },
];

const defaultCreateForm: QuickCreateFormState = {
  name: "",
  roomId: "",
  quantity: "1",
  installedPowerPerUnitKw: "0.10",
  demandFactor: "1.00",
  totalPowerKw: "0.10",
  addCount: "1",
};

const defaultFilterState: ListFilterState = {
  query: "",
  sortField: "name",
  sortDirection: "asc",
};

const defaultBulkEditState: BulkEditState = {
  quantity: "",
  installedPowerPerUnitKw: "",
  demandFactor: "",
};

const allColumns: Array<{ key: ColumnKey; label: string }> = [
  { key: "selection", label: "Auswahl" },
  { key: "circuitNumber", label: "Stromkreis-Nr." },
  { key: "description", label: "Beschreibung" },
  { key: "name", label: "Verbraucher" },
  { key: "projectDevice", label: "Projektgerät" },
  { key: "deviceLink", label: "Verknüpfung" },
  { key: "room", label: "Raum" },
  { key: "floor", label: "Etage" },
  { key: "category", label: "Kategorie" },
  { key: "deviceType", label: "Geräteart" },
  { key: "phaseType", label: "Phasenart" },
  { key: "tradeOrCostGroup", label: "Kostengruppe" },
  { key: "group", label: "Gruppe" },
  { key: "protectionType", label: "Schutzart" },
  { key: "protectionRatedCurrent", label: "Schutznennstrom [A]" },
  { key: "protectionCharacteristic", label: "Schutzkennlinie" },
  { key: "cableType", label: "Kabeltyp" },
  { key: "cableCrossSection", label: "Querschnitt" },
  { key: "comment", label: "Kommentar" },
  { key: "quantity", label: "Anzahl" },
  { key: "installedPowerPerUnitKw", label: "Einzelleistung [kW]" },
  { key: "installedPowerKw", label: "Installierte Leistung [kW]" },
  { key: "demandFactor", label: "Gleichzeitigkeitsfaktor" },
  { key: "demandPowerKw", label: "Gesamtleistung [kW]" },
  { key: "voltageV", label: "Spannung [V]" },
  { key: "phaseCount", label: "Phasen" },
  { key: "powerFactor", label: "cos f" },
  { key: "currentA", label: "Strom [A]" },
  { key: "note", label: "Bemerkung" },
  { key: "actions", label: "Aktionen" },
];

const defaultVisibleColumns: ColumnKey[] = [
  "selection",
  "circuitNumber",
  "description",
  "name",
  "projectDevice",
  "deviceLink",
  "room",
  "quantity",
  "installedPowerPerUnitKw",
  "demandFactor",
  "demandPowerKw",
  "actions",
];

function formatNumber(value: number | undefined, digits = 2) {
  if (value === undefined || Number.isNaN(value)) {
    return "-";
  }
  return value.toFixed(digits);
}

function roomLabel(room: RoomDto) {
  return `${room.roomNumber} - ${room.roomName}`;
}

export default function CircuitListsPage() {
  const params = useParams<{ projectId: string }>();
  const searchParams = useSearchParams();
  const [projectId, setProjectId] = useState("");
  const [project, setProject] = useState<ProjectDto | null>(null);
  const [boards, setBoards] = useState<DistributionBoardDto[]>([]);
  const [rooms, setRooms] = useState<RoomDto[]>([]);
  const [projectDevices, setProjectDevices] = useState<ProjectDeviceDto[]>([]);
  const [consumers, setConsumers] = useState<ConsumerWithCalculatedValues[]>([]);
  const [slots, setSlots] = useState<SlotState[]>(defaultSlots);
  const [activeListCount, setActiveListCount] = useState(1);
  const [newDeviceTemplateId, setNewDeviceTemplateId] = useState<Record<number, string>>({
    0: "",
    1: "",
    2: "",
  });
  const [quickCreateForms, setQuickCreateForms] = useState<Record<number, QuickCreateFormState>>({
    0: { ...defaultCreateForm },
    1: { ...defaultCreateForm },
    2: { ...defaultCreateForm },
  });
  const [visibleColumns, setVisibleColumns] = useState<ColumnKey[]>(defaultVisibleColumns);
  const [listFilters, setListFilters] = useState<Record<number, ListFilterState>>({
    0: { ...defaultFilterState },
    1: { ...defaultFilterState },
    2: { ...defaultFilterState },
  });
  const [bulkEditForms, setBulkEditForms] = useState<Record<number, BulkEditState>>({
    0: { ...defaultBulkEditState },
    1: { ...defaultBulkEditState },
    2: { ...defaultBulkEditState },
  });
  const [showColumnManager, setShowColumnManager] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);

  useEffect(() => {
    setProjectId(params.projectId);
  }, [params.projectId]);

  useEffect(() => {
    if (!projectId) {
      return;
    }
    Promise.all([
      getProject(projectId),
      listDistributionBoards(projectId),
      listRooms(projectId),
      listProjectDevices(projectId),
      listConsumers(projectId),
    ])
      .then(([loadedProject, distributionBoards, loadedRooms, loadedProjectDevices, loadedConsumers]) => {
        const initialBoardId = searchParams.get("boardId") ?? distributionBoards[0]?.id ?? "";
        setProject(loadedProject);
        setBoards(distributionBoards);
        setRooms(loadedRooms);
        setProjectDevices(loadedProjectDevices);
        setConsumers(loadedConsumers);
        setSlots((current) => [
          { ...current[0], boardId: current[0].boardId || initialBoardId },
          current[1],
          current[2],
        ]);
        setActiveListCount(1);
        setError(null);
      })
      .catch((err: unknown) =>
        setError(err instanceof Error ? err.message : "Stromkreislisten konnten nicht geladen werden.")
      );
  }, [projectId, searchParams]);

  const boardById = useMemo(() => new Map(boards.map((board) => [board.id, board])), [boards]);
  const slotColumnClass =
    activeListCount === 1 ? "col-12" : activeListCount === 2 ? "col-12 col-xxl-6" : "col-12 col-xxl-4";

  function consumersForBoard(boardId: string) {
    return consumers.filter((item) => item.distributionBoardId === boardId);
  }

  function updateListFilter(slotIndex: number, patch: Partial<ListFilterState>) {
    setListFilters((current) => ({
      ...current,
      [slotIndex]: { ...current[slotIndex], ...patch },
    }));
  }

  function updateBulkEditForm(slotIndex: number, patch: Partial<BulkEditState>) {
    setBulkEditForms((current) => ({
      ...current,
      [slotIndex]: { ...current[slotIndex], ...patch },
    }));
  }

  function getComparableSortValue(consumer: ConsumerWithCalculatedValues, sortField: SortField): number | string {
    switch (sortField) {
      case "name":
        return (consumer.name ?? "").toLocaleLowerCase("de-DE");
      case "circuitNumber":
        return (consumer.circuitNumber ?? "").toLocaleLowerCase("de-DE");
      case "quantity":
        return consumer.quantity ?? 0;
      case "installedPowerPerUnitKw":
        return consumer.installedPowerPerUnitKw ?? 0;
      case "demandFactor":
        return consumer.demandFactor ?? 0;
      case "demandPowerKw":
        return consumer.demandPowerKw ?? 0;
      default:
        return "";
    }
  }

  function setSlotBoard(slotIndex: number, boardId: string) {
    setSlots((current) =>
      current.map((slot, index) => (index === slotIndex ? { boardId, selectedConsumerIds: [] } : slot))
    );
  }

  function addList() {
    setActiveListCount((current) => Math.min(3, current + 1));
  }

  function removeList() {
    setActiveListCount((current) => {
      const next = Math.max(1, current - 1);
      setSlots((slotState) =>
        slotState.map((slot, index) => (index >= next ? { boardId: "", selectedConsumerIds: [] } : slot))
      );
      return next;
    });
  }

  function toggleConsumerSelection(slotIndex: number, consumerId: string) {
    setSlots((current) =>
      current.map((slot, index) => {
        if (index !== slotIndex) {
          return slot;
        }
        const exists = slot.selectedConsumerIds.includes(consumerId);
        return {
          ...slot,
          selectedConsumerIds: exists
            ? slot.selectedConsumerIds.filter((id) => id !== consumerId)
            : [...slot.selectedConsumerIds, consumerId],
        };
      })
    );
  }

  function updateQuickCreateForm(slotIndex: number, patch: Partial<QuickCreateFormState>) {
    setQuickCreateForms((current) => {
      const next = { ...current[slotIndex], ...patch };
      const quantity = Number(next.quantity);
      const unit = Number(next.installedPowerPerUnitKw);
      const demandFactor = Number(next.demandFactor);
      if (!Number.isNaN(quantity) && !Number.isNaN(unit) && !Number.isNaN(demandFactor)) {
        next.totalPowerKw = String(quantity * unit * demandFactor);
      }
      return { ...current, [slotIndex]: next };
    });
  }

  function updateTotalPower(slotIndex: number, totalPowerKw: string) {
    setQuickCreateForms((current) => {
      const next = { ...current[slotIndex], totalPowerKw };
      const quantity = Number(next.quantity);
      const demandFactor = Number(next.demandFactor);
      const total = Number(totalPowerKw);
      if (
        !Number.isNaN(quantity) &&
        !Number.isNaN(demandFactor) &&
        !Number.isNaN(total) &&
        quantity > 0 &&
        demandFactor > 0
      ) {
        next.installedPowerPerUnitKw = String(total / (quantity * demandFactor));
      }
      return { ...current, [slotIndex]: next };
    });
  }

  async function reloadConsumers() {
    if (!projectId) {
      return;
    }
    setConsumers(await listConsumers(projectId));
  }

  async function handleCreateManualConsumer(slotIndex: number, event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const slot = slots[slotIndex];
    const form = quickCreateForms[slotIndex];
    const name = form.name.trim();
    if (!projectId || !slot.boardId || !name) {
      return;
    }

    const payload: CreateConsumerInput = {
      projectId,
      distributionBoardId: slot.boardId,
      isLinkedToDevice: false,
      roomId: form.roomId || undefined,
      description: name,
      name,
      quantity: Number(form.quantity),
      installedPowerPerUnitKw: Number(form.installedPowerPerUnitKw),
      demandFactor: Number(form.demandFactor),
      phaseCount: 1,
      powerFactor: 1,
    };

    setIsSaving(true);
    setError(null);
    try {
      await createConsumer(payload);
      setQuickCreateForms((current) => ({
        ...current,
        [slotIndex]: { ...defaultCreateForm, roomId: current[slotIndex].roomId },
      }));
      await reloadConsumers();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Verbraucher konnte nicht erstellt werden.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleCreateFromProjectDevice(slotIndex: number) {
    const slot = slots[slotIndex];
    const form = quickCreateForms[slotIndex];
    const templateId = newDeviceTemplateId[slotIndex];
    const projectDevice = projectDevices.find((item) => item.id === templateId);
    if (!projectId || !slot.boardId || !projectDevice) {
      return;
    }
    const addCountRaw = Number(form.addCount);
    const addCount = Number.isFinite(addCountRaw) ? Math.max(1, Math.floor(addCountRaw)) : 1;

    const payload: CreateConsumerInput = {
      projectId,
      distributionBoardId: slot.boardId,
      projectDeviceId: projectDevice.id,
      isLinkedToDevice: true,
      roomId: form.roomId || undefined,
      description: projectDevice.displayName,
      name: projectDevice.displayName,
      category: projectDevice.category ?? undefined,
      quantity: projectDevice.quantity,
      installedPowerPerUnitKw: projectDevice.installedPowerPerUnitKw,
      demandFactor: projectDevice.demandFactor,
      phaseCount: projectDevice.phaseCount ?? 1,
      powerFactor: projectDevice.powerFactor ?? 1,
      note: projectDevice.note ?? undefined,
    };

    setIsSaving(true);
    setError(null);
    try {
      await Promise.all(Array.from({ length: addCount }, () => createConsumer(payload)));
      await reloadConsumers();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Verbraucher konnte nicht aus Projektgerät erstellt werden.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleCopyToSlot(sourceConsumer: ConsumerWithCalculatedValues, targetSlotIndex: number) {
    const targetBoardId = slots[targetSlotIndex].boardId;
    if (!projectId || !targetBoardId) {
      return;
    }

    const payload: CreateConsumerInput = {
      projectId,
      distributionBoardId: targetBoardId,
      projectDeviceId: sourceConsumer.projectDeviceId ?? undefined,
      isLinkedToDevice: sourceConsumer.isLinkedToDevice,
      circuitNumber: sourceConsumer.circuitNumber,
      description: sourceConsumer.description,
      roomId: sourceConsumer.roomId ?? undefined,
      name: sourceConsumer.name,
      category: sourceConsumer.category,
      deviceType: sourceConsumer.deviceType,
      phaseType: sourceConsumer.phaseType,
      tradeOrCostGroup: sourceConsumer.tradeOrCostGroup,
      group: sourceConsumer.group,
      protectionType: sourceConsumer.protectionType,
      protectionRatedCurrent: sourceConsumer.protectionRatedCurrent,
      protectionCharacteristic: sourceConsumer.protectionCharacteristic,
      cableType: sourceConsumer.cableType,
      cableCrossSection: sourceConsumer.cableCrossSection,
      comment: sourceConsumer.comment,
      quantity: sourceConsumer.quantity,
      installedPowerPerUnitKw: sourceConsumer.installedPowerPerUnitKw,
      demandFactor: sourceConsumer.demandFactor,
      voltageV: sourceConsumer.voltageV,
      phaseCount: sourceConsumer.phaseCount,
      powerFactor: sourceConsumer.powerFactor,
      note: sourceConsumer.note,
    };

    setIsSaving(true);
    setError(null);
    try {
      await createConsumer(payload);
      await reloadConsumers();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Kopieren in Ziel-Stromkreisliste fehlgeschlagen.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleDuplicateInSameList(sourceConsumer: ConsumerWithCalculatedValues) {
    if (!projectId || !sourceConsumer.distributionBoardId) {
      return;
    }

    const payload: CreateConsumerInput = {
      projectId,
      distributionBoardId: sourceConsumer.distributionBoardId,
      projectDeviceId: sourceConsumer.projectDeviceId ?? undefined,
      isLinkedToDevice: sourceConsumer.isLinkedToDevice,
      circuitNumber: sourceConsumer.circuitNumber,
      description: sourceConsumer.description,
      roomId: sourceConsumer.roomId ?? undefined,
      name: sourceConsumer.name,
      category: sourceConsumer.category,
      deviceType: sourceConsumer.deviceType,
      phaseType: sourceConsumer.phaseType,
      tradeOrCostGroup: sourceConsumer.tradeOrCostGroup,
      group: sourceConsumer.group,
      protectionType: sourceConsumer.protectionType,
      protectionRatedCurrent: sourceConsumer.protectionRatedCurrent,
      protectionCharacteristic: sourceConsumer.protectionCharacteristic,
      cableType: sourceConsumer.cableType,
      cableCrossSection: sourceConsumer.cableCrossSection,
      comment: sourceConsumer.comment,
      quantity: sourceConsumer.quantity,
      installedPowerPerUnitKw: sourceConsumer.installedPowerPerUnitKw,
      demandFactor: sourceConsumer.demandFactor,
      voltageV: sourceConsumer.voltageV,
      phaseCount: sourceConsumer.phaseCount,
      powerFactor: sourceConsumer.powerFactor,
      note: sourceConsumer.note,
    };

    setIsSaving(true);
    setError(null);
    try {
      await createConsumer(payload);
      await reloadConsumers();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Duplizieren in derselben Liste fehlgeschlagen.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleCopySelectionToSlot(sourceSlotIndex: number, targetSlotIndex: number) {
    const sourceSlot = slots[sourceSlotIndex];
    const targetBoardId = slots[targetSlotIndex].boardId;
    if (!projectId || !targetBoardId || !sourceSlot.selectedConsumerIds.length) {
      return;
    }

    const selected = consumers.filter((consumer) => sourceSlot.selectedConsumerIds.includes(consumer.id));
    if (!selected.length) {
      return;
    }

    setIsSaving(true);
    setError(null);
    try {
      await Promise.all(
        selected.map((sourceConsumer) =>
          createConsumer({
            projectId,
            distributionBoardId: targetBoardId,
            projectDeviceId: sourceConsumer.projectDeviceId ?? undefined,
            isLinkedToDevice: sourceConsumer.isLinkedToDevice,
            circuitNumber: sourceConsumer.circuitNumber,
            description: sourceConsumer.description,
            roomId: sourceConsumer.roomId ?? undefined,
            name: sourceConsumer.name,
            category: sourceConsumer.category,
            deviceType: sourceConsumer.deviceType,
            phaseType: sourceConsumer.phaseType,
            tradeOrCostGroup: sourceConsumer.tradeOrCostGroup,
            group: sourceConsumer.group,
            protectionType: sourceConsumer.protectionType,
            protectionRatedCurrent: sourceConsumer.protectionRatedCurrent,
            protectionCharacteristic: sourceConsumer.protectionCharacteristic,
            cableType: sourceConsumer.cableType,
            cableCrossSection: sourceConsumer.cableCrossSection,
            comment: sourceConsumer.comment,
            quantity: sourceConsumer.quantity,
            installedPowerPerUnitKw: sourceConsumer.installedPowerPerUnitKw,
            demandFactor: sourceConsumer.demandFactor,
            voltageV: sourceConsumer.voltageV,
            phaseCount: sourceConsumer.phaseCount,
            powerFactor: sourceConsumer.powerFactor,
            note: sourceConsumer.note,
          })
        )
      );
      await reloadConsumers();
      setSlots((current) =>
        current.map((slot, index) => (index === sourceSlotIndex ? { ...slot, selectedConsumerIds: [] } : slot))
      );
    } catch (err) {
      setError(err instanceof Error ? err.message : "Sammel-Kopieren fehlgeschlagen.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleBulkEditSelection(slotIndex: number) {
    const slot = slots[slotIndex];
    if (!slot.selectedConsumerIds.length) {
      return;
    }

    const form = bulkEditForms[slotIndex];
    const patch: Partial<CreateConsumerInput> = {};
    const quantity = form.quantity.trim();
    const installedPowerPerUnitKw = form.installedPowerPerUnitKw.trim();
    const demandFactor = form.demandFactor.trim();

    if (quantity) {
      const value = Number(quantity);
      if (!Number.isNaN(value) && value >= 0) {
        patch.quantity = value;
      }
    }
    if (installedPowerPerUnitKw) {
      const value = Number(installedPowerPerUnitKw);
      if (!Number.isNaN(value) && value >= 0) {
        patch.installedPowerPerUnitKw = value;
      }
    }
    if (demandFactor) {
      const value = Number(demandFactor);
      if (!Number.isNaN(value) && value >= 0 && value <= 1) {
        patch.demandFactor = value;
      }
    }

    if (!Object.keys(patch).length) {
      return;
    }

    const selected = consumers.filter((consumer) => slot.selectedConsumerIds.includes(consumer.id));
    if (!selected.length) {
      return;
    }

    setIsSaving(true);
    setError(null);
    try {
      await Promise.all(selected.map((consumer) => handleInlineUpdateFields(consumer, patch)));
      await reloadConsumers();
      setBulkEditForms((current) => ({ ...current, [slotIndex]: { ...defaultBulkEditState } }));
    } catch (err) {
      setError(err instanceof Error ? err.message : "Sammeländerung fehlgeschlagen.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleInlineUpdateFields(
    consumer: ConsumerWithCalculatedValues,
    patch: Partial<CreateConsumerInput>
  ) {
    const payload = {
      projectId,
      distributionBoardId:
        patch.distributionBoardId !== undefined
          ? patch.distributionBoardId
          : consumer.distributionBoardId ?? undefined,
      circuitListId: patch.circuitListId !== undefined ? patch.circuitListId : consumer.circuitListId ?? undefined,
      projectDeviceId:
        patch.projectDeviceId !== undefined ? patch.projectDeviceId : consumer.projectDeviceId ?? undefined,
      isLinkedToDevice:
        patch.isLinkedToDevice !== undefined ? patch.isLinkedToDevice : consumer.isLinkedToDevice ?? false,
      circuitNumber: patch.circuitNumber !== undefined ? patch.circuitNumber : consumer.circuitNumber,
      description: patch.description !== undefined ? patch.description : consumer.description,
      roomId: patch.roomId !== undefined ? patch.roomId : consumer.roomId ?? undefined,
      name: patch.name ?? consumer.name,
      category: patch.category !== undefined ? patch.category : consumer.category ?? undefined,
      deviceType: patch.deviceType !== undefined ? patch.deviceType : consumer.deviceType,
      phaseType: patch.phaseType !== undefined ? patch.phaseType : consumer.phaseType,
      tradeOrCostGroup:
        patch.tradeOrCostGroup !== undefined ? patch.tradeOrCostGroup : consumer.tradeOrCostGroup,
      group: patch.group !== undefined ? patch.group : consumer.group,
      protectionType: patch.protectionType !== undefined ? patch.protectionType : consumer.protectionType,
      protectionRatedCurrent:
        patch.protectionRatedCurrent !== undefined
          ? patch.protectionRatedCurrent
          : consumer.protectionRatedCurrent,
      protectionCharacteristic:
        patch.protectionCharacteristic !== undefined
          ? patch.protectionCharacteristic
          : consumer.protectionCharacteristic,
      cableType: patch.cableType !== undefined ? patch.cableType : consumer.cableType,
      cableCrossSection:
        patch.cableCrossSection !== undefined ? patch.cableCrossSection : consumer.cableCrossSection,
      comment: patch.comment !== undefined ? patch.comment : consumer.comment,
      quantity: patch.quantity ?? consumer.quantity,
      installedPowerPerUnitKw: patch.installedPowerPerUnitKw ?? consumer.installedPowerPerUnitKw,
      demandFactor: patch.demandFactor ?? consumer.demandFactor,
      voltageV: patch.voltageV !== undefined ? patch.voltageV : consumer.voltageV,
      phaseCount: patch.phaseCount !== undefined ? patch.phaseCount : consumer.phaseCount,
      powerFactor: patch.powerFactor !== undefined ? patch.powerFactor : consumer.powerFactor,
      note: patch.note !== undefined ? patch.note : consumer.note,
    };
    try {
      const updated = await updateConsumer(consumer.id, payload);
      setConsumers((current) => current.map((item) => (item.id === consumer.id ? updated : item)));
    } catch (err) {
      setError(err instanceof Error ? err.message : "Aktualisierung fehlgeschlagen.");
    }
  }

  async function handleDeleteConsumer(consumerId: string) {
    setIsSaving(true);
    setError(null);
    try {
      await deleteConsumer(consumerId);
      await reloadConsumers();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Verbraucher konnte nicht gelöscht werden.");
    } finally {
      setIsSaving(false);
    }
  }

  function toggleColumn(column: ColumnKey) {
    if (column === "selection" || column === "actions") {
      return;
    }
    setVisibleColumns((current) =>
      current.includes(column) ? current.filter((item) => item !== column) : [...current, column]
    );
  }

  function moveColumn(column: ColumnKey, direction: -1 | 1) {
    setVisibleColumns((current) => {
      const index = current.indexOf(column);
      if (index < 0) {
        return current;
      }
      const nextIndex = index + direction;
      if (nextIndex < 0 || nextIndex >= current.length) {
        return current;
      }
      const clone = [...current];
      const [item] = clone.splice(index, 1);
      clone.splice(nextIndex, 0, item);
      return clone;
    });
  }

  const renderedColumns = allColumns.filter((column) => visibleColumns.includes(column.key));

  return (
    <main className="container-fluid py-3">
      <div className="d-flex justify-content-between align-items-center mb-3">
        <div>
          <h1 className="h4 mb-1">Stromkreislisten</h1>
          <p className="text-secondary mb-0">Projekt: {project?.name ?? projectId}</p>
        </div>
        <div className="d-flex gap-2">
          <button
            className="btn btn-outline-primary"
            type="button"
            onClick={addList}
            disabled={activeListCount >= 3}
          >
            Liste hinzufügen
          </button>
          <button
            className="btn btn-outline-primary"
            type="button"
            onClick={removeList}
            disabled={activeListCount <= 1}
          >
            Liste entfernen
          </button>
          <button
            className="btn btn-outline-secondary"
            type="button"
            onClick={() => setShowColumnManager((current) => !current)}
          >
            Spalten konfigurieren
          </button>
          <Link className="btn btn-outline-secondary" href={`/projects/${projectId}`}>
            Zurück zu Verteilern
          </Link>
        </div>
      </div>

      <p className="text-secondary mb-3">Aktiv geöffnet: {activeListCount} von maximal 3 Listen.</p>

      {error ? <div className="alert alert-warning">{error}</div> : null}

      {showColumnManager ? (
        <section className="card shadow-sm mb-3">
          <div className="card-header">Spaltenauswahl und Reihenfolge</div>
          <div className="card-body">
            <div className="row g-2">
              {allColumns
                .filter((column) => column.key !== "selection" && column.key !== "actions")
                .map((column) => (
                  <div className="col-12 col-lg-6" key={column.key}>
                    <div className="d-flex align-items-center justify-content-between border rounded p-2">
                      <label className="form-check m-0">
                        <input
                          className="form-check-input me-2"
                          type="checkbox"
                          checked={visibleColumns.includes(column.key)}
                          onChange={() => toggleColumn(column.key)}
                        />
                        <span className="form-check-label">{column.label}</span>
                      </label>
                      <div className="btn-group btn-group-sm">
                        <button
                          className="btn btn-outline-secondary"
                          type="button"
                          onClick={() => moveColumn(column.key, -1)}
                          disabled={!visibleColumns.includes(column.key)}
                        >
                          ←
                        </button>
                        <button
                          className="btn btn-outline-secondary"
                          type="button"
                          onClick={() => moveColumn(column.key, 1)}
                          disabled={!visibleColumns.includes(column.key)}
                        >
                          →
                        </button>
                      </div>
                    </div>
                  </div>
                ))}
            </div>
            <small className="text-secondary d-block mt-2">
              Standardmäßig sind cos f, Phasen und Strom ausgeblendet. Du kannst sie hier jederzeit einblenden.
            </small>
          </div>
        </section>
      ) : null}

      <div className="row g-3">
        {slots.slice(0, activeListCount).map((slot, slotIndex) => {
          const currentFilter = listFilters[slotIndex];
          const bulkEditForm = bulkEditForms[slotIndex];
          const baseConsumersForSlot = slot.boardId ? consumersForBoard(slot.boardId) : [];
          const query = currentFilter.query.trim().toLocaleLowerCase("de-DE");
          const filteredConsumersForSlot = query
            ? baseConsumersForSlot.filter((consumer) => {
                const searchable = [
                  consumer.circuitNumber ?? "",
                  consumer.description ?? "",
                  consumer.name ?? "",
                  consumer.category ?? "",
                  consumer.note ?? "",
                  consumer.roomNumber ?? "",
                  consumer.roomName ?? "",
                  consumer.floorName ?? "",
                ]
                  .join(" ")
                  .toLocaleLowerCase("de-DE");
                return searchable.includes(query);
              })
            : baseConsumersForSlot;
          const listConsumersForSlot = [...filteredConsumersForSlot].sort((a, b) => {
            const aValue = getComparableSortValue(a, currentFilter.sortField);
            const bValue = getComparableSortValue(b, currentFilter.sortField);
            let result = 0;
            if (typeof aValue === "number" && typeof bValue === "number") {
              result = aValue - bValue;
            } else {
              result = String(aValue).localeCompare(String(bValue), "de-DE", { sensitivity: "base" });
            }
            return currentFilter.sortDirection === "asc" ? result : result * -1;
          });
          const quickForm = quickCreateForms[slotIndex];

          return (
            <section className={slotColumnClass} key={slotIndex}>
              <div className="card shadow-sm h-100">
                <div className="card-header d-flex justify-content-between align-items-center">
                  <span>Liste {slotIndex + 1}</span>
                  <span className="badge text-bg-secondary">{listConsumersForSlot.length}</span>
                </div>
                <div className="card-body vstack gap-2">
                  <label className="form-label mb-0">Verteiler</label>
                  <select
                    className="form-select"
                    value={slot.boardId}
                    onChange={(event) => setSlotBoard(slotIndex, event.target.value)}
                  >
                    <option value="">Bitte wählen</option>
                    {boards.map((board) => (
                      <option key={board.id} value={board.id}>
                        {board.name}
                      </option>
                    ))}
                  </select>

                  <form className="row g-2" onSubmit={(event) => handleCreateManualConsumer(slotIndex, event)}>
                    <div className="col-12">
                      <input
                        className="form-control"
                        placeholder="Name Verbraucher (Anzeigename)"
                        value={quickForm.name}
                        onChange={(event) => updateQuickCreateForm(slotIndex, { name: event.target.value })}
                      />
                    </div>
                    <div className="col-12 col-lg-6">
                      <select
                        className="form-select"
                        value={quickForm.roomId}
                        onChange={(event) => updateQuickCreateForm(slotIndex, { roomId: event.target.value })}
                      >
                        <option value="">Kein Raum</option>
                        {rooms.map((room) => (
                          <option key={room.id} value={room.id}>
                            {roomLabel(room)}
                          </option>
                        ))}
                      </select>
                    </div>
                    <div className="col-6 col-lg-3">
                      <input
                        className="form-control"
                        type="number"
                        min="0"
                        value={quickForm.quantity}
                        onChange={(event) => updateQuickCreateForm(slotIndex, { quantity: event.target.value })}
                        placeholder="Anzahl"
                      />
                    </div>
                    <div className="col-6 col-lg-3">
                      <input
                        className="form-control"
                        type="number"
                        min="0"
                        step="0.01"
                        value={quickForm.installedPowerPerUnitKw}
                        onChange={(event) =>
                          updateQuickCreateForm(slotIndex, { installedPowerPerUnitKw: event.target.value })
                        }
                        placeholder="Einzelleistung"
                      />
                    </div>
                    <div className="col-6 col-lg-6">
                      <input
                        className="form-control"
                        type="number"
                        min="0"
                        max="1"
                        step="0.01"
                        value={quickForm.demandFactor}
                        onChange={(event) => updateQuickCreateForm(slotIndex, { demandFactor: event.target.value })}
                        placeholder="Gleichzeitigkeitsfaktor"
                      />
                    </div>
                    <div className="col-6 col-lg-6">
                      <input
                        className="form-control"
                        type="number"
                        min="0"
                        step="0.01"
                        value={quickForm.totalPowerKw}
                        onChange={(event) => updateTotalPower(slotIndex, event.target.value)}
                        placeholder="Gesamtleistung"
                      />
                    </div>
                    <div className="col-12">
                      <button className="btn btn-primary w-100" type="submit" disabled={!slot.boardId || isSaving}>
                        Verbraucher anlegen
                      </button>
                    </div>
                  </form>

                  <div className="input-group">
                    <select
                      className="form-select"
                      value={newDeviceTemplateId[slotIndex] ?? ""}
                      onChange={(event) =>
                        setNewDeviceTemplateId((current) => ({ ...current, [slotIndex]: event.target.value }))
                      }
                    >
                      <option value="">Projektgerät wählen</option>
                      {projectDevices.map((item) => (
                        <option key={item.id} value={item.id}>
                          {item.displayName}
                        </option>
                      ))}
                    </select>
                    <input
                      className="form-control"
                      type="number"
                      min="1"
                      step="1"
                      value={quickForm.addCount}
                      onChange={(event) => updateQuickCreateForm(slotIndex, { addCount: event.target.value })}
                      title="Anzahl Einträge"
                      style={{ maxWidth: "8rem" }}
                    />
                    <button
                      className="btn btn-outline-primary"
                      type="button"
                      onClick={() => handleCreateFromProjectDevice(slotIndex)}
                      disabled={!slot.boardId || !newDeviceTemplateId[slotIndex] || isSaving}
                    >
                      Übernehmen
                    </button>
                  </div>

                  <div className="table-responsive border rounded">
                    <div className="border-bottom p-2 bg-light-subtle">
                      <div className="row g-2">
                        <div className="col-12 col-xl-4">
                          <input
                            className="form-control form-control-sm"
                            placeholder="Filter (z. B. Name, Raum, Nummer)"
                            value={currentFilter.query}
                            onChange={(event) => updateListFilter(slotIndex, { query: event.target.value })}
                          />
                        </div>
                        <div className="col-6 col-xl-3">
                          <select
                            className="form-select form-select-sm"
                            value={currentFilter.sortField}
                            onChange={(event) =>
                              updateListFilter(slotIndex, { sortField: event.target.value as SortField })
                            }
                          >
                            <option value="name">Sortierung: Verbraucher</option>
                            <option value="circuitNumber">Sortierung: Stromkreis-Nr.</option>
                            <option value="quantity">Sortierung: Anzahl</option>
                            <option value="installedPowerPerUnitKw">Sortierung: Einzelleistung</option>
                            <option value="demandFactor">Sortierung: Gleichzeitigkeitsfaktor</option>
                            <option value="demandPowerKw">Sortierung: Gesamtleistung</option>
                          </select>
                        </div>
                        <div className="col-6 col-xl-2">
                          <select
                            className="form-select form-select-sm"
                            value={currentFilter.sortDirection}
                            onChange={(event) =>
                              updateListFilter(slotIndex, { sortDirection: event.target.value as SortDirection })
                            }
                          >
                            <option value="asc">Aufsteigend</option>
                            <option value="desc">Absteigend</option>
                          </select>
                        </div>
                        <div className="col-4 col-xl-1">
                          <input
                            className="form-control form-control-sm"
                            type="number"
                            min="0"
                            step="1"
                            placeholder="Anzahl"
                            value={bulkEditForm.quantity}
                            onChange={(event) => updateBulkEditForm(slotIndex, { quantity: event.target.value })}
                          />
                        </div>
                        <div className="col-4 col-xl-1">
                          <input
                            className="form-control form-control-sm"
                            type="number"
                            min="0"
                            step="0.01"
                            placeholder="kW"
                            value={bulkEditForm.installedPowerPerUnitKw}
                            onChange={(event) =>
                              updateBulkEditForm(slotIndex, { installedPowerPerUnitKw: event.target.value })
                            }
                          />
                        </div>
                        <div className="col-4 col-xl-1">
                          <input
                            className="form-control form-control-sm"
                            type="number"
                            min="0"
                            max="1"
                            step="0.01"
                            placeholder="GZF"
                            value={bulkEditForm.demandFactor}
                            onChange={(event) => updateBulkEditForm(slotIndex, { demandFactor: event.target.value })}
                          />
                        </div>
                      </div>
                      <div className="d-flex justify-content-between align-items-center mt-2">
                        <small className="text-secondary">
                          Gefiltert: {listConsumersForSlot.length} von {baseConsumersForSlot.length}
                        </small>
                        <button
                          className="btn btn-sm btn-outline-primary"
                          type="button"
                          onClick={() => handleBulkEditSelection(slotIndex)}
                          disabled={!slot.selectedConsumerIds.length || isSaving}
                        >
                          Auswahl ändern
                        </button>
                      </div>
                    </div>
                    <table className="table table-sm align-middle mb-0">
                      <thead className="table-light">
                        <tr>
                          {renderedColumns.map((column) => (
                            <th key={column.key}>{column.label}</th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {listConsumersForSlot.map((consumer) => (
                          <tr key={consumer.id}>
                            {renderedColumns.map((column) => {
                              switch (column.key) {
                                case "selection":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-check-input"
                                        type="checkbox"
                                        checked={slot.selectedConsumerIds.includes(consumer.id)}
                                        onChange={() => toggleConsumerSelection(slotIndex, consumer.id)}
                                      />
                                    </td>
                                  );
                                case "circuitNumber":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.circuitNumber ?? ""}
                                        onBlur={(event) =>
                                          event.target.value !== (consumer.circuitNumber ?? "")
                                            ? handleInlineUpdateFields(consumer, {
                                                circuitNumber: event.target.value || undefined,
                                              })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "description":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.description ?? consumer.name}
                                        onBlur={(event) =>
                                          event.target.value !== (consumer.description ?? consumer.name)
                                            ? handleInlineUpdateFields(consumer, {
                                                description: event.target.value || undefined,
                                              })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "name":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.name}
                                        onBlur={(event) =>
                                          event.target.value !== consumer.name
                                            ? handleInlineUpdateFields(consumer, { name: event.target.value })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "projectDevice":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.projectDeviceId ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            projectDeviceId: event.target.value || undefined,
                                            isLinkedToDevice: false,
                                          })
                                        }
                                      >
                                        <option value="">Kein Projektgerät</option>
                                        {projectDevices.map((device) => (
                                          <option key={device.id} value={device.id}>
                                            {device.displayName}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "deviceLink":
                                  return (
                                    <td key={column.key}>
                                      <button
                                        className="btn btn-sm btn-outline-secondary"
                                        type="button"
                                        disabled={!consumer.projectDeviceId}
                                        onClick={() =>
                                          handleInlineUpdateFields(consumer, {
                                            isLinkedToDevice: !consumer.isLinkedToDevice,
                                          })
                                        }
                                      >
                                        {consumer.isLinkedToDevice ? "Verknüpft" : "Entkoppelt"}
                                      </button>
                                    </td>
                                  );
                                case "room":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.roomId ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            roomId: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Kein Raum</option>
                                        {rooms.map((room) => (
                                          <option key={room.id} value={room.id}>
                                            {roomLabel(room)}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "floor":
                                  return <td key={column.key}>{consumer.floorName ?? "-"}</td>;
                                case "category":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.category ?? ""}
                                        onBlur={(event) =>
                                          event.target.value !== (consumer.category ?? "")
                                            ? handleInlineUpdateFields(consumer, {
                                                category: event.target.value || undefined,
                                              })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "deviceType":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.deviceType ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            deviceType: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {deviceTypeOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "phaseType":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.phaseType ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            phaseType: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {phaseTypeOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "tradeOrCostGroup":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.tradeOrCostGroup ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            tradeOrCostGroup: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {tradeOrCostGroupOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "group":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.group ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            group: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {consumerGroupOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "protectionType":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.protectionType ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            protectionType: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {protectionTypeOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "protectionRatedCurrent":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        type="number"
                                        min="0"
                                        step="0.1"
                                        defaultValue={consumer.protectionRatedCurrent ?? ""}
                                        onBlur={(event) => {
                                          const raw = event.target.value.trim();
                                          const value = raw ? Number(raw) : undefined;
                                          if (raw === "" && consumer.protectionRatedCurrent !== undefined) {
                                            void handleInlineUpdateFields(consumer, {
                                              protectionRatedCurrent: undefined,
                                            });
                                          } else if (
                                            value !== undefined &&
                                            !Number.isNaN(value) &&
                                            value !== consumer.protectionRatedCurrent
                                          ) {
                                            void handleInlineUpdateFields(consumer, { protectionRatedCurrent: value });
                                          }
                                        }}
                                      />
                                    </td>
                                  );
                                case "protectionCharacteristic":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.protectionCharacteristic ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            protectionCharacteristic: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {protectionCharacteristicOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "cableType":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.cableType ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            cableType: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {cableTypeOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "cableCrossSection":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={consumer.cableCrossSection ?? ""}
                                        onChange={(event) =>
                                          handleInlineUpdateFields(consumer, {
                                            cableCrossSection: event.target.value || undefined,
                                          })
                                        }
                                      >
                                        <option value="">Bitte wählen</option>
                                        {cableCrossSectionOptions.map((value) => (
                                          <option key={value} value={value}>
                                            {value}
                                          </option>
                                        ))}
                                      </select>
                                    </td>
                                  );
                                case "comment":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.comment ?? ""}
                                        onBlur={(event) =>
                                          event.target.value !== (consumer.comment ?? "")
                                            ? handleInlineUpdateFields(consumer, {
                                                comment: event.target.value || undefined,
                                              })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "quantity":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        type="number"
                                        min="0"
                                        defaultValue={consumer.quantity}
                                        onBlur={(event) => {
                                          const value = Number(event.target.value);
                                          if (!Number.isNaN(value) && value !== consumer.quantity) {
                                            void handleInlineUpdateFields(consumer, { quantity: value });
                                          }
                                        }}
                                      />
                                    </td>
                                  );
                                case "installedPowerPerUnitKw":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        type="number"
                                        min="0"
                                        step="0.01"
                                        defaultValue={consumer.installedPowerPerUnitKw}
                                        onBlur={(event) => {
                                          const value = Number(event.target.value);
                                          if (!Number.isNaN(value) && value !== consumer.installedPowerPerUnitKw) {
                                            void handleInlineUpdateFields(consumer, { installedPowerPerUnitKw: value });
                                          }
                                        }}
                                      />
                                    </td>
                                  );
                                case "installedPowerKw":
                                  return <td key={column.key}>{formatNumber(consumer.installedPowerKw)}</td>;
                                case "demandFactor":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        type="number"
                                        min="0"
                                        max="1"
                                        step="0.01"
                                        defaultValue={consumer.demandFactor}
                                        onBlur={(event) => {
                                          const value = Number(event.target.value);
                                          if (!Number.isNaN(value) && value !== consumer.demandFactor) {
                                            void handleInlineUpdateFields(consumer, { demandFactor: value });
                                          }
                                        }}
                                      />
                                    </td>
                                  );
                                case "demandPowerKw":
                                  return <td key={column.key}>{formatNumber(consumer.demandPowerKw)}</td>;
                                case "voltageV":
                                  return <td key={column.key}>{formatNumber(consumer.effectiveVoltageV, 0)}</td>;
                                case "phaseCount":
                                  return (
                                    <td key={column.key}>
                                      <select
                                        className="form-select form-select-sm"
                                        defaultValue={String(consumer.phaseCount ?? 1)}
                                        onChange={(event) => {
                                          const value = event.target.value === "3" ? 3 : 1;
                                          if (value !== consumer.phaseCount) {
                                            void handleInlineUpdateFields(consumer, {
                                              phaseCount: value,
                                              voltageV: consumer.voltageV,
                                            });
                                          }
                                        }}
                                      >
                                        <option value="1">1</option>
                                        <option value="3">3</option>
                                      </select>
                                    </td>
                                  );
                                case "powerFactor":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        type="number"
                                        min="0"
                                        max="1"
                                        step="0.01"
                                        defaultValue={consumer.powerFactor ?? ""}
                                        onBlur={(event) => {
                                          const raw = event.target.value.trim();
                                          const value = raw ? Number(raw) : undefined;
                                          if (raw === "" && consumer.powerFactor !== undefined) {
                                            void handleInlineUpdateFields(consumer, { powerFactor: undefined });
                                          } else if (!Number.isNaN(value) && value !== consumer.powerFactor) {
                                            void handleInlineUpdateFields(consumer, { powerFactor: value });
                                          }
                                        }}
                                      />
                                    </td>
                                  );
                                case "currentA":
                                  return <td key={column.key}>{consumer.currentA?.toFixed(2) ?? "-"}</td>;
                                case "note":
                                  return (
                                    <td key={column.key}>
                                      <input
                                        className="form-control form-control-sm"
                                        defaultValue={consumer.note ?? ""}
                                        onBlur={(event) =>
                                          event.target.value !== (consumer.note ?? "")
                                            ? handleInlineUpdateFields(consumer, { note: event.target.value || undefined })
                                            : undefined
                                        }
                                      />
                                    </td>
                                  );
                                case "actions":
                                  return (
                                    <td key={column.key} className="text-nowrap">
                                      <div className="btn-group btn-group-sm">
                                        {slots.slice(0, activeListCount).map((_, targetSlotIndex) => (
                                          <button
                                            key={targetSlotIndex}
                                            className="btn btn-outline-secondary"
                                            type="button"
                                            title={`Nach Liste ${targetSlotIndex + 1} kopieren`}
                                            onClick={() => handleCopyToSlot(consumer, targetSlotIndex)}
                                            disabled={
                                              targetSlotIndex === slotIndex ||
                                              !slots[targetSlotIndex].boardId ||
                                              isSaving
                                            }
                                          >
                                            L{targetSlotIndex + 1}
                                          </button>
                                        ))}
                                        <button
                                          className="btn btn-outline-secondary"
                                          type="button"
                                          onClick={() => handleDuplicateInSameList(consumer)}
                                          disabled={isSaving}
                                          title="In derselben Liste duplizieren"
                                        >
                                          Dupl.
                                        </button>
                                        <button
                                          className="btn btn-outline-danger"
                                          type="button"
                                          onClick={() => handleDeleteConsumer(consumer.id)}
                                          disabled={isSaving}
                                        >
                                          X
                                        </button>
                                      </div>
                                    </td>
                                  );
                                default:
                                  return null;
                              }
                            })}
                          </tr>
                        ))}
                        {!listConsumersForSlot.length ? (
                          <tr>
                            <td colSpan={renderedColumns.length} className="text-center text-secondary py-3">
                              Keine Einträge für {slot.boardId ? boardById.get(slot.boardId)?.name : "diese Liste"}.
                            </td>
                          </tr>
                        ) : null}
                      </tbody>
                    </table>
                  </div>

                  <div className="d-flex justify-content-between align-items-center">
                    <small className="text-secondary">Ausgewählt: {slot.selectedConsumerIds.length}</small>
                    <div className="btn-group btn-group-sm">
                      {slots.slice(0, activeListCount).map((_, targetSlotIndex) => (
                        <button
                          key={`bulk-${targetSlotIndex}`}
                          className="btn btn-outline-primary"
                          type="button"
                          onClick={() => handleCopySelectionToSlot(slotIndex, targetSlotIndex)}
                          disabled={
                            targetSlotIndex === slotIndex ||
                            !slots[targetSlotIndex].boardId ||
                            !slot.selectedConsumerIds.length ||
                            isSaving
                          }
                          title={`Auswahl nach Liste ${targetSlotIndex + 1} kopieren`}
                        >
                          Auswahl → L{targetSlotIndex + 1}
                        </button>
                      ))}
                    </div>
                  </div>
                </div>
              </div>
            </section>
          );
        })}
      </div>
    </main>
  );
}


