// SPDX-License-Identifier: GPL-3.0-or-later

import { useState, useEffect } from 'react';
import { Clock, HardDrive, Calendar, Tag, Trash2, Eye, RefreshCw, Download } from 'lucide-react';
import { useBackend } from '../contexts/BackendContext';
import { useToast } from '../components/Toast';
import Card from '../components/Card';
import Alert from '../components/Alert';
import Modal from '../components/Modal';
import { formatBytes, formatDateTime, formatRelativeTime } from '../lib/utils';
import type { Snapshot } from '../lib/api';

export default function Snapshots() {
  const { listSnapshots, getSnapshot, deleteSnapshot, startRestore } = useBackend();
  const toast = useToast();
  const [snapshots, setSnapshots] = useState<Snapshot[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [isRefreshing, setIsRefreshing] = useState(false);

  // Detail modal
  const [selectedSnapshot, setSelectedSnapshot] = useState<Snapshot | null>(null);
  const [showDetailModal, setShowDetailModal] = useState(false);

  // Delete confirmation
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [isDeleting, setIsDeleting] = useState(false);

  // Restore modal
  const [showRestoreModal, setShowRestoreModal] = useState(false);
  const [restoreTarget, setRestoreTarget] = useState('');
  const [isRestoring, setIsRestoring] = useState(false);

  const fetchSnapshots = async () => {
    try {
      const result = await listSnapshots();
      setSnapshots(result);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load snapshots');
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchSnapshots();
  }, [listSnapshots]);

  const handleRefresh = async () => {
    setIsRefreshing(true);
    await fetchSnapshots();
    setIsRefreshing(false);
  };

  const handleViewDetail = async (snapshot: Snapshot) => {
    try {
      const detail = await getSnapshot(snapshot.id);
      setSelectedSnapshot(detail);
      setShowDetailModal(true);
    } catch {
      setSelectedSnapshot(snapshot);
      setShowDetailModal(true);
    }
  };

  const handleDelete = async () => {
    if (!deletingId) return;
    setIsDeleting(true);
    try {
      await deleteSnapshot(deletingId);
      toast.success('Snapshot deleted');
      setDeletingId(null);
      await fetchSnapshots();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to delete snapshot');
    } finally {
      setIsDeleting(false);
    }
  };

  const handleRestore = async () => {
    if (!selectedSnapshot || !restoreTarget.trim()) return;
    setIsRestoring(true);
    try {
      await startRestore(selectedSnapshot.id, restoreTarget.trim());
      toast.info('Restore started');
      setShowRestoreModal(false);
      setShowDetailModal(false);
      setSelectedSnapshot(null);
      setRestoreTarget('');
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to start restore');
    } finally {
      setIsRestoring(false);
    }
  };

  if (isLoading) {
    return (
      <div className="flex flex-col items-center justify-center h-64 space-y-3">
        <div className="animate-spin rounded-full h-8 w-8 border-2 border-primary-600 border-t-transparent"></div>
        <p className="text-sm text-slate-500 dark:text-slate-400">
          Loading snapshots via Tor — this may take a minute…
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-slate-900 dark:text-white">Snapshots</h1>
          <p className="text-slate-600 dark:text-slate-400 mt-1">
            Browse your backup history ({snapshots.length} snapshot{snapshots.length !== 1 ? 's' : ''})
          </p>
        </div>
        <button onClick={handleRefresh} disabled={isRefreshing} className="btn-secondary">
          <RefreshCw className={`w-4 h-4 mr-2 ${isRefreshing ? 'animate-spin' : ''}`} />
          Refresh
        </button>
      </div>

      {/* Error */}
      {error && (
        <Alert type="error" onClose={() => setError(null)}>
          {error}
        </Alert>
      )}

      {/* Snapshots List */}
      {snapshots.length === 0 ? (
        <Card>
          <div className="text-center py-12">
            <Clock className="w-16 h-16 text-slate-300 dark:text-slate-600 mx-auto mb-4" />
            <h3 className="text-lg font-medium text-slate-900 dark:text-white mb-2">
              No Snapshots Yet
            </h3>
            <p className="text-slate-500 dark:text-slate-400 max-w-sm mx-auto">
              Create your first backup to see snapshots here. Each backup creates a new snapshot of your files.
            </p>
          </div>
        </Card>
      ) : (
        <div className="space-y-4">
          {snapshots.map((snapshot) => (
            <Card key={snapshot.id}>
              <div className="flex items-start justify-between">
                <div className="flex items-start space-x-4">
                  <div className="p-3 rounded-lg bg-primary-100 dark:bg-primary-900/30">
                    <HardDrive className="w-6 h-6 text-primary-600" />
                  </div>
                  <div>
                    <div className="flex items-center space-x-2">
                      <h3 className="font-mono text-sm font-medium text-slate-900 dark:text-white">
                        {snapshot.id.substring(0, 8)}
                      </h3>

                    </div>
                    <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
                      {snapshot.hostname}
                    </p>
                    
                    {/* Paths */}
                    <div className="mt-3 space-y-1">
                      {snapshot.paths.map((path) => (
                        <p key={path} className="text-sm text-slate-600 dark:text-slate-300 font-mono">
                          {path}
                        </p>
                      ))}
                    </div>

                    {/* Tags */}
                    {snapshot.tags && Object.keys(snapshot.tags).length > 0 && (
                      <div className="mt-3 flex items-center space-x-2">
                        <Tag className="w-3.5 h-3.5 text-slate-400" />
                        <div className="flex flex-wrap gap-1">
                          {Object.keys(snapshot.tags).map((tag) => (
                            <span
                              key={tag}
                              className="px-2 py-0.5 text-xs rounded bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300"
                            >
                              {tag}
                            </span>
                          ))}
                        </div>
                      </div>
                    )}
                  </div>
                </div>

                <div className="text-right space-y-1">
                  <div className="flex items-center text-sm text-slate-500 dark:text-slate-400">
                    <Calendar className="w-4 h-4 mr-1.5" />
                    {formatRelativeTime(snapshot.time)}
                  </div>
                  <p className="text-xs text-slate-400 dark:text-slate-500">
                    {formatDateTime(snapshot.time)}
                  </p>
                  {snapshot.size && (
                    <p className="text-sm text-slate-600 dark:text-slate-300">
                      {formatBytes(snapshot.size)}
                    </p>
                  )}
                  <div className="flex items-center space-x-1 justify-end pt-1">
                    <button
                      onClick={() => handleViewDetail(snapshot)}
                      className="p-1.5 rounded hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-400 hover:text-primary-600 transition-colors"
                      title="View details"
                    >
                      <Eye className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() => { setSelectedSnapshot(snapshot); setRestoreTarget(''); setShowRestoreModal(true); }}
                      className="p-1.5 rounded hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-400 hover:text-green-600 transition-colors"
                      title="Restore"
                    >
                      <Download className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() => setDeletingId(snapshot.id)}
                      className="p-1.5 rounded hover:bg-red-50 dark:hover:bg-red-900/20 text-slate-400 hover:text-red-600 transition-colors"
                      title="Delete snapshot"
                    >
                      <Trash2 className="w-4 h-4" />
                    </button>
                  </div>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}

      {/* Delete Confirmation Modal */}
      <Modal
        isOpen={!!deletingId}
        onClose={() => setDeletingId(null)}
        title="Delete Snapshot"
      >
        <div className="space-y-4">
          <Alert type="warning">
            <p>Are you sure you want to delete snapshot <code className="font-mono">{deletingId?.substring(0, 8)}</code>?</p>
            <p className="text-sm mt-1">This snapshot will be permanently removed from your backup history.</p>
          </Alert>
          <div className="flex justify-end space-x-3">
            <button onClick={() => setDeletingId(null)} className="btn-secondary">Cancel</button>
            <button
              onClick={handleDelete}
              disabled={isDeleting}
              className="btn-primary bg-red-600 hover:bg-red-700"
            >
              {isDeleting ? 'Deleting...' : 'Delete Snapshot'}
            </button>
          </div>
        </div>
      </Modal>

      {/* Snapshot Detail Modal */}
      <Modal
        isOpen={showDetailModal}
        onClose={() => { setShowDetailModal(false); setSelectedSnapshot(null); }}
        title="Snapshot Details"
        size="lg"
      >
        {selectedSnapshot && (
          <div className="space-y-4">
            <div className="bg-slate-50 dark:bg-slate-700/50 rounded-lg p-4 space-y-2">
              <div className="flex justify-between">
                <span className="text-sm text-slate-500 dark:text-slate-400">Snapshot ID</span>
                <span className="text-sm font-mono text-slate-900 dark:text-white">{selectedSnapshot.id}</span>
              </div>
              <div className="flex justify-between">
                <span className="text-sm text-slate-500 dark:text-slate-400">Date</span>
                <span className="text-sm text-slate-900 dark:text-white">{formatDateTime(selectedSnapshot.time)}</span>
              </div>
              <div className="flex justify-between">
                <span className="text-sm text-slate-500 dark:text-slate-400">Hostname</span>
                <span className="text-sm text-slate-900 dark:text-white">{selectedSnapshot.hostname}</span>
              </div>
              {selectedSnapshot.size && (
                <div className="flex justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Size</span>
                  <span className="text-sm text-slate-900 dark:text-white">{formatBytes(selectedSnapshot.size)}</span>
                </div>
              )}
            </div>

            {/* Paths */}
            <div>
              <h4 className="text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Paths ({selectedSnapshot.paths.length})</h4>
              <div className="space-y-1 max-h-40 overflow-y-auto">
                {selectedSnapshot.paths.map((path) => (
                  <p key={path} className="text-sm font-mono text-slate-600 dark:text-slate-400">{path}</p>
                ))}
              </div>
            </div>

            {/* Tags */}
            {selectedSnapshot.tags && Object.keys(selectedSnapshot.tags).length > 0 && (
              <div>
                <h4 className="text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Tags</h4>
                <div className="flex flex-wrap gap-2">
                  {Object.entries(selectedSnapshot.tags).map(([key, value]) => (
                    <span key={key} className="px-2 py-1 text-xs rounded bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300">
                      {key}: {value}
                    </span>
                  ))}
                </div>
              </div>
            )}

            <div className="flex justify-end space-x-3 pt-2">
              <button onClick={() => { setShowDetailModal(false); setSelectedSnapshot(null); }} className="btn-secondary">
                Close
              </button>
              <button
                onClick={() => { setRestoreTarget(''); setShowRestoreModal(true); }}
                className="btn-primary"
              >
                <Download className="w-4 h-4 mr-2" />
                Restore
              </button>
            </div>
          </div>
        )}
      </Modal>

      {/* Restore from Snapshot Modal */}
      <Modal
        isOpen={showRestoreModal}
        onClose={() => { setShowRestoreModal(false); setRestoreTarget(''); }}
        title="Restore Snapshot"
      >
        {selectedSnapshot && (
          <div className="space-y-4">
            <div className="p-4 bg-slate-50 dark:bg-slate-700/50 rounded-lg">
              <div className="flex items-center justify-between mb-2">
                <span className="text-sm text-slate-500 dark:text-slate-400">Snapshot</span>
                <span className="font-mono text-sm text-slate-900 dark:text-white">
                  {selectedSnapshot.id.substring(0, 8)}
                </span>
              </div>
              <div className="flex items-center justify-between">
                <span className="text-sm text-slate-500 dark:text-slate-400">Date</span>
                <span className="text-sm text-slate-900 dark:text-white">
                  {formatDateTime(selectedSnapshot.time)}
                </span>
              </div>
            </div>
            <div>
              <label className="label">Restore to Directory</label>
              <input
                type="text"
                value={restoreTarget}
                onChange={(e) => setRestoreTarget(e.target.value)}
                placeholder="/home/user/restored"
                className="input"
                autoFocus
              />
            </div>
            <Alert type="warning">Existing files in the target directory may be overwritten.</Alert>
            <div className="flex justify-end space-x-3 pt-2">
              <button onClick={() => { setShowRestoreModal(false); setRestoreTarget(''); }} className="btn-secondary">Cancel</button>
              <button
                onClick={handleRestore}
                disabled={!restoreTarget.trim() || isRestoring}
                className="btn-primary"
              >
                {isRestoring ? 'Starting...' : 'Start Restore'}
              </button>
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
