import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router';
import {
  Badge,
  Button,
  DataTable,
  Input,
  Modal,
  MonoText,
  SectionHeader,
  Select,
  Spinner,
  Toggle,
  useToast,
} from '@cameleer/design-system';
import type { Column } from '@cameleer/design-system';
import { useEnvironmentStore } from '../../api/environment-store';
import { useEnvironments } from '../../api/queries/admin/environments';
import {
  useAllApps,
  useApps,
  useCreateApp,
  useDeleteApp,
  useAppVersions,
  useUploadJar,
  useDeployments,
  useCreateDeployment,
  useStopDeployment,
  useUpdateContainerConfig,
} from '../../api/queries/admin/apps';
import type { App, AppVersion, Deployment } from '../../api/queries/admin/apps';
import type { Environment } from '../../api/queries/admin/environments';
import { useApplicationConfig, useUpdateApplicationConfig } from '../../api/queries/commands';
import type { ApplicationConfig } from '../../api/queries/commands';
import styles from './AppsTab.module.css';

function formatBytes(bytes: number): string {
  if (bytes >= 1_048_576) return `${(bytes / 1_048_576).toFixed(1)} MB`;
  if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${bytes} B`;
}

function timeAgo(date: string): string {
  const seconds = Math.floor((Date.now() - new Date(date).getTime()) / 1000);
  if (seconds < 60) return `${seconds}s ago`;
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  return `${Math.floor(hours / 24)}d ago`;
}

const STATUS_COLORS: Record<string, 'success' | 'warning' | 'error' | 'auto' | 'running'> = {
  RUNNING: 'running', STARTING: 'warning', FAILED: 'error', STOPPED: 'auto',
};

function slugify(name: string): string {
  return name
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '')
    .substring(0, 100);
}

export default function AppsTab() {
  const { appId } = useParams<{ appId?: string }>();
  const selectedEnv = useEnvironmentStore((s) => s.environment);
  const { data: environments = [] } = useEnvironments();

  if (appId) return <AppDetailView appId={appId} environments={environments} selectedEnv={selectedEnv} />;
  return <AppListView selectedEnv={selectedEnv} environments={environments} />;
}

// ═══════════════════════════════════════════════════════════════════
//  LIST VIEW
// ═══════════════════════════════════════════════════════════════════

function AppListView({ selectedEnv, environments }: { selectedEnv: string | undefined; environments: Environment[] }) {
  const { toast } = useToast();
  const navigate = useNavigate();
  const { data: allApps = [], isLoading: allLoading } = useAllApps();
  const envId = useMemo(() => environments.find((e) => e.slug === selectedEnv)?.id, [environments, selectedEnv]);
  const { data: envApps = [], isLoading: envLoading } = useApps(envId);
  const [createOpen, setCreateOpen] = useState(false);

  const apps = selectedEnv ? envApps : allApps;
  const isLoading = selectedEnv ? envLoading : allLoading;

  const envMap = useMemo(() => new Map(environments.map((e) => [e.id, e])), [environments]);

  type AppRow = App & { id: string; envName: string };
  const rows: AppRow[] = useMemo(
    () => apps.map((a) => ({ ...a, envName: envMap.get(a.environmentId)?.displayName ?? '?' })),
    [apps, envMap],
  );

  const columns: Column<AppRow>[] = useMemo(() => [
    { key: 'displayName', header: 'Name', sortable: true,
      render: (_v: unknown, row: AppRow) => (
        <div><div className={styles.cellName}>{row.displayName}</div><div className={styles.cellMeta}>{row.slug}</div></div>
      ),
    },
    ...(!selectedEnv ? [{ key: 'envName', header: 'Environment', sortable: true,
      render: (_v: unknown, row: AppRow) => <Badge label={row.envName} color={'auto' as const} />,
    }] : []),
    { key: 'updatedAt', header: 'Updated', sortable: true,
      render: (_v: unknown, row: AppRow) => <span className={styles.cellMeta}>{timeAgo(row.updatedAt)}</span>,
    },
    { key: 'createdAt', header: 'Created', sortable: true,
      render: (_v: unknown, row: AppRow) => <span className={styles.cellMeta}>{new Date(row.createdAt).toLocaleDateString()}</span>,
    },
  ], [selectedEnv]);

  if (isLoading) return <Spinner size="md" />;

  return (
    <div className={styles.container}>
      <div className={styles.toolbar}>
        <Button size="sm" variant="primary" onClick={() => setCreateOpen(true)}>+ Create App</Button>
      </div>
      <DataTable columns={columns} data={rows} onRowClick={(row) => navigate(`/apps/${row.id}`)} />
      <CreateAppModal
        open={createOpen}
        onClose={() => setCreateOpen(false)}
        environments={environments}
        defaultEnvId={envId}
        onCreated={(appId) => { setCreateOpen(false); navigate(`/apps/${appId}`); }}
      />
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
//  CREATE APP MODAL
// ═══════════════════════════════════════════════════════════════════

function CreateAppModal({ open, onClose, environments, defaultEnvId, onCreated }: {
  open: boolean;
  onClose: () => void;
  environments: Environment[];
  defaultEnvId: string | undefined;
  onCreated: (appId: string) => void;
}) {
  const { toast } = useToast();
  const createApp = useCreateApp();
  const uploadJar = useUploadJar();
  const createDeployment = useCreateDeployment();

  const [name, setName] = useState('');
  const [slugEdited, setSlugEdited] = useState(false);
  const [slug, setSlug] = useState('');
  const [envId, setEnvId] = useState('');
  const [file, setFile] = useState<File | null>(null);
  const [deploy, setDeploy] = useState(true);
  const [busy, setBusy] = useState(false);
  const [step, setStep] = useState('');
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Reset on open
  useEffect(() => {
    if (open) {
      setName(''); setSlug(''); setSlugEdited(false); setFile(null);
      setDeploy(true); setBusy(false); setStep('');
      setEnvId(defaultEnvId || (environments.length > 0 ? environments[0].id : ''));
    }
  }, [open, defaultEnvId, environments]);

  // Auto-compute slug from name
  useEffect(() => {
    if (!slugEdited) setSlug(slugify(name));
  }, [name, slugEdited]);

  const canSubmit = name.trim() && slug.trim() && envId && file;

  async function handleSubmit() {
    if (!canSubmit) return;
    setBusy(true);
    try {
      // 1. Create app
      setStep('Creating app...');
      const app = await createApp.mutateAsync({ environmentId: envId, slug: slug.trim(), displayName: name.trim() });

      // 2. Upload JAR
      setStep('Uploading JAR...');
      const version = await uploadJar.mutateAsync({ appId: app.id, file: file! });

      // 3. Deploy (if requested)
      if (deploy) {
        setStep('Starting deployment...');
        await createDeployment.mutateAsync({ appId: app.id, appVersionId: version.id, environmentId: envId });
      }

      toast({ title: 'App created and deployed', description: name.trim(), variant: 'success' });
      onCreated(app.id);
    } catch (e) {
      toast({ title: 'Failed: ' + step, description: e instanceof Error ? e.message : 'Unknown error', variant: 'error', duration: 86_400_000 });
    } finally {
      setBusy(false);
      setStep('');
    }
  }

  return (
    <Modal open={open} onClose={onClose} title="Create Application" size="md">
      <div className={styles.createModal}>
        <div className={styles.createField}>
          <label className={styles.createLabel}>Application Name</label>
          <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="e.g. Payment Gateway" disabled={busy} />
        </div>

        <div className={styles.createField}>
          <label className={styles.createLabel}>
            Slug
            <span className={styles.createLabelHint}>(auto-generated, editable)</span>
          </label>
          <Input value={slug} onChange={(e) => { setSlug(e.target.value); setSlugEdited(true); }} disabled={busy} />
        </div>

        <div className={styles.createField}>
          <label className={styles.createLabel}>Environment</label>
          <Select value={envId} onChange={(e) => setEnvId(e.target.value)} disabled={busy}
            options={environments.filter((e) => e.enabled).map((e) => ({ value: e.id, label: `${e.displayName} (${e.slug})` }))} />
        </div>

        <div className={styles.createField}>
          <label className={styles.createLabel}>Application JAR</label>
          <div className={styles.fileRow}>
            <input ref={fileInputRef} type="file" accept=".jar" style={{ display: 'none' }}
              onChange={(e) => setFile(e.target.files?.[0] ?? null)} />
            <Button size="sm" variant="secondary" onClick={() => fileInputRef.current?.click()} disabled={busy}>
              {file ? 'Change file' : 'Select JAR'}
            </Button>
            {file && <span className={styles.fileName}>{file.name} ({formatBytes(file.size)})</span>}
          </div>
        </div>

        <div className={styles.createField}>
          <div className={styles.deployToggle}>
            <Toggle checked={deploy} onChange={() => setDeploy(!deploy)} disabled={busy} />
            <span>{deploy ? 'Deploy immediately after upload' : 'Upload only (deploy later)'}</span>
          </div>
        </div>

        {step && <div className={styles.stepIndicator}>{step}</div>}

        <div className={styles.createActions}>
          <Button size="sm" variant="ghost" onClick={onClose} disabled={busy}>Cancel</Button>
          <Button size="sm" variant="primary" onClick={handleSubmit} loading={busy} disabled={!canSubmit || busy}>
            {deploy ? 'Create & Deploy' : 'Create & Upload'}
          </Button>
        </div>
      </div>
    </Modal>
  );
}

// ═══════════════════════════════════════════════════════════════════
//  DETAIL VIEW
// ═══════════════════════════════════════════════════════════════════

function AppDetailView({ appId, environments, selectedEnv }: { appId: string; environments: Environment[]; selectedEnv: string | undefined }) {
  const { toast } = useToast();
  const navigate = useNavigate();
  const { data: allApps = [] } = useAllApps();
  const app = useMemo(() => allApps.find((a) => a.id === appId), [allApps, appId]);
  const { data: versions = [] } = useAppVersions(appId);
  const { data: deployments = [] } = useDeployments(appId);
  const uploadJar = useUploadJar();
  const createDeployment = useCreateDeployment();
  const stopDeployment = useStopDeployment();
  const deleteApp = useDeleteApp();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [subTab, setSubTab] = useState<'overview' | 'config'>('overview');

  const envMap = useMemo(() => new Map(environments.map((e) => [e.id, e])), [environments]);
  const sortedVersions = useMemo(() => [...versions].sort((a, b) => b.version - a.version), [versions]);

  if (!app) return <Spinner size="md" />;

  const env = envMap.get(app.environmentId);

  async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    try {
      const v = await uploadJar.mutateAsync({ appId, file });
      toast({ title: `Version ${v.version} uploaded`, description: file.name, variant: 'success' });
    } catch { toast({ title: 'Upload failed', variant: 'error', duration: 86_400_000 }); }
    if (fileInputRef.current) fileInputRef.current.value = '';
  }

  async function handleDeploy(versionId: string, environmentId: string) {
    try {
      await createDeployment.mutateAsync({ appId, appVersionId: versionId, environmentId });
      toast({ title: 'Deployment started', variant: 'success' });
    } catch { toast({ title: 'Deploy failed', variant: 'error', duration: 86_400_000 }); }
  }

  async function handleStop(deploymentId: string) {
    try {
      await stopDeployment.mutateAsync({ appId, deploymentId });
      toast({ title: 'Deployment stopped', variant: 'warning' });
    } catch { toast({ title: 'Stop failed', variant: 'error', duration: 86_400_000 }); }
  }

  async function handleDelete() {
    try {
      await deleteApp.mutateAsync(appId);
      toast({ title: 'App deleted', variant: 'warning' });
      navigate('/apps');
    } catch { toast({ title: 'Delete failed', variant: 'error', duration: 86_400_000 }); }
  }

  return (
    <div className={styles.container}>
      <div className={styles.detailHeader}>
        <div>
          <h2 className={styles.detailTitle}>{app.displayName}</h2>
          <div className={styles.detailMeta}>
            {app.slug} &middot; <Badge label={env?.displayName ?? '?'} color="auto" />
          </div>
        </div>
        <div className={styles.detailActions}>
          <input ref={fileInputRef} type="file" accept=".jar" style={{ display: 'none' }} onChange={handleUpload} />
          <Button size="sm" variant="primary" onClick={() => fileInputRef.current?.click()} loading={uploadJar.isPending}>Upload JAR</Button>
          <Button size="sm" variant="danger" onClick={handleDelete}>Delete App</Button>
        </div>
      </div>

      <div className={styles.subTabs}>
        <button className={`${styles.subTab} ${subTab === 'overview' ? styles.subTabActive : ''}`} onClick={() => setSubTab('overview')}>Overview</button>
        <button className={`${styles.subTab} ${subTab === 'config' ? styles.subTabActive : ''}`} onClick={() => setSubTab('config')}>Configuration</button>
      </div>

      {subTab === 'overview' && (
        <OverviewSubTab
          app={app} deployments={deployments} versions={sortedVersions}
          environments={environments} envMap={envMap} selectedEnv={selectedEnv}
          onDeploy={handleDeploy} onStop={handleStop}
        />
      )}
      {subTab === 'config' && (
        <ConfigSubTab app={app} environment={env} />
      )}
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
//  OVERVIEW SUB-TAB
// ═══════════════════════════════════════════════════════════════════

function OverviewSubTab({ app, deployments, versions, environments, envMap, selectedEnv, onDeploy, onStop }: {
  app: App; deployments: Deployment[]; versions: AppVersion[];
  environments: Environment[]; envMap: Map<string, Environment>;
  selectedEnv: string | undefined;
  onDeploy: (versionId: string, envId: string) => void;
  onStop: (deploymentId: string) => void;
}) {
  // Determine which env slug is selected
  const selectedEnvId = useMemo(
    () => selectedEnv ? environments.find((e) => e.slug === selectedEnv)?.id : undefined,
    [environments, selectedEnv],
  );

  return (
    <>
      <SectionHeader>Deployments</SectionHeader>
      {deployments.length === 0 && <p className={styles.emptyNote}>No deployments yet.</p>}
      {deployments.length > 0 && (
        <table className={styles.table}>
          <thead>
            <tr>
              <th>Environment</th>
              <th>Version</th>
              <th>Status</th>
              <th>URL</th>
              <th>Deployed</th>
              <th style={{ textAlign: 'right' }}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {deployments.map((d) => {
              const dEnv = envMap.get(d.environmentId);
              const version = versions.find((v) => v.id === d.appVersionId);
              const isSelectedEnv = !selectedEnvId || d.environmentId === selectedEnvId;
              const canAct = isSelectedEnv && (d.status === 'RUNNING' || d.status === 'STARTING');
              const canStart = isSelectedEnv && d.status === 'STOPPED';
              const url = dEnv ? `/${dEnv.slug}/${app.slug}/` : '';

              return (
                <tr key={d.id} className={!isSelectedEnv ? styles.mutedRow : undefined}>
                  <td>
                    <Badge label={dEnv?.displayName ?? '?'} color={dEnv?.production ? 'error' : 'auto'} />
                  </td>
                  <td><Badge label={version ? `v${version.version}` : '?'} color="auto" /></td>
                  <td><Badge label={d.status} color={STATUS_COLORS[d.status] ?? 'auto'} /></td>
                  <td>
                    {d.status === 'RUNNING' ? (
                      <MonoText size="xs">{url}</MonoText>
                    ) : (
                      <span className={styles.mutedMono}>{url}</span>
                    )}
                  </td>
                  <td><span className={styles.cellMeta}>{d.deployedAt ? timeAgo(d.deployedAt) : '—'}</span></td>
                  <td style={{ textAlign: 'right' }}>
                    {canAct && <Button size="sm" variant="danger" onClick={() => onStop(d.id)}>Stop</Button>}
                    {canStart && <Button size="sm" variant="secondary" onClick={() => onDeploy(d.appVersionId, d.environmentId)}>Start</Button>}
                    {!isSelectedEnv && <span className={styles.envHint}>switch env to manage</span>}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      )}

      <SectionHeader>Versions ({versions.length})</SectionHeader>
      {versions.length === 0 && <p className={styles.emptyNote}>No versions uploaded yet.</p>}
      {versions.map((v) => (
        <VersionRow key={v.id} version={v} environments={environments} onDeploy={(envId) => onDeploy(v.id, envId)} />
      ))}
    </>
  );
}

function VersionRow({ version, environments, onDeploy }: { version: AppVersion; environments: Environment[]; onDeploy: (envId: string) => void }) {
  const [deployEnv, setDeployEnv] = useState('');
  return (
    <div className={styles.row}>
      <Badge label={`v${version.version}`} color="auto" />
      <span className={styles.rowText}>{version.jarFilename} ({formatBytes(version.jarSizeBytes)})</span>
      <MonoText size="xs">{version.jarChecksum.substring(0, 8)}</MonoText>
      <span className={styles.cellMeta}>{timeAgo(version.uploadedAt)}</span>
      <select className={styles.nativeSelect} value={deployEnv} onChange={(e) => setDeployEnv(e.target.value)}>
        <option value="">Deploy to...</option>
        {environments.filter((e) => e.enabled).map((e) => <option key={e.id} value={e.id}>{e.displayName}</option>)}
      </select>
      <Button size="sm" variant="secondary" disabled={!deployEnv} onClick={() => { onDeploy(deployEnv); setDeployEnv(''); }}>Deploy</Button>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
//  CONFIGURATION SUB-TAB
// ═══════════════════════════════════════════════════════════════════

function ConfigSubTab({ app, environment }: { app: App; environment?: Environment }) {
  const { toast } = useToast();
  const { data: agentConfig } = useApplicationConfig(app.slug);
  const updateAgentConfig = useUpdateApplicationConfig();
  const updateContainerConfig = useUpdateContainerConfig();
  const isProd = environment?.production ?? false;
  const [editing, setEditing] = useState(false);

  // Agent config state
  const [engineLevel, setEngineLevel] = useState('REGULAR');
  const [payloadCapture, setPayloadCapture] = useState('BOTH');
  const [payloadSize, setPayloadSize] = useState('4');
  const [payloadUnit, setPayloadUnit] = useState('KB');
  const [appLogLevel, setAppLogLevel] = useState('INFO');
  const [agentLogLevel, setAgentLogLevel] = useState('INFO');
  const [metricsEnabled, setMetricsEnabled] = useState(true);
  const [metricsInterval, setMetricsInterval] = useState('60');
  const [samplingRate, setSamplingRate] = useState('1.0');
  const [replayEnabled, setReplayEnabled] = useState(true);
  const [routeControlEnabled, setRouteControlEnabled] = useState(true);

  // Container config state
  const defaults = environment?.defaultContainerConfig ?? {};
  const merged = useMemo(() => ({ ...defaults, ...app.containerConfig }), [defaults, app.containerConfig]);
  const [memoryLimit, setMemoryLimit] = useState('512');
  const [memoryReserve, setMemoryReserve] = useState('');
  const [cpuShares, setCpuShares] = useState('512');
  const [cpuLimit, setCpuLimit] = useState('');
  const [ports, setPorts] = useState<number[]>([]);
  const [newPort, setNewPort] = useState('');
  const [envVars, setEnvVars] = useState<{ key: string; value: string }[]>([]);

  // Sync from server data
  const syncFromServer = useCallback(() => {
    if (agentConfig) {
      setEngineLevel(agentConfig.engineLevel ?? 'REGULAR');
      setPayloadCapture(agentConfig.payloadCaptureMode ?? 'BOTH');
      const raw = agentConfig.payloadCaptureMode !== undefined ? 4096 : 4096; // TODO: read from config when available
      setPayloadSize('4'); setPayloadUnit('KB');
      setAppLogLevel(agentConfig.applicationLogLevel ?? 'INFO');
      setAgentLogLevel(agentConfig.agentLogLevel ?? 'INFO');
      setMetricsEnabled(agentConfig.metricsEnabled);
      setSamplingRate(String(agentConfig.samplingRate));
    }
    setMemoryLimit(String(merged.memoryLimitMb ?? 512));
    setMemoryReserve(String(merged.memoryReserveMb ?? ''));
    setCpuShares(String(merged.cpuShares ?? 512));
    setCpuLimit(String(merged.cpuLimit ?? ''));
    setPorts(Array.isArray(merged.exposedPorts) ? merged.exposedPorts as number[] : []);
    const vars = merged.customEnvVars as Record<string, string> | undefined;
    setEnvVars(vars ? Object.entries(vars).map(([key, value]) => ({ key, value })) : []);
  }, [agentConfig, merged]);

  useEffect(() => { syncFromServer(); }, [syncFromServer]);

  function handleCancel() {
    syncFromServer();
    setEditing(false);
  }

  function payloadSizeToBytes(): number {
    const val = parseFloat(payloadSize) || 0;
    if (payloadUnit === 'KB') return val * 1024;
    if (payloadUnit === 'MB') return val * 1048576;
    return val;
  }

  async function handleSave() {
    // Save agent config
    if (agentConfig) {
      try {
        await updateAgentConfig.mutateAsync({
          ...agentConfig,
          engineLevel, payloadCaptureMode: payloadCapture,
          applicationLogLevel: appLogLevel, agentLogLevel,
          metricsEnabled, samplingRate: parseFloat(samplingRate) || 1.0,
        });
      } catch { toast({ title: 'Failed to save agent config', variant: 'error', duration: 86_400_000 }); return; }
    }

    // Save container config
    const containerConfig: Record<string, unknown> = {
      memoryLimitMb: memoryLimit ? parseInt(memoryLimit) : null,
      memoryReserveMb: memoryReserve ? parseInt(memoryReserve) : null,
      cpuShares: cpuShares ? parseInt(cpuShares) : null,
      cpuLimit: cpuLimit ? parseFloat(cpuLimit) : null,
      exposedPorts: ports,
      customEnvVars: Object.fromEntries(envVars.filter((v) => v.key.trim()).map((v) => [v.key, v.value])),
    };
    try {
      await updateContainerConfig.mutateAsync({ appId: app.id, config: containerConfig });
      toast({ title: 'Configuration saved', variant: 'success' });
      setEditing(false);
    } catch { toast({ title: 'Failed to save container config', variant: 'error', duration: 86_400_000 }); }
  }

  function addPort() {
    const p = parseInt(newPort);
    if (p && !ports.includes(p)) { setPorts([...ports, p]); setNewPort(''); }
  }

  return (
    <>
      {!editing && (
        <div className={styles.editBanner}>
          <span className={styles.editBannerText}>Configuration is read-only. Enter edit mode to make changes.</span>
          <Button size="sm" variant="secondary" onClick={() => setEditing(true)}>Edit</Button>
        </div>
      )}
      {editing && (
        <div className={`${styles.editBanner} ${styles.editBannerActive}`}>
          <span className={styles.editBannerTextWarn}>Editing configuration. Changes are not saved until you click Save.</span>
          <div className={styles.editBannerActions}>
            <Button size="sm" variant="ghost" onClick={handleCancel}>Cancel</Button>
            <Button size="sm" variant="primary" onClick={handleSave}
              loading={updateAgentConfig.isPending || updateContainerConfig.isPending}>Save Configuration</Button>
          </div>
        </div>
      )}

      {/* Agent Observability */}
      <SectionHeader>Agent Observability</SectionHeader>
      <div className={styles.configGrid}>
        <span className={styles.configLabel}>Engine Level</span>
        <Select disabled={!editing} value={engineLevel} onChange={(e) => setEngineLevel(e.target.value)}
          options={[{ value: 'NONE', label: 'NONE' }, { value: 'MINIMAL', label: 'MINIMAL' }, { value: 'REGULAR', label: 'REGULAR' }, { value: 'COMPLETE', label: 'COMPLETE' }]} />

        <span className={styles.configLabel}>Payload Capture</span>
        <Select disabled={!editing} value={payloadCapture} onChange={(e) => setPayloadCapture(e.target.value)}
          options={[{ value: 'NONE', label: 'NONE' }, { value: 'INPUT', label: 'INPUT' }, { value: 'OUTPUT', label: 'OUTPUT' }, { value: 'BOTH', label: 'BOTH' }]} />

        <span className={styles.configLabel}>Max Payload Size</span>
        <div className={styles.configInline}>
          <Input disabled={!editing} value={payloadSize} onChange={(e) => setPayloadSize(e.target.value)} style={{ width: 70 }} />
          <Select disabled={!editing} value={payloadUnit} onChange={(e) => setPayloadUnit(e.target.value)} style={{ width: 90 }}
            options={[{ value: 'bytes', label: 'bytes' }, { value: 'KB', label: 'KB' }, { value: 'MB', label: 'MB' }]} />
        </div>

        <span className={styles.configLabel}>App Log Level</span>
        <Select disabled={!editing} value={appLogLevel} onChange={(e) => setAppLogLevel(e.target.value)}
          options={['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'].map((l) => ({ value: l, label: l }))} />

        <span className={styles.configLabel}>Agent Log Level</span>
        <Select disabled={!editing} value={agentLogLevel} onChange={(e) => setAgentLogLevel(e.target.value)}
          options={['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'].map((l) => ({ value: l, label: l }))} />

        <span className={styles.configLabel}>Metrics</span>
        <div className={styles.configInline}>
          <Toggle checked={metricsEnabled} onChange={() => editing && setMetricsEnabled(!metricsEnabled)} disabled={!editing} />
          <span className={metricsEnabled ? styles.toggleEnabled : styles.toggleDisabled}>{metricsEnabled ? 'Enabled' : 'Disabled'}</span>
          <span className={styles.cellMeta} style={{ marginLeft: 8 }}>Interval</span>
          <Input disabled={!editing} value={metricsInterval} onChange={(e) => setMetricsInterval(e.target.value)} style={{ width: 50 }} />
          <span className={styles.cellMeta}>s</span>
        </div>

        <span className={styles.configLabel}>Sampling Rate</span>
        <Input disabled={!editing} value={samplingRate} onChange={(e) => setSamplingRate(e.target.value)} style={{ width: 80 }} />

        <span className={styles.configLabel}>Replay</span>
        <div className={styles.configInline}>
          <Toggle checked={replayEnabled} onChange={() => editing && setReplayEnabled(!replayEnabled)} disabled={!editing} />
          <span className={replayEnabled ? styles.toggleEnabled : styles.toggleDisabled}>{replayEnabled ? 'Enabled' : 'Disabled'}</span>
        </div>

        <span className={styles.configLabel}>Route Control</span>
        <div className={styles.configInline}>
          <Toggle checked={routeControlEnabled} onChange={() => editing && setRouteControlEnabled(!routeControlEnabled)} disabled={!editing} />
          <span className={routeControlEnabled ? styles.toggleEnabled : styles.toggleDisabled}>{routeControlEnabled ? 'Enabled' : 'Disabled'}</span>
        </div>
      </div>

      {/* Container Resources */}
      <SectionHeader>Container Resources</SectionHeader>
      <div className={styles.configGrid}>
        <span className={styles.configLabel}>Memory Limit</span>
        <div className={styles.configInline}>
          <Input disabled={!editing} value={memoryLimit} onChange={(e) => setMemoryLimit(e.target.value)} style={{ width: 80 }} />
          <span className={styles.cellMeta}>MB</span>
        </div>

        <span className={styles.configLabel}>Memory Reserve</span>
        <div>
          <div className={styles.configInline}>
            <Input disabled value={memoryReserve} onChange={(e) => setMemoryReserve(e.target.value)} placeholder="---" style={{ width: 80 }} />
            <span className={styles.cellMeta}>MB</span>
          </div>
          {!isProd && <span className={styles.configHint}>Available in production environments only</span>}
        </div>

        <span className={styles.configLabel}>CPU Shares</span>
        <Input disabled={!editing} value={cpuShares} onChange={(e) => setCpuShares(e.target.value)} style={{ width: 80 }} />

        <span className={styles.configLabel}>CPU Limit</span>
        <div className={styles.configInline}>
          <Input disabled={!editing} value={cpuLimit} onChange={(e) => setCpuLimit(e.target.value)} placeholder="e.g. 1.0" style={{ width: 80 }} />
          <span className={styles.cellMeta}>cores</span>
        </div>

        <span className={styles.configLabel}>Exposed Ports</span>
        <div className={styles.portPills}>
          {ports.map((p) => (
            <span key={p} className={styles.portPill}>
              {p}
              <button className={styles.portPillDelete} disabled={!editing}
                onClick={() => editing && setPorts(ports.filter((x) => x !== p))}>&times;</button>
            </span>
          ))}
          <input className={styles.portAddInput} disabled={!editing} placeholder="+ port" value={newPort}
            onChange={(e) => setNewPort(e.target.value)}
            onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addPort(); } }} />
        </div>
      </div>

      {/* Environment Variables */}
      <SectionHeader>Environment Variables</SectionHeader>
      {envVars.map((v, i) => (
        <div key={i} className={styles.envVarRow}>
          <Input disabled={!editing} value={v.key} onChange={(e) => {
            const next = [...envVars]; next[i] = { ...v, key: e.target.value }; setEnvVars(next);
          }} className={styles.envVarKey} />
          <Input disabled={!editing} value={v.value} onChange={(e) => {
            const next = [...envVars]; next[i] = { ...v, value: e.target.value }; setEnvVars(next);
          }} className={styles.envVarValue} />
          <button className={styles.envVarDelete} disabled={!editing}
            onClick={() => editing && setEnvVars(envVars.filter((_, j) => j !== i))}>&times;</button>
        </div>
      ))}
      {editing && (
        <Button size="sm" variant="secondary" onClick={() => setEnvVars([...envVars, { key: '', value: '' }])}>+ Add Variable</Button>
      )}
    </>
  );
}
