import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '../api';
import type { HorizonPoint } from '../api/types';

const DEFAULT_PROFILE: EquipProfile = {
  id: 'default',
  name: 'AT71 + ATR2600C',
  focal_mm: 490,
  aperture_mm: 71,
  pixel_um: 3.76,
  res_x: 6248,
  res_y: 4176,
};

interface EquipProfile {
  id: string;
  name: string;
  focal_mm: number;
  aperture_mm: number;
  pixel_um: number;
  res_x: number;
  res_y: number;
}

function loadProfiles(): EquipProfile[] {
  try {
    const stored = JSON.parse(localStorage.getItem('astronome_equip_profiles') ?? '[]') as EquipProfile[];
    // Ensure the default profile is always present
    if (!stored.find(p => p.id === 'default')) {
      return [DEFAULT_PROFILE, ...stored];
    }
    return stored;
  } catch { return [DEFAULT_PROFILE]; }
}

function calcProfile(p: { focal_mm: number; aperture_mm: number; pixel_um: number; res_x: number; res_y: number }) {
  const ps = (206.265 * p.pixel_um / 1000) / p.focal_mm * 1000;
  const fov_w_deg = (ps * p.res_x) / 3600;
  const fov_h_deg = (ps * p.res_y) / 3600;
  const focal_ratio = p.focal_mm / p.aperture_mm;
  return {
    plate_scale_arcsec: ps.toFixed(3),
    fov_w: `${(fov_w_deg * 60).toFixed(1)}′ × ${(fov_h_deg * 60).toFixed(1)}′`,
    focal_ratio: `f/${focal_ratio.toFixed(1)}`,
  };
}

function EquipmentProfiles() {
  const [profiles, setProfiles] = useState<EquipProfile[]>(loadProfiles);
  const [activeId, setActiveId] = useState<string>(() =>
    localStorage.getItem('astronome_active_profile') ?? 'default'
  );
  const [editing, setEditing] = useState<EquipProfile | null>(null);
  const [adding, setAdding] = useState(false);
  const [form, setForm] = useState({ name: '', focal_mm: 490, aperture_mm: 71, pixel_um: 3.76, res_x: 6248, res_y: 4176 });

  useEffect(() => {
    localStorage.setItem('astronome_equip_profiles', JSON.stringify(profiles));
  }, [profiles]);

  useEffect(() => {
    localStorage.setItem('astronome_active_profile', activeId);
  }, [activeId]);

  const saveProfile = () => {
    if (!form.name.trim()) return;
    if (editing) {
      setProfiles(ps => ps.map(p => p.id === editing.id ? { ...form, id: editing.id } : p));
    } else {
      setProfiles(ps => [...ps, { ...form, id: Date.now().toString() }]);
    }
    setEditing(null);
    setAdding(false);
    setForm({ name: '', focal_mm: 490, aperture_mm: 71, pixel_um: 3.76, res_x: 6248, res_y: 4176 });
  };

  const deleteProfile = (id: string) => {
    if (profiles.length <= 1) return;
    setProfiles(ps => ps.filter(p => p.id !== id));
    if (activeId === id) setActiveId(profiles.find(p => p.id !== id)?.id ?? 'default');
  };

  const startEdit = (p: EquipProfile) => {
    setEditing(p);
    setForm({ name: p.name, focal_mm: p.focal_mm, aperture_mm: p.aperture_mm, pixel_um: p.pixel_um, res_x: p.res_x, res_y: p.res_y });
    setAdding(false);
  };

  const fieldStyle: React.CSSProperties = {
    background: 'var(--bg-void)', border: '1px solid var(--border)', borderRadius: 3,
    color: 'var(--text-hi)', fontFamily: 'var(--font-mono)', fontSize: 12,
    padding: '4px 8px', width: '100%', boxSizing: 'border-box',
  };

  return (
    <section style={{ marginBottom: 32 }}>
      <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 16, marginBottom: 14, color: 'var(--text-hi)' }}>
        Equipment Profiles
      </h2>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, maxWidth: 640 }}>
        {profiles.map(p => {
          const calc = calcProfile(p);
          const isActive = p.id === activeId;
          return (
            <div key={p.id} style={{
              background: 'var(--bg-panel)', border: `1px solid ${isActive ? 'var(--amber-dim)' : 'var(--border)'}`,
              borderRadius: 6, padding: '12px 16px',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: isActive ? 'var(--amber)' : 'var(--text-hi)', fontWeight: 600 }}>
                    {p.name}
                    {isActive && <span style={{ marginLeft: 8, fontSize: 10, color: 'var(--amber)', background: 'var(--amber-glow)', padding: '1px 6px', borderRadius: 3 }}>ACTIVE</span>}
                  </div>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-lo)', marginTop: 4 }}>
                    {p.focal_mm}mm {calc.focal_ratio} · {p.aperture_mm}mm aperture · {p.pixel_um}μm px · {p.res_x}×{p.res_y}
                  </div>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-mid)', marginTop: 3 }}>
                    Plate scale: <strong style={{ color: 'var(--teal)' }}>{calc.plate_scale_arcsec}″/px</strong>
                    {' · '}FOV: <strong style={{ color: 'var(--teal)' }}>{calc.fov_w}</strong>
                  </div>
                </div>
                <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                  {!isActive && (
                    <button onClick={() => setActiveId(p.id)} style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--amber)', background: 'var(--amber-glow)', border: '1px solid var(--amber-dim)', borderRadius: 3, padding: '3px 8px', cursor: 'pointer', whiteSpace: 'nowrap' }}>
                      Use
                    </button>
                  )}
                  <button onClick={() => startEdit(p)} style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--blue)', background: 'none', border: '1px solid var(--border)', borderRadius: 3, padding: '3px 8px', cursor: 'pointer' }}>
                    Edit
                  </button>
                  {profiles.length > 1 && (
                    <button onClick={() => deleteProfile(p.id)} style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--danger)', background: 'none', border: '1px solid var(--border)', borderRadius: 3, padding: '3px 8px', cursor: 'pointer' }}>
                      ✕
                    </button>
                  )}
                </div>
              </div>
            </div>
          );
        })}

        {(adding || editing) && (
          <div style={{ background: 'var(--bg-panel)', border: '1px solid var(--border-hi)', borderRadius: 6, padding: '14px 16px' }}>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-lo)', marginBottom: 10, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
              {editing ? 'Edit Profile' : 'New Profile'}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10, marginBottom: 10 }}>
              {[
                { key: 'name', label: 'Profile name', type: 'text', fullWidth: true },
                { key: 'focal_mm', label: 'Focal length (mm)', type: 'number' },
                { key: 'aperture_mm', label: 'Aperture (mm)', type: 'number' },
                { key: 'pixel_um', label: 'Pixel size (μm)', type: 'number' },
                { key: 'res_x', label: 'Sensor width (px)', type: 'number' },
                { key: 'res_y', label: 'Sensor height (px)', type: 'number' },
              ].map(field => (
                <div key={field.key} style={{ gridColumn: field.fullWidth ? '1 / -1' : undefined }}>
                  <label style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-lo)', display: 'block', marginBottom: 3 }}>
                    {field.label}
                  </label>
                  <input
                    type={field.type}
                    step={field.key === 'pixel_um' ? '0.01' : '1'}
                    value={(form as Record<string, string | number>)[field.key]}
                    onChange={e => setForm(f => ({ ...f, [field.key]: field.type === 'number' ? parseFloat(e.target.value) || 0 : e.target.value }))}
                    style={fieldStyle}
                  />
                </div>
              ))}
            </div>
            {form.focal_mm > 0 && form.pixel_um > 0 && (
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--teal)', marginBottom: 10 }}>
                Preview: {calcProfile(form).plate_scale_arcsec}″/px · {calcProfile(form).fov_w} FOV
              </div>
            )}
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={saveProfile} style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: '#fff', background: 'var(--amber)', border: 'none', borderRadius: 3, padding: '5px 14px', cursor: 'pointer' }}>
                Save
              </button>
              <button onClick={() => { setAdding(false); setEditing(null); }} style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-mid)', background: 'var(--bg-deep)', border: '1px solid var(--border)', borderRadius: 3, padding: '5px 14px', cursor: 'pointer' }}>
                Cancel
              </button>
            </div>
          </div>
        )}

        {!adding && !editing && (
          <button
            onClick={() => { setAdding(true); setEditing(null); }}
            style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--amber)', background: 'var(--bg-deep)', border: '1px dashed var(--amber-dim)', borderRadius: 4, padding: '8px 16px', cursor: 'pointer', textAlign: 'left' }}
          >
            + Add equipment profile
          </button>
        )}
      </div>
    </section>
  );
}

function HorizonPolarChart({ points }: { points: HorizonPoint[] }) {
  const size = 280;
  const cx = size / 2;
  const cy = size / 2;
  const r = 120;

  // Draw horizon profile as a polar chart
  const pathParts = points.map((p, i) => {
    const azRad = (p.az_deg - 90) * (Math.PI / 180);
    const altFrac = 1 - p.alt_deg / 90;
    const pr = altFrac * r;
    const x = cx + pr * Math.cos(azRad);
    const y = cy + pr * Math.sin(azRad);
    return `${i === 0 ? 'M' : 'L'} ${x.toFixed(1)} ${y.toFixed(1)}`;
  });
  if (pathParts.length) pathParts.push('Z');

  return (
    <svg width={size} height={size} style={{ display: 'block' }}>
      {/* Grid circles */}
      {[15, 30, 45, 60, 75, 90].map(alt => {
        const pr = (1 - alt / 90) * r;
        return (
          <g key={alt}>
            <circle cx={cx} cy={cy} r={pr}
              fill="none" stroke="var(--border)" strokeWidth={1} strokeDasharray={alt === 15 ? '4 4' : '2 4'}
            />
            <text x={cx + 3} y={cy - pr - 2} fill="var(--text-lo)" fontSize={8} fontFamily="IBM Plex Mono">{alt}°</text>
          </g>
        );
      })}
      {/* Cardinal lines */}
      {[0, 90, 180, 270].map(az => {
        const azRad = (az - 90) * (Math.PI / 180);
        return (
          <line key={az}
            x1={cx} y1={cy}
            x2={cx + r * Math.cos(azRad)} y2={cy + r * Math.sin(azRad)}
            stroke="var(--border)" strokeWidth={1}
          />
        );
      })}
      {/* Labels */}
      {[['N', 0], ['E', 90], ['S', 180], ['W', 270]].map(([label, az]) => {
        const azRad = ((az as number) - 90) * (Math.PI / 180);
        return (
          <text key={label as string}
            x={cx + (r + 14) * Math.cos(azRad)}
            y={cy + (r + 14) * Math.sin(azRad) + 4}
            textAnchor="middle"
            fill="var(--text-lo)"
            fontSize={10}
            fontFamily="IBM Plex Mono"
          >
            {label as string}
          </text>
        );
      })}
      {/* Horizon profile */}
      {pathParts.length > 0 && (
        <path d={pathParts.join(' ')} fill="rgba(232,131,42,0.15)" stroke="var(--amber)" strokeWidth={1.5} />
      )}
    </svg>
  );
}

export default function Settings() {
  const qc = useQueryClient();
  const { data: horizonData } = useQuery({
    queryKey: ['horizon'],
    queryFn: () => api.horizon.get(),
  });
  const { data: health } = useQuery({
    queryKey: ['health'],
    queryFn: () => api.health.get(),
  });

  const setHorizon = useMutation({
    mutationFn: (points: HorizonPoint[]) => api.horizon.set(points),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['horizon'] }),
  });

  const [recomputing, setRecomputing] = useState(false);
  const [recomputeMsg, setRecomputeMsg] = useState('');
  const [rebuilding, setRebuilding] = useState(false);
  const [rebuildResult, setRebuildResult] = useState<any>(null);
  const [showResetConfirm, setShowResetConfirm] = useState(false);
  const [resetting, setResetting] = useState(false);
  const [resetMsg, setResetMsg] = useState('');

  const triggerRecompute = async () => {
    setRecomputing(true);
    setRecomputeMsg('');
    try {
      const res = await fetch('/api/nightly/recompute', { method: 'POST' });
      if (res.ok) {
        setRecomputeMsg('Nightly recompute started — takes ~20s. Reload the Targets page when done.');
      } else {
        setRecomputeMsg('Backend returned an error. Check logs.');
      }
    } catch {
      setRecomputeMsg('Error reaching backend.');
    }
    setRecomputing(false);
  };

  const triggerFactoryReset = async () => {
    setResetting(true);
    setResetMsg('');
    setShowResetConfirm(false);
    try {
      const res = await fetch('/api/factory-reset', { method: 'POST' });
      if (res.ok) {
        setResetMsg('Reset started. Catalog is rebuilding (~60s). Reload the page when done.');
        qc.invalidateQueries({ queryKey: ['health'] });
        qc.invalidateQueries({ queryKey: ['targets'] });
      } else {
        const d = await res.json().catch(() => ({}));
        setResetMsg((d as { error?: string }).error ?? 'Backend returned an error.');
      }
    } catch {
      setResetMsg('Error reaching backend.');
    }
    setResetting(false);
  };

  const triggerRebuild = async () => {
    setRebuilding(true);
    setRebuildResult(null);
    try {
      const res = await fetch('/api/catalog/rebuild');
      if (res.ok) {
        const data = await res.json();
        if (data.status === 'success') {
          setRebuildResult({
            status: 'success',
            message: `Rebuild complete: ${data.total} objects. Starting automatic nightly recompute...`,
            ...data
          });
          // Invalidate queries to refresh the catalog
          qc.invalidateQueries({ queryKey: ['targets'] });
          qc.invalidateQueries({ queryKey: ['health'] });
          // Wait for nightly recompute to complete (~30s) then reload
          setTimeout(() => window.location.reload(), 4000);
        } else {
          setRebuildResult({ error: 'Unexpected response from server.' });
        }
      } else {
        const errorData = await res.json().catch(() => ({}));
        setRebuildResult({ error: errorData.error || 'Backend returned an error. Check logs.' });
      }
    } catch (err) {
      setRebuildResult({ error: `Error reaching backend: ${String(err)}` });
    }
    setRebuilding(false);
  };

  const handleHorizonCSV = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const text = await file.text();
    const lines = text.trim().split('\n').slice(1); // skip header
    const points: HorizonPoint[] = [];
    for (const line of lines) {
      const [az, alt] = line.split(',').map(Number);
      if (!isNaN(az) && !isNaN(alt)) {
        points.push({ az_deg: Math.round(az) % 360, alt_deg: Math.max(0, Math.min(90, alt)) });
      }
    }
    if (points.length === 360) {
      setHorizon.mutate(points);
    } else {
      alert(`CSV must have exactly 360 rows (got ${points.length}). Format: az_deg,alt_deg`);
    }
  };

  const resetHorizon = () => {
    const flat: HorizonPoint[] = Array.from({ length: 360 }, (_, i) => ({ az_deg: i, alt_deg: 15.0 }));
    setHorizon.mutate(flat);
  };

  return (
    <div className="page-body">
      <h1 style={{ fontFamily: 'var(--font-display)', fontSize: 22, marginBottom: 24 }}>Settings</h1>

      {/* Equipment Profiles */}
      <EquipmentProfiles />

      {/* Custom Horizon */}
      <section style={{ marginBottom: 32 }}>
        <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 16, marginBottom: 14, color: 'var(--text-hi)' }}>
          Custom Horizon Profile
        </h2>
        <div style={{ display: 'flex', gap: 24, alignItems: 'flex-start' }}>
          {horizonData?.points && <HorizonPolarChart points={horizonData.points} />}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            <div style={{ fontSize: 12, color: 'var(--text-mid)', maxWidth: 300 }}>
              Upload a CSV file with columns <code>az_deg,alt_deg</code>, one row per degree (360 rows total).
            </div>
            <label style={{
              display: 'inline-flex',
              alignItems: 'center',
              padding: '6px 14px',
              background: 'var(--bg-panel)',
              border: '1px solid var(--border-hi)',
              borderRadius: 4,
              cursor: 'pointer',
              fontFamily: 'var(--font-mono)',
              fontSize: 12,
              color: 'var(--text-hi)',
            }}>
              ↑ Upload CSV
              <input type="file" accept=".csv" style={{ display: 'none' }} onChange={handleHorizonCSV} />
            </label>
            <button
              onClick={resetHorizon}
              style={{
                padding: '6px 14px',
                background: 'var(--bg-deep)',
                border: '1px solid var(--border)',
                borderRadius: 4,
                fontFamily: 'var(--font-mono)',
                fontSize: 12,
                color: 'var(--text-mid)',
                cursor: 'pointer',
              }}
            >
              Reset to Flat 15°
            </button>
            {setHorizon.isSuccess && (
              <div style={{ color: 'var(--good)', fontSize: 12, fontFamily: 'var(--font-mono)' }}>
                ✓ Horizon updated
              </div>
            )}
          </div>
        </div>
      </section>

      {/* App Info */}
      <section>
        <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 16, marginBottom: 14, color: 'var(--text-hi)' }}>
          App Info
        </h2>
        <div style={{ background: 'var(--bg-panel)', border: '1px solid var(--border)', borderRadius: 6, padding: '14px 18px', maxWidth: 440 }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', marginBottom: 12 }}>
            <tbody>
              {[
                ['Status', health?.status ?? '—'],
                ['Catalog size', health?.catalog_size != null ? `${health.catalog_size.toLocaleString()} objects` : '—'],
                ['Last refreshed', health?.catalog_last_refreshed
                  ? new Date(health.catalog_last_refreshed * 1000).toLocaleString('fr-FR', { dateStyle: 'medium', timeStyle: 'short' })
                  : '—'],
                ['DB size', health?.db_size_bytes != null
                  ? health.db_size_bytes < 1024 * 1024
                    ? `${Math.round(health.db_size_bytes / 1024)} KB`
                    : `${(health.db_size_bytes / 1024 / 1024).toFixed(1)} MB`
                  : '—'],
                ['Backend version', health?.version ?? '—'],
              ].map(([label, value]) => (
                <tr key={label}>
                  <td style={{ color: 'var(--text-lo)', fontFamily: 'var(--font-mono)', fontSize: 12, paddingBottom: 8, width: '45%' }}>{label}</td>
                  <td style={{ color: 'var(--text-hi)', fontFamily: 'var(--font-mono)', fontSize: 12 }}>{value}</td>
                </tr>
              ))}
            </tbody>
          </table>
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
            <button
              onClick={triggerRebuild}
              disabled={rebuilding}
              style={{
                padding: '6px 16px',
                background: 'var(--blue)',
                color: '#fff',
                borderRadius: 4,
                fontFamily: 'var(--font-mono)',
                fontSize: 12,
                opacity: rebuilding ? 0.6 : 1,
                cursor: rebuilding ? 'default' : 'pointer',
              }}
            >
              {rebuilding ? 'Rebuilding…' : 'Rebuild Catalog'}
            </button>
            <button
              onClick={triggerRecompute}
              disabled={recomputing}
              style={{
                padding: '6px 16px',
                background: 'var(--bg-deep)',
                border: '1px solid var(--border-hi)',
                color: 'var(--text-hi)',
                borderRadius: 4,
                fontFamily: 'var(--font-mono)',
                fontSize: 12,
                opacity: recomputing ? 0.6 : 1,
                cursor: recomputing ? 'default' : 'pointer',
              }}
            >
              {recomputing ? 'Starting…' : 'Recompute Tonight'}
            </button>
          </div>

          {/* Factory Reset */}
          <div style={{ marginTop: 18, borderTop: '1px solid var(--border)', paddingTop: 14 }}>
            {!showResetConfirm ? (
              <button
                onClick={() => setShowResetConfirm(true)}
                disabled={resetting}
                style={{
                  padding: '6px 16px',
                  background: 'rgba(224,82,82,0.1)',
                  border: '1px solid rgba(224,82,82,0.4)',
                  color: 'var(--danger)',
                  borderRadius: 4,
                  fontFamily: 'var(--font-mono)',
                  fontSize: 12,
                  cursor: resetting ? 'default' : 'pointer',
                  opacity: resetting ? 0.6 : 1,
                }}
              >
                {resetting ? 'Resetting…' : 'Factory Reset'}
              </button>
            ) : (
              <div style={{ background: 'rgba(224,82,82,0.08)', border: '1px solid rgba(224,82,82,0.3)', borderRadius: 4, padding: '12px 14px' }}>
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--danger)', marginBottom: 8, fontWeight: 600 }}>
                  Factory Reset
                </div>
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-mid)', marginBottom: 10, lineHeight: 1.5 }}>
                  Clears catalog, nightly cache, and weather data. Triggers a full rebuild (~60s).
                  <br />
                  <strong style={{ color: 'var(--text-hi)' }}>Imaging logs, gallery, PHD2 logs, and horizon are preserved.</strong>
                </div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button
                    onClick={triggerFactoryReset}
                    style={{
                      padding: '5px 14px',
                      background: 'var(--danger)',
                      color: '#fff',
                      border: 'none',
                      borderRadius: 3,
                      fontFamily: 'var(--font-mono)',
                      fontSize: 12,
                      cursor: 'pointer',
                    }}
                  >
                    Confirm Reset
                  </button>
                  <button
                    onClick={() => setShowResetConfirm(false)}
                    style={{
                      padding: '5px 14px',
                      background: 'var(--bg-deep)',
                      border: '1px solid var(--border)',
                      color: 'var(--text-mid)',
                      borderRadius: 3,
                      fontFamily: 'var(--font-mono)',
                      fontSize: 12,
                      cursor: 'pointer',
                    }}
                  >
                    Cancel
                  </button>
                </div>
              </div>
            )}
          </div>
          {recomputeMsg && (
            <div style={{ marginTop: 8, fontSize: 12, color: 'var(--text-mid)', fontFamily: 'var(--font-mono)' }}>
              {recomputeMsg}
            </div>
          )}
          {resetMsg && (
            <div style={{ marginTop: 8, fontSize: 12, color: resetting ? 'var(--text-mid)' : 'var(--good)', fontFamily: 'var(--font-mono)' }}>
              {resetMsg}
            </div>
          )}
          {rebuildResult && (
            <div style={{ marginTop: 12, fontSize: 11, color: 'var(--text-mid)', fontFamily: 'var(--font-mono)', background: 'var(--bg-row)', padding: '10px 12px', borderRadius: 4 }}>
              {rebuildResult.error ? (
                <div style={{ color: 'var(--danger)' }}>{rebuildResult.error}</div>
              ) : rebuildResult.message ? (
                <div style={{ color: 'var(--good)' }}>{rebuildResult.message}</div>
              ) : (
                <>
                  <div><strong>Total:</strong> {rebuildResult.total?.toLocaleString() || '?'} entries</div>
                  <div style={{ marginTop: 6 }}>
                    <strong>By Type:</strong>
                    {rebuildResult.by_type && Object.entries(rebuildResult.by_type).length > 0 ? (
                      <div style={{ marginLeft: 12, marginTop: 4 }}>
                        {Object.entries(rebuildResult.by_type).map(([type, count]: [string, any]) => (
                          <div key={type} style={{ fontSize: 10 }}>{type}: {count}</div>
                        ))}
                      </div>
                    ) : (
                      <div style={{ marginLeft: 12, marginTop: 4, fontSize: 10 }}>None</div>
                    )}
                  </div>
                  <div style={{ marginTop: 6 }}>
                    <strong>Messier:</strong> {rebuildResult.messier_count || 0}
                    <span style={{ color: 'var(--text-lo)', marginLeft: 8 }}>({rebuildResult.has_sizes || 0} with size data)</span>
                  </div>
                </>
              )}
            </div>
          )}
        </div>
      </section>
    </div>
  );
}
