import { ArrowLeft, Play, RefreshCw } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { api, errorMessage } from '../api.js';
import { JobStatusPanel } from './JobStatusPanel.jsx';
import { RestoreModal } from './RestoreModal.jsx';
import { SnapshotFilesPanel } from './SnapshotFilesPanel.jsx';
import { SnapshotTable } from './SnapshotTable.jsx';

export function VMDetail({ jobs, onBack, onChanged, vm }) {
  const [snapshots, setSnapshots] = useState([]);
  const [selectedSnapshot, setSelectedSnapshot] = useState(null);
  const [inspectedSnapshot, setInspectedSnapshot] = useState(null);
  const [snapshotFiles, setSnapshotFiles] = useState([]);
  const [snapshotFilesLoading, setSnapshotFilesLoading] = useState(false);
  const [confirmText, setConfirmText] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  const vmJobs = useMemo(() => jobs.filter((job) => job.vmName === vm.name && job.nodeId === vm.nodeId), [jobs, vm.name, vm.nodeId]);
  const visibleJob = vmJobs.find((job) => ['queued', 'running'].includes(job.status)) || vmJobs[0] || null;
  const latestSnapshot = snapshots[0]?.time;

  async function loadSnapshots() {
    setError('');
    try {
      const result = await api.get(`/snapshots/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`);
      setSnapshots(result.data);
    } catch (requestError) {
      setError(errorMessage(requestError));
    }
  }

  useEffect(() => {
    loadSnapshots();
  }, [vm.name, vm.nodeId]);

  async function createBackup() {
    setBusy(true);
    setError('');
    try {
      await api.post(`/backup/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`);
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    } finally {
      setBusy(false);
    }
  }

  async function confirmRestore() {
    setBusy(true);
    setError('');
    try {
      await api.post(`/restore/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}`, {
        snapshotId: selectedSnapshot.id,
        confirmVmName: confirmText,
      });
      setSelectedSnapshot(null);
      setConfirmText('');
      await onChanged();
    } catch (requestError) {
      setError(errorMessage(requestError));
    } finally {
      setBusy(false);
    }
  }

  async function inspectSnapshot(snapshot) {
    setInspectedSnapshot(snapshot);
    setSnapshotFiles([]);
    setSnapshotFilesLoading(true);
    setError('');
    try {
      const result = await api.get(`/snapshots/${encodeURIComponent(vm.nodeId)}/${encodeURIComponent(vm.name)}/${encodeURIComponent(snapshot.id)}/files`);
      setSnapshotFiles(result.data);
    } catch (requestError) {
      setError(errorMessage(requestError));
    } finally {
      setSnapshotFilesLoading(false);
    }
  }

  return (
    <section className="space-y-5">
      <div className="flex flex-col gap-4 border-b border-zinc-800 pb-5 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <button className="mb-4 inline-flex items-center gap-2 text-sm text-zinc-400 hover:text-zinc-100" onClick={onBack} type="button">
            <ArrowLeft className="h-4 w-4" />
            Back
          </button>
          <div className="flex items-center gap-3">
            <h1 className="text-2xl font-semibold text-zinc-100">{vm.name}</h1>
            <span className="rounded-md border border-zinc-800 px-2 py-1 text-xs text-zinc-300">{vm.type === 'container' ? 'Container' : 'VM'}</span>
            <span className="rounded-md border border-zinc-800 px-2 py-1 text-xs text-zinc-300">{vm.status || 'Unknown'}</span>
          </div>
          <p className="mt-2 text-sm text-zinc-500">Node: {vm.nodeName || '-'}</p>
          <p className="mt-2 text-sm text-zinc-500">Latest snapshot: {latestSnapshot ? formatTime(latestSnapshot) : 'None'}</p>
        </div>
        <div className="flex gap-2">
          <button className="inline-flex h-9 items-center gap-2 rounded-md border border-zinc-700 px-3 text-sm text-zinc-100" onClick={loadSnapshots} type="button">
            <RefreshCw className="h-4 w-4" />
            Snapshots
          </button>
          <button
            className="inline-flex h-9 items-center gap-2 rounded-md border border-emerald-800 bg-emerald-950 px-3 text-sm text-emerald-100 hover:bg-emerald-900"
            disabled={busy || Boolean(visibleJob && ['queued', 'running'].includes(visibleJob.status))}
            onClick={createBackup}
            type="button"
          >
            <Play className="h-4 w-4" />
            Create Backup
          </button>
        </div>
      </div>

      {error ? <div className="rounded-md border border-amber-900 bg-amber-950/50 px-4 py-3 text-sm text-amber-200">{error}</div> : null}

      <JobStatusPanel job={visibleJob} />
      <SnapshotTable
        snapshots={snapshots}
        onInspect={inspectSnapshot}
        onRestore={(snapshot) => {
          if (vm.type === 'container') {
            setError('Container restore is not implemented yet. Backups are available, restore needs a safe zfs receive workflow.');
            return;
          }
          setSelectedSnapshot(snapshot);
        }}
      />
      <SnapshotFilesPanel
        files={snapshotFiles}
        loading={snapshotFilesLoading}
        onClose={() => {
          setInspectedSnapshot(null);
          setSnapshotFiles([]);
        }}
        snapshot={inspectedSnapshot}
      />
      <RestoreModal
        busy={busy}
        confirmText={confirmText}
        onCancel={() => {
          setSelectedSnapshot(null);
          setConfirmText('');
        }}
        onConfirm={confirmRestore}
        onTextChange={setConfirmText}
        snapshot={selectedSnapshot}
        vmName={vm.name}
      />
    </section>
  );
}

function formatTime(value) {
  return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'medium' }).format(new Date(value));
}
