import { useEffect, useMemo, useRef, useState } from 'react';
import { Avatar } from 'primereact/avatar';
import { Badge } from 'primereact/badge';
import { Button } from 'primereact/button';
import { Card } from 'primereact/card';
import { DataView } from 'primereact/dataview';
import { Dialog } from 'primereact/dialog';
import { Divider } from 'primereact/divider';
import { Dropdown } from 'primereact/dropdown';
import { InputSwitch } from 'primereact/inputswitch';
import { InputNumber } from 'primereact/inputnumber';
import { InputText } from 'primereact/inputtext';
import { Message } from 'primereact/message';
import { ProgressBar } from 'primereact/progressbar';
import { Steps } from 'primereact/steps';
import { Tag } from 'primereact/tag';
import { Toolbar } from 'primereact/toolbar';

const statusConfig = {
  healthy: { label: 'Healthy', severity: 'success' },
  warning: { label: 'Healthy', severity: 'success' },
  critical: { label: 'Critical', severity: 'danger' }
};

const serverTypes = [
  { label: 'Proxmox', value: 'proxmox' },
  { label: 'TrueNAS SCALE', value: 'truenas' },
  { label: 'Proxmox Backup Server', value: 'pbs' }
];

const schemeOptions = [
  { label: 'https', value: 'https' },
  { label: 'http', value: 'http' }
];

const initialDraft = {
  name: '',
  host: '',
  port: null
};

const initialConfig = {
  type: 'proxmox',
  apiTokenId: '',
  apiTokenSecret: '',
  apiKey: '',
  scheme: 'https',
  allowInsecure: true
};

const usageClass = (percent) => {
  if (percent >= 85) {
    return 'usage-high';
  }
  if (percent >= 65) {
    return 'usage-mid';
  }
  return 'usage-low';
};

const getCapacityBase = (server) => {
  const platform = String(server?.platform || server?.type || '').toLowerCase();
  return platform.includes('truenas') ? 1024 : 1000;
};

const toBytes = (valueTb, base) => (valueTb ?? 0) * (base ** 4);

const formatCapacity = (bytes, base, fixedDecimals = false) => {
  const safeBytes = bytes ?? 0;
  const digits = fixedDecimals ? 2 : 1;
  const formatOptions = { minimumFractionDigits: digits, maximumFractionDigits: digits };
  const tbDivisor = base ** 4;
  const gbDivisor = base ** 3;
  const useGb = Math.abs(safeBytes) < tbDivisor;
  const value = safeBytes / (useGb ? gbDivisor : tbDivisor);
  const unit = useGb
    ? (base === 1024 ? 'GB' : 'GB')
    : (base === 1024 ? 'TB' : 'TB');

  return `${new Intl.NumberFormat('en-US', formatOptions).format(value)} ${unit}`;
};

const getPlatformMeta = (server) => {
  const raw = String(server?.platform || server?.type || '').toLowerCase();
  if (raw.includes('backup')) {
    return { label: 'Proxmox Backup Server', short: 'B', tone: 'pbs', icon: 'pi pi-cloud-upload' };
  }
  if (raw.includes('proxmox')) {
    return { label: 'Proxmox Virtual Environment', short: 'P', tone: 'proxmox', icon: 'pi pi-server' };
  }
  return { label: 'TrueNAS SCALE', short: 'T', tone: 'truenas', icon: 'pi pi-database' };
};

export default function App() {
  const [servers, setServers] = useState([]);
  const [dataSource, setDataSource] = useState('empty');
  const [lastUpdated, setLastUpdated] = useState(new Date().toISOString());
  const [errors, setErrors] = useState([]);
  const [wizardOpen, setWizardOpen] = useState(false);
  const [wizardStep, setWizardStep] = useState(0);
  const [draft, setDraft] = useState(initialDraft);
  const [config, setConfig] = useState(initialConfig);
  const [detectedType, setDetectedType] = useState('proxmox');
  const [serverId, setServerId] = useState(null);
  const [wizardError, setWizardError] = useState('');
  const [isSaving, setIsSaving] = useState(false);
  const [fixedDecimals, setFixedDecimals] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);
  const [editName, setEditName] = useState('');
  const [activeServer, setActiveServer] = useState(null);
  const [reorderMode, setReorderMode] = useState(false);
  const [draggingId, setDraggingId] = useState(null);
  const [dragOverId, setDragOverId] = useState(null);
  const [resizingId, setResizingId] = useState(null);
  const [maxColumns, setMaxColumns] = useState(4);
  const gridRef = useRef(null);
  const [showSettingsSheet, setShowSettingsSheet] = useState(false);
  const [alertsConfig, setAlertsConfig] = useState(null);
  const [alertsSaving, setAlertsSaving] = useState(false);
  const [alertsError, setAlertsError] = useState('');
  const [alertsTestState, setAlertsTestState] = useState('idle');
  const [serverAlertsOpen, setServerAlertsOpen] = useState(false);
  const [serverAlertsServer, setServerAlertsServer] = useState(null);
  const [serverAlertsDraft, setServerAlertsDraft] = useState(null);

  useEffect(() => {
    const resolveColumns = () => {
      const width = window.innerWidth;
      if (width <= 900) {
        return 1;
      }
      if (width <= 1200) {
        return 2;
      }
      return 4;
    };
    const updateColumns = () => setMaxColumns(resolveColumns());
    updateColumns();
    window.addEventListener('resize', updateColumns);
    return () => window.removeEventListener('resize', updateColumns);
  }, []);

  useEffect(() => {
    if (!reorderMode) {
      setDraggingId(null);
      setDragOverId(null);
      setResizingId(null);
    }
  }, [reorderMode]);

  const loadStorage = async () => {
    try {
      const response = await fetch('/api/storage');
      if (!response.ok) {
        throw new Error('Backend unreachable');
      }
      const data = await response.json();
      const nextServers = Array.isArray(data?.servers) ? data.servers : [];
      const nextErrors = Array.isArray(data?.errors) ? data.errors : [];
      nextServers.sort((a, b) => {
        const aPos = Number.isFinite(a.position) ? a.position : 0;
        const bPos = Number.isFinite(b.position) ? b.position : 0;
        return aPos - bPos;
      });
      setServers(nextServers);
      setErrors(nextErrors);
      setDataSource(data?.source || 'live');
      setLastUpdated(data?.generatedAt || new Date().toISOString());
    } catch (error) {
      setServers([]);
      setErrors([{ message: error.message || 'Backend unreachable.' }]);
      setDataSource('error');
      setLastUpdated(new Date().toISOString());
    }
  };

  const loadAlerts = async () => {
    try {
      const response = await fetch('/api/alerts');
      if (!response.ok) {
        throw new Error('Alerts config could not be loaded.');
      }
      const data = await response.json();
      setAlertsConfig(data?.alerts || null);
      setAlertsError('');
    } catch (error) {
      setAlertsError(error.message || 'Alerts config could not be loaded.');
    }
  };

  useEffect(() => {
    loadStorage();
    loadAlerts();
  }, []);

  const totals = useMemo(() => {
    const bases = new Set(servers.map(getCapacityBase));
    const summaryBase = bases.size === 1 ? Array.from(bases)[0] : 1000;

    const totalBytes = servers.reduce((sum, server) => {
      const base = getCapacityBase(server);
      const value = Number(server.totalBytes);
      if (Number.isFinite(value)) {
        return sum + value;
      }
      return sum + toBytes(server.totalTb ?? 0, base);
    }, 0);

    const usedBytes = servers.reduce((sum, server) => {
      const base = getCapacityBase(server);
      const value = Number(server.usedBytes);
      if (Number.isFinite(value)) {
        return sum + value;
      }
      return sum + toBytes(server.usedTb ?? 0, base);
    }, 0);

    const percent = totalBytes === 0 ? 0 : Math.round((usedBytes / totalBytes) * 100);


    return {
      totalBytes,
      usedBytes,
      freeBytes: totalBytes - usedBytes,
      percent,
      unitBase: summaryBase
    };
  }, [servers]);

  const lastUpdateLabel = new Date(lastUpdated).toLocaleString('de-DE', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  });

  const summaryCards = [
    {
      title: 'Gesamter Speicher',
      icon: 'pi pi-database',
      render: () => (
        <div className="summary-overview">
          <div className="summary-overview-row">
            <span className="summary-overview-label">Last update</span>
            <span className="summary-overview-value">{lastUpdateLabel}</span>
          </div>
          <div className="summary-overview-row">
            <span className="summary-overview-label">Servers</span>
            <span className="summary-overview-value">{servers.length}</span>
          </div>
          <div className="summary-overview-row">
            <span className="summary-overview-label">Total</span>
            <span className="summary-overview-value">{formatCapacity(totals.totalBytes, totals.unitBase, fixedDecimals)}</span>
          </div>
          <div className="summary-overview-row">
            <span className="summary-overview-label">Used</span>
            <span className="summary-overview-value">{formatCapacity(totals.usedBytes, totals.unitBase, fixedDecimals)}</span>
          </div>
          <div className="summary-overview-row">
            <span className="summary-overview-label">Free</span>
            <span className="summary-overview-value">{formatCapacity(totals.freeBytes, totals.unitBase, fixedDecimals)}</span>
          </div>
          <div
            className="summary-progress-track"
            style={{ '--progress': `${Math.min(100, Math.max(0, totals.percent))}%` }}
          >
            <ProgressBar value={totals.percent} showValue={false} className={`summary-progress usage-bar ${usageClass(totals.percent)}`} />
            {totals.percent > 0 ? (
              <span className="summary-progress-label">{totals.percent}%</span>
            ) : null}
            <span className="summary-progress-start">0%</span>
            <span className="summary-progress-end">100%</span>
          </div>
        </div>
      )
    }
  ];

  const setPoolsCollapsed = async (serverId, collapsed) => {
    try {
      const response = await fetch(`/api/servers/${serverId}/pools-collapsed`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ collapsed })
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to update pools.');
      }
    } catch (error) {
      setErrors((prev) => [...prev, { message: error.message || 'Failed to update pools.' }]);
    }
  };

  const togglePools = (server) => {
    const collapsed = !server.poolsCollapsed;
    setServers((prev) => prev.map((item) => (
      item.id === server.id ? { ...item, poolsCollapsed: collapsed } : item
    )));
    setPoolsCollapsed(server.id, collapsed);
  };

  const openEditServer = (server) => {
    setActiveServer(server);
    setEditName(server.name || '');
    setEditOpen(true);
  };

  const openDeleteServer = (server) => {
    setActiveServer(server);
    setDeleteOpen(true);
  };

  const handleSaveServerName = async () => {
    if (!activeServer) {
      return;
    }
    const nextName = editName.trim() || activeServer.host || activeServer.name || '';
    setServers((prev) => prev.map((item) => (
      item.id === activeServer.id ? { ...item, name: nextName } : item
    )));
    try {
      const response = await fetch(`/api/servers/${activeServer.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: editName })
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to update server.');
      }
      setEditOpen(false);
      setActiveServer(null);
      await loadStorage();
    } catch (error) {
      await loadStorage();
      setErrors((prev) => [...prev, { message: error.message || 'Failed to update server.' }]);
    }
  };

  const handleDeleteServer = async () => {
    if (!activeServer) {
      return;
    }
    try {
      const response = await fetch(`/api/servers/${activeServer.id}`, {
        method: 'DELETE'
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to delete server.');
      }
      await loadStorage();
      setDeleteOpen(false);
      setActiveServer(null);
    } catch (error) {
      setErrors((prev) => [...prev, { message: error.message || 'Failed to delete server.' }]);
    }
  };

  const serverTemplate = (server) => {
    const base = getCapacityBase(server);
    const totalBytes = Number(server.totalBytes);
    const usedBytes = Number(server.usedBytes);
    const fallbackTotal = Number.isFinite(totalBytes) ? totalBytes : toBytes(server.totalTb ?? 0, base);
    const fallbackUsed = Number.isFinite(usedBytes) ? usedBytes : toBytes(server.usedTb ?? 0, base);
    const status = statusConfig[server.status] || { label: 'Unknown', severity: 'info' };
    const platform = getPlatformMeta(server);

    const pools = Array.isArray(server.pools) && server.pools.length > 0
      ? server.pools
      : [{ name: server.pool || 'Pool', totalBytes: fallbackTotal, usedBytes: fallbackUsed }];

    const serverTotal = pools.reduce((sum, pool) => {
      const value = Number(pool.totalBytes);
      if (Number.isFinite(value)) {
        return sum + value;
      }
      return sum + toBytes(pool.totalTb ?? 0, base);
    }, 0);
    const serverUsed = pools.reduce((sum, pool) => {
      const value = Number(pool.usedBytes);
      if (Number.isFinite(value)) {
        return sum + value;
      }
      return sum + toBytes(pool.usedTb ?? 0, base);
    }, 0);
    const serverPercent = serverTotal ? Math.round((serverUsed / serverTotal) * 100) : 0;

    return (
      <Card className="server-card" title={
        <div className="server-title">
          <Avatar
            icon={platform.icon}
            shape="circle"
            className={`platform-avatar ${platform.tone}`}
          />
          <div className="server-name">
            <span className="server-id">{server.name || server.host}</span>
            <span className="server-cluster">{server.cluster || 'Vault Cluster'}</span>
          </div>
          <div className="server-actions">
            <Button
              icon="pi pi-pencil"
              className="p-button-text server-action"
              onClick={() => openEditServer(server)}
              aria-label="Server umbenennen"
            />
            <Button
              icon="pi pi-trash"
              className="p-button-text p-button-danger server-action"
              onClick={() => openDeleteServer(server)}
              aria-label="Server loeschen"
            />
          </div>
        </div>
      } subTitle={`${server.location || 'Rack ?'}`}>
        <div className="server-tags">
          <Tag value={platform.label} severity="info" className={`platform-tag ${platform.tone}`} />
          <Tag value={status.label} severity={status.severity} />
        </div>
        <Divider />
        <div className="server-aggregate">
          <div className="pool-header">
            <span className="pool-name">Gesamt</span>
            <span className="pool-numbers">{formatCapacity(serverUsed, base, fixedDecimals)} / {formatCapacity(serverTotal, base, fixedDecimals)}</span>
          </div>
          <ProgressBar value={serverPercent} showValue={false} className={`usage-bar ${usageClass(serverPercent)}`} />
          <Button
            type="button"
            className="p-button-text pool-toggle"
            icon={server.poolsCollapsed ? 'pi pi-angle-down' : 'pi pi-angle-up'}
            label={server.poolsCollapsed ? 'Pools anzeigen' : 'Pools ausblenden'}
            onClick={() => togglePools(server)}
          />
        </div>
        {!server.poolsCollapsed ? (
          <div className="pool-list">
            {pools.map((pool) => {
              const poolTotal = Number.isFinite(Number(pool.totalBytes))
                ? Number(pool.totalBytes)
                : toBytes(pool.totalTb ?? 0, base);
              const poolUsed = Number.isFinite(Number(pool.usedBytes))
                ? Number(pool.usedBytes)
                : toBytes(pool.usedTb ?? 0, base);
              const poolPercent = poolTotal ? Math.round((poolUsed / poolTotal) * 100) : 0;

              return (
                <div key={pool.name} className="pool-row">
                  <div className="pool-header">
                    <span className="pool-name">{pool.name}</span>
                    <span className="pool-numbers">{formatCapacity(poolUsed, base, fixedDecimals)} / {formatCapacity(poolTotal, base, fixedDecimals)}</span>
                  </div>
                  <ProgressBar value={poolPercent} showValue={false} className={`usage-bar ${usageClass(poolPercent)}`} />
                </div>
              );
            })}
          </div>
        ) : null}
        {reorderMode ? (
          <div
            className="resize-handle"
            role="presentation"
            onMouseDown={(event) => handleResizeStart(event, server)}
          />
        ) : null}
      </Card>
    );
  };

  const reorderServers = (list, sourceId, targetId) => {
    const fromIndex = list.findIndex((item) => item.id === sourceId);
    const toIndex = list.findIndex((item) => item.id === targetId);
    if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) {
      return list;
    }
    const next = [...list];
    const [moved] = next.splice(fromIndex, 1);
    next.splice(toIndex, 0, moved);
    return next;
  };

  const persistLayout = async ({ order, sizes }) => {
    try {
      const response = await fetch('/api/servers/order', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ order, sizes })
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to save server layout.');
      }
    } catch (error) {
      setErrors((prev) => [...prev, { message: error.message || 'Failed to save server layout.' }]);
    }
  };

  const handleDragStart = (event, server) => {
    if (!reorderMode) {
      return;
    }
    setDraggingId(server.id);
    event.dataTransfer.effectAllowed = 'move';
    event.dataTransfer.setData('text/plain', server.id);
  };

  const handleDragOver = (event, server) => {
    if (!reorderMode) {
      return;
    }
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
    setDragOverId(server.id);
  };

  const handleDragLeave = (server) => {
    if (dragOverId === server.id) {
      setDragOverId(null);
    }
  };

  const handleDrop = (event, server) => {
    if (!reorderMode) {
      return;
    }
    event.preventDefault();
    const sourceId = draggingId || event.dataTransfer.getData('text/plain');
    if (!sourceId || sourceId === server.id) {
      setDragOverId(null);
      return;
    }
    setServers((prev) => {
      const next = reorderServers(prev, sourceId, server.id);
      if (next !== prev) {
        persistLayout({ order: next.map((item) => item.id) });
      }
      return next;
    });
    setDragOverId(null);
    setDraggingId(null);
  };

  const clampSpan = (value, max) => {
    const parsed = Number(value);
    if (!Number.isFinite(parsed)) {
      return 1;
    }
    return Math.min(max, Math.max(1, Math.round(parsed)));
  };

  const handleResizeStart = (event, server) => {
    if (!reorderMode) {
      return;
    }
    event.preventDefault();
    event.stopPropagation();
    setResizingId(server.id);

    const container = gridRef.current;
    const containerWidth = container?.getBoundingClientRect().width || 1;
    const columns = maxColumns;
    const stepWidth = containerWidth / Math.max(1, columns);
    const startSpan = clampSpan(server.span ?? 1, columns);
    const startX = event.clientX;
    let nextSpan = startSpan;

    const handleMove = (moveEvent) => {
      const delta = moveEvent.clientX - startX;
      const steps = Math.round(delta / stepWidth);
      const proposed = clampSpan(startSpan + steps, columns);
      if (proposed === nextSpan) {
        return;
      }
      nextSpan = proposed;
      setServers((prev) => prev.map((item) => (
        item.id === server.id ? { ...item, span: nextSpan } : item
      )));
    };

    const handleUp = () => {
      document.removeEventListener('mousemove', handleMove);
      document.removeEventListener('mouseup', handleUp);
      setResizingId(null);
      setDragOverId(null);
      persistLayout({ sizes: [{ id: server.id, span: nextSpan }] });
    };

    document.addEventListener('mousemove', handleMove);
    document.addEventListener('mouseup', handleUp);
  };

  const listTemplate = (items) => {
    if (!items || items.length === 0) {
      return <div className="server-grid-empty">Keine Server konfiguriert.</div>;
    }

    return (
      <div className="server-grid-inner" ref={gridRef}>
        {items.map((server) => (
          <div
            key={server.id || server.name}
            className={`server-grid-item ${reorderMode ? 'is-draggable' : ''} ${draggingId === server.id ? 'is-dragging' : ''} ${dragOverId === server.id ? 'is-drop-target' : ''} ${resizingId === server.id ? 'is-resizing' : ''}`}
            draggable={reorderMode}
            onDragStart={(event) => handleDragStart(event, server)}
            onDragOver={(event) => handleDragOver(event, server)}
            onDragLeave={() => handleDragLeave(server)}
            onDrop={(event) => handleDrop(event, server)}
            style={{ gridColumn: `span ${clampSpan(server.span ?? 1, maxColumns)}` }}
          >
            {serverTemplate(server)}
          </div>
        ))}
      </div>
    );
  };

  const resetWizard = () => {
    setWizardStep(0);
    setDraft(initialDraft);
    setConfig(initialConfig);
    setDetectedType('proxmox');
    setServerId(null);
    setWizardError('');
    setIsSaving(false);
  };

  const handleOpenWizard = () => {
    resetWizard();
    setWizardOpen(true);
  };

  const handleCloseWizard = () => {
    setWizardOpen(false);
    resetWizard();
  };

  const handleDetectType = async () => {
    setWizardError('');
    setIsSaving(true);
    try {
      const response = await fetch('/api/servers', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: draft.name,
          host: draft.host,
          port: draft.port
        })
      });

      if (!response.ok) {
        const payload = await response.json().catch(() => ({}));
        throw new Error(payload.error || 'Failed to create server.');
      }

      const payload = await response.json();
      const detected = payload.detectedType || 'proxmox';
      setServerId(payload.id);
      setDetectedType(detected);
      setConfig((prev) => ({ ...prev, type: detected }));
      setWizardStep(1);
    } catch (error) {
      setWizardError(error.message || 'Failed to create server.');
    } finally {
      setIsSaving(false);
    }
  };

  const handleSaveConfig = async () => {
    setWizardError('');
    setIsSaving(true);
    try {
      const payload = {
        type: config.type,
        config: {
          scheme: config.scheme,
          allowInsecure: config.allowInsecure,
          ...(config.type === 'truenas'
            ? { apiKey: config.apiKey }
            : { apiTokenId: config.apiTokenId, apiTokenSecret: config.apiTokenSecret })
        }
      };

      const response = await fetch(`/api/servers/${serverId}/config`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });

      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Failed to save config.');
      }

      await loadStorage();
      handleCloseWizard();
    } catch (error) {
      setWizardError(error.message || 'Failed to save config.');
    } finally {
      setIsSaving(false);
    }
  };

  const mergeAlerts = (base, override) => ({
    enabled: override?.enabled ?? base?.enabled ?? true,
    warnPercent: override?.warnPercent ?? base?.warnPercent ?? 80,
    critPercent: override?.critPercent ?? base?.critPercent ?? 90,
    cooldownMinutes: override?.cooldownMinutes ?? base?.cooldownMinutes ?? 60,
    once: override?.once ?? base?.once ?? false,
    includePools: override?.includePools ?? base?.includePools ?? true
  });

  const openServerAlerts = (server) => {
    const base = alertsConfig?.defaults || null;
    setServerAlertsServer(server);
    setServerAlertsDraft(mergeAlerts(base, server.alerts));
    setServerAlertsOpen(true);
  };

  const handleSaveAlerts = async () => {
    if (!alertsConfig) {
      return;
    }
    setAlertsSaving(true);
    setAlertsError('');
    try {
      const payload = {
        enabled: alertsConfig.enabled,
        pushover: {
          userKey: alertsConfig?.pushover?.userKey || '',
          apiToken: alertsConfig?.pushover?.apiToken || ''
        },
        defaults: {
          enabled: alertsConfig?.defaults?.enabled ?? true,
          warnPercent: alertsConfig?.defaults?.warnPercent ?? 80,
          critPercent: alertsConfig?.defaults?.critPercent ?? 90,
          cooldownMinutes: alertsConfig?.defaults?.cooldownMinutes ?? 60,
          once: alertsConfig?.defaults?.once ?? false,
          includePools: alertsConfig?.defaults?.includePools ?? true
        }
      };
      const response = await fetch('/api/alerts', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Alerts konnten nicht gespeichert werden.');
      }
      await loadAlerts();
    } catch (error) {
      setAlertsError(error.message || 'Alerts konnten nicht gespeichert werden.');
    } finally {
      setAlertsSaving(false);
    }
  };

  const handleTestAlert = async () => {
    setAlertsTestState('loading');
    setAlertsError('');
    try {
      const response = await fetch('/api/alerts/test', { method: 'POST' });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Test-Alert fehlgeschlagen.');
      }
      setAlertsTestState('success');
      window.setTimeout(() => setAlertsTestState('idle'), 2000);
    } catch (error) {
      setAlertsTestState('error');
      setAlertsError(error.message || 'Test-Alert fehlgeschlagen.');
    }
  };

  const handleSaveServerAlerts = async () => {
    if (!serverAlertsServer || !serverAlertsDraft) {
      return;
    }
    try {
      const response = await fetch(`/api/servers/${serverAlertsServer.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ alerts: serverAlertsDraft })
      });
      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || 'Server-Alerts konnten nicht gespeichert werden.');
      }
      setServerAlertsOpen(false);
      setServerAlertsServer(null);
      setServerAlertsDraft(null);
      await loadStorage();
    } catch (error) {
      setErrors((prev) => [...prev, { message: error.message || 'Server-Alerts konnten nicht gespeichert werden.' }]);
    }
  };

  const sourceMeta = {
    live: { label: 'Live', severity: 'success' },
    empty: { label: 'Leer', severity: 'warning' },
    error: { label: 'Fehler', severity: 'danger' }
  };
  const sourceBadge = sourceMeta[dataSource] || sourceMeta.empty;

  const toolbarLeft = (
    <div className="brand-block">
      <Avatar label="V" shape="circle" className="brand-avatar" />
      <div className="brand-text">
        <span className="brand-title">Vault</span>
        <span className="brand-sub">Proxmox + PBS + TrueNAS Ueberblick</span>
      </div>
      <Tag value={sourceBadge.label} severity={sourceBadge.severity} />
    </div>
  );

  const toolbarRight = (
    <div className="toolbar-actions">
      <div className="toolbar-toggle">
        <span>Bearbeiten</span>
        <InputSwitch checked={reorderMode} onChange={(event) => setReorderMode(Boolean(event.value))} />
      </div>
      <div className="toolbar-toggle">
        <span>2 Dezimalstellen</span>
        <InputSwitch checked={fixedDecimals} onChange={(event) => setFixedDecimals(Boolean(event.value))} />
      </div>
      <Button label="Refresh" icon="pi pi-sync" className="p-button-text" onClick={loadStorage} />
      <Button label="Settings" icon="pi pi-cog" className="p-button-text" onClick={() => setShowSettingsSheet(true)} />
      <Button label="Server anlegen" icon="pi pi-plus" severity="secondary" onClick={handleOpenWizard} />
    </div>
  );

  const canContinue = Boolean(draft.host);
  const canSave = config.type === 'truenas'
    ? Boolean(config.apiKey)
    : Boolean(config.apiTokenId && config.apiTokenSecret);
  const steps = [
    { label: 'Basis' },
    { label: 'Typ & Zugang' }
  ];

  return (
    <div className="app-shell">
      <Toolbar left={toolbarLeft} right={toolbarRight} className="app-toolbar" />
      <div className="app-content">
        <div className="summary-grid">
          {summaryCards.map((card) => (
            <Card key={card.title} className="summary-card" title={card.render ? null : card.title}>
              {card.render ? (
                <>
                  <div className="summary-top summary-top-title">
                    <i className={`summary-icon ${card.icon}`} />
                    <span className="summary-title">{card.title}</span>
                  </div>
                  {card.render()}
                </>
              ) : (
                <>
                  <div className="summary-top">
                    <i className={`summary-icon ${card.icon}`} />
                    <span className="summary-value">{card.value}</span>
                  </div>
                  <span className="summary-detail">{card.detail}</span>
                </>
              )}
            </Card>
          ))}
        </div>

        {dataSource === 'empty' ? (
          <Message severity="info" text="Keine Server konfiguriert. Bitte einen Server anlegen." className="status-message" />
        ) : null}

        {errors.length > 0 ? (
          <div className="error-stack">
            {errors.map((error, index) => (
              <Message
                key={error.id || `${error.name}-${index}`}
                severity="error"
                text={`${error.name || 'Server'}: ${error.message || 'Fehler beim Laden.'}`}
              />
            ))}
          </div>
        ) : null}


        <Card className="servers-card" title="Server" subTitle="Speicherkapazitäten der Server">
          <DataView value={servers} layout="grid" listTemplate={listTemplate} className="server-grid" />
        </Card>
      </div>

      <nav className="bottom-nav">
        <Button className="bottom-action" onClick={handleOpenWizard}>
          <span className="nav-icon">
            <i className="pi pi-plus" />
          </span>
          <span>Server</span>
        </Button>
        <Button className="bottom-action" onClick={() => setShowSettingsSheet(true)}>
          <span className="nav-icon">
            <i className="pi pi-cog" />
          </span>
          <span>Settings</span>
        </Button>
      </nav>

      {showSettingsSheet ? (
        <div className="sheet-backdrop" onClick={() => setShowSettingsSheet(false)}>
          <div className="sheet-card" onClick={(event) => event.stopPropagation()}>
            <div className="sheet-header">
              <strong>Settings</strong>
              <Button
                className="icon-button"
                icon="pi pi-times"
                onClick={() => setShowSettingsSheet(false)}
                aria-label="Schliessen"
              />
            </div>
            <div className="drawer-system">
              <Button label="Refresh" icon="pi pi-sync" className="p-button-text" onClick={loadStorage} />
              <div className="toolbar-toggle">
                <span>2 Dezimalstellen</span>
                <InputSwitch checked={fixedDecimals} onChange={(event) => setFixedDecimals(Boolean(event.value))} />
              </div>
              <Divider />
              <div className="drawer-section">
                <div className="drawer-section-title">Alerts (Pushover)</div>
                {alertsError ? <Message severity="error" text={alertsError} /> : null}
                {alertsConfig ? (
                  <div className="form-grid drawer-form">
                    <div className="form-field">
                      <label htmlFor="alerts-enabled">Alerts global aktiv</label>
                      <InputSwitch
                        id="alerts-enabled"
                        checked={Boolean(alertsConfig.enabled)}
                        onChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          enabled: Boolean(event.value)
                        }))}
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-user-key">Pushover User Key</label>
                      <InputText
                        id="alerts-user-key"
                        value={alertsConfig?.pushover?.userKey || ''}
                        onChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          pushover: { ...(prev?.pushover || {}), userKey: event.target.value }
                        }))}
                        placeholder="uQiRzpo4DXghDmr9QzzfQu27cmVRsG"
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-api-token">Pushover API Token</label>
                      <InputText
                        id="alerts-api-token"
                        type="password"
                        value={alertsConfig?.pushover?.apiToken || ''}
                        onChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          pushover: { ...(prev?.pushover || {}), apiToken: event.target.value }
                        }))}
                        placeholder="a1b2c3d4e5f6g7h8i9"
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-warn">Warnung ab %</label>
                      <InputNumber
                        id="alerts-warn"
                        value={alertsConfig?.defaults?.warnPercent ?? 80}
                        onValueChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          defaults: { ...(prev?.defaults || {}), warnPercent: event.value ?? 0 }
                        }))}
                        min={1}
                        max={99}
                        useGrouping={false}
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-crit">Kritisch ab %</label>
                      <InputNumber
                        id="alerts-crit"
                        value={alertsConfig?.defaults?.critPercent ?? 90}
                        onValueChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          defaults: { ...(prev?.defaults || {}), critPercent: event.value ?? 0 }
                        }))}
                        min={2}
                        max={100}
                        useGrouping={false}
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-cooldown">Cooldown (Minuten)</label>
                      <InputNumber
                        id="alerts-cooldown"
                        value={alertsConfig?.defaults?.cooldownMinutes ?? 60}
                        onValueChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          defaults: { ...(prev?.defaults || {}), cooldownMinutes: event.value ?? 0 }
                        }))}
                        min={0}
                        max={525600}
                        useGrouping={false}
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-once">Nur einmal (bis Entwarnung)</label>
                      <InputSwitch
                        id="alerts-once"
                        checked={Boolean(alertsConfig?.defaults?.once)}
                        onChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          defaults: { ...(prev?.defaults || {}), once: Boolean(event.value) }
                        }))}
                      />
                    </div>
                    <div className="form-field">
                      <label htmlFor="alerts-pools">Pools mit pruefen</label>
                      <InputSwitch
                        id="alerts-pools"
                        checked={alertsConfig?.defaults?.includePools !== false}
                        onChange={(event) => setAlertsConfig((prev) => ({
                          ...prev,
                          defaults: { ...(prev?.defaults || {}), includePools: Boolean(event.value) }
                        }))}
                      />
                    </div>
                    <div className="form-actions drawer-actions">
                      <Button
                        label={alertsSaving ? 'Speichern...' : 'Speichern'}
                        icon="pi pi-save"
                        onClick={handleSaveAlerts}
                        disabled={alertsSaving}
                      />
                      <Button
                        label={alertsTestState === 'loading' ? 'Teste...' : alertsTestState === 'success' ? 'Gesendet' : 'Test-Alert'}
                        icon="pi pi-send"
                        className="p-button-text"
                        onClick={handleTestAlert}
                        disabled={alertsSaving || alertsTestState === 'loading'}
                      />
                    </div>
                  </div>
                ) : (
                  <div className="drawer-hint">Alerts werden geladen...</div>
                )}
              </div>
              <Divider />
              <div className="drawer-section">
                <div className="drawer-section-title">Server Overrides</div>
                <div className="drawer-list">
                  {servers.map((server) => (
                    <div key={server.id} className="drawer-list-item">
                      <div className="drawer-list-label">{server.name || server.host}</div>
                      <Button
                        label="Alerts"
                        icon="pi pi-bell"
                        className="p-button-text"
                        onClick={() => openServerAlerts(server)}
                      />
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>
      ) : null}

      <Dialog
        header={`Alerts: ${serverAlertsServer?.name || serverAlertsServer?.host || 'Server'}`}
        visible={serverAlertsOpen}
        onHide={() => setServerAlertsOpen(false)}
        className="wizard-dialog"
        draggable={false}
      >
        {serverAlertsDraft ? (
          <>
            <div className="form-grid">
              <div className="form-field">
                <label htmlFor="server-alerts-enabled">Alerts fuer diesen Server</label>
                <InputSwitch
                  id="server-alerts-enabled"
                  checked={Boolean(serverAlertsDraft.enabled)}
                  onChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    enabled: Boolean(event.value)
                  }))}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-alerts-warn">Warnung ab %</label>
                <InputNumber
                  id="server-alerts-warn"
                  value={serverAlertsDraft.warnPercent}
                  onValueChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    warnPercent: event.value ?? prev.warnPercent
                  }))}
                  min={1}
                  max={99}
                  useGrouping={false}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-alerts-crit">Kritisch ab %</label>
                <InputNumber
                  id="server-alerts-crit"
                  value={serverAlertsDraft.critPercent}
                  onValueChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    critPercent: event.value ?? prev.critPercent
                  }))}
                  min={2}
                  max={100}
                  useGrouping={false}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-alerts-cooldown">Cooldown (Minuten)</label>
                <InputNumber
                  id="server-alerts-cooldown"
                  value={serverAlertsDraft.cooldownMinutes}
                  onValueChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    cooldownMinutes: event.value ?? prev.cooldownMinutes
                  }))}
                  min={0}
                  max={525600}
                  useGrouping={false}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-alerts-once">Nur einmal</label>
                <InputSwitch
                  id="server-alerts-once"
                  checked={Boolean(serverAlertsDraft.once)}
                  onChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    once: Boolean(event.value)
                  }))}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-alerts-pools">Pools mit pruefen</label>
                <InputSwitch
                  id="server-alerts-pools"
                  checked={serverAlertsDraft.includePools !== false}
                  onChange={(event) => setServerAlertsDraft((prev) => ({
                    ...prev,
                    includePools: Boolean(event.value)
                  }))}
                />
              </div>
            </div>
            <div className="form-actions">
              <Button label="Abbrechen" className="p-button-text" onClick={() => setServerAlertsOpen(false)} />
              <Button label="Speichern" icon="pi pi-check" onClick={handleSaveServerAlerts} />
            </div>
          </>
        ) : (
          <div className="drawer-hint">Alerts werden geladen...</div>
        )}
      </Dialog>

      <Dialog
        header="Server anlegen"
        visible={wizardOpen}
        onHide={handleCloseWizard}
        className="wizard-dialog"
        draggable={false}
      >
        <Steps model={steps} activeIndex={wizardStep} readOnly className="wizard-steps" />
        {wizardError ? <div className="form-error">{wizardError}</div> : null}

        {wizardStep === 0 ? (
          <div className="wizard-step">
            <div className="form-grid">
              <div className="form-field">
                <label htmlFor="server-name">Servername (optional)</label>
                <InputText
                  id="server-name"
                  value={draft.name}
                  onChange={(event) => setDraft((prev) => ({ ...prev, name: event.target.value }))}
                  placeholder="vault-core-01"
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-host">Host/IP</label>
                <InputText
                  id="server-host"
                  value={draft.host}
                  onChange={(event) => setDraft((prev) => ({ ...prev, host: event.target.value }))}
                  placeholder="10.10.10.23"
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-port">Port (optional)</label>
                <InputNumber
                  id="server-port"
                  value={draft.port}
                  onValueChange={(event) => setDraft((prev) => ({ ...prev, port: event.value }))}
                  min={1}
                  max={65535}
                  placeholder="8006/443"
                  useGrouping={false}
                />
              </div>
              <div className="form-field">
                <label>Hinweis</label>
                <span className="form-hint">Im naechsten Schritt erkennen wir den Typ und hinterlegen Zugangsdaten.</span>
              </div>
            </div>
            <div className="form-actions">
              <span />
              <div className="form-actions-right">
                <Button label="Abbrechen" className="p-button-text" onClick={handleCloseWizard} />
                <Button label="Weiter" icon="pi pi-arrow-right" onClick={handleDetectType} disabled={!canContinue || isSaving} />
              </div>
            </div>
          </div>
        ) : (
          <div className="wizard-step">
            <div className="form-grid">
              <div className="form-field">
                <label>Erkannter Typ</label>
                <Tag
                  value={detectedType === 'pbs'
                    ? 'Proxmox Backup Server'
                    : detectedType === 'proxmox'
                      ? 'Proxmox'
                      : 'TrueNAS SCALE'}
                  severity="info"
                  className={`platform-tag ${detectedType}`}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-type">Typ anpassen</label>
                <Dropdown
                  id="server-type"
                  value={config.type}
                  options={serverTypes}
                  onChange={(event) => setConfig((prev) => ({ ...prev, type: event.value }))}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-scheme">Protokoll</label>
                <Dropdown
                  id="server-scheme"
                  value={config.scheme}
                  options={schemeOptions}
                  onChange={(event) => setConfig((prev) => ({ ...prev, scheme: event.value }))}
                />
              </div>
              <div className="form-field">
                <label htmlFor="server-insecure">TLS ignorieren (self-signed)</label>
                <InputSwitch
                  id="server-insecure"
                  checked={config.allowInsecure}
                  onChange={(event) => setConfig((prev) => ({ ...prev, allowInsecure: event.value }))}
                />
              </div>

              {config.type === 'truenas' ? (
                <div className="form-field">
                  <label htmlFor="truenas-api-key">API Key</label>
                  <InputText
                    id="truenas-api-key"
                    type="password"
                    value={config.apiKey}
                    onChange={(event) => setConfig((prev) => ({ ...prev, apiKey: event.target.value }))}
                    placeholder="********"
                  />
                </div>
              ) : (
                <>
                  <div className="form-field">
                    <label htmlFor="proxmox-token-id">API Token ID</label>
                    <InputText
                      id="proxmox-token-id"
                      value={config.apiTokenId}
                      onChange={(event) => setConfig((prev) => ({ ...prev, apiTokenId: event.target.value }))}
                      placeholder="vault@pam!token"
                    />
                  </div>
                  <div className="form-field">
                    <label htmlFor="proxmox-token-secret">API Token Secret</label>
                    <InputText
                      id="proxmox-token-secret"
                      type="password"
                      value={config.apiTokenSecret}
                      onChange={(event) => setConfig((prev) => ({ ...prev, apiTokenSecret: event.target.value }))}
                      placeholder="********"
                    />
                  </div>
                </>
              )}
            </div>
            <div className="form-actions">
              <Button label="Zurueck" className="p-button-text" onClick={() => setWizardStep(0)} />
              <div className="form-actions-right">
                <Button label="Abbrechen" className="p-button-text" onClick={handleCloseWizard} />
                <Button label="Speichern" icon="pi pi-check" onClick={handleSaveConfig} disabled={!serverId || !canSave || isSaving} />
              </div>
            </div>
          </div>
        )}
      </Dialog>

      <Dialog
        header="Server umbenennen"
        visible={editOpen}
        onHide={() => setEditOpen(false)}
        className="wizard-dialog"
        draggable={false}
      >
        <div className="form-grid">
          <div className="form-field">
            <label htmlFor="edit-server-name">Neuer Servername</label>
            <InputText
              id="edit-server-name"
              value={editName}
              onChange={(event) => setEditName(event.target.value)}
              placeholder={activeServer?.host || 'Servername'}
            />
          </div>
        </div>
        <div className="form-actions">
          <Button label="Abbrechen" className="p-button-text" onClick={() => setEditOpen(false)} />
          <Button label="Speichern" icon="pi pi-check" onClick={handleSaveServerName} />
        </div>
      </Dialog>

      <Dialog
        header="Server loeschen"
        visible={deleteOpen}
        onHide={() => setDeleteOpen(false)}
        className="wizard-dialog"
        draggable={false}
      >
        <p>Willst du den Server "{activeServer?.name || activeServer?.host}" wirklich entfernen?</p>
        <div className="form-actions">
          <Button label="Abbrechen" className="p-button-text" onClick={() => setDeleteOpen(false)} />
          <Button label="Loeschen" icon="pi pi-trash" severity="danger" onClick={handleDeleteServer} />
        </div>
      </Dialog>
    </div>
  );
}
