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

import { useState, useEffect } from 'react';
import { Download, FolderOpen, Clock, Play } from 'lucide-react';
import { useBackend } from '../contexts/BackendContext';
import Card from '../components/Card';
import ProgressBar from '../components/ProgressBar';
import Alert from '../components/Alert';
import Modal from '../components/Modal';
import { formatRelativeTime, formatDateTime } from '../lib/utils';
import type { Snapshot, Job } from '../lib/api';
import * as api from '../lib/api';

export default function Restore() {
  const { listSnapshots, startRestore, listJobs, cancelJob } = useBackend();
  const [snapshots, setSnapshots] = useState<Snapshot[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [activeJob, setActiveJob] = useState<Job | null>(null);

  // Restore modal
  const [showRestoreModal, setShowRestoreModal] = useState(false);
  const [selectedSnapshot, setSelectedSnapshot] = useState<Snapshot | null>(null);
  const [restoreTarget, setRestoreTarget] = useState('');
  const [isRestoring, setIsRestoring] = useState(false);

  // Load snapshots and check for active restore
  useEffect(() => {
    const load = async () => {
      try {
        const [snapshotResult, jobs] = await Promise.all([
          listSnapshots(),
          listJobs(),
        ]);
        setSnapshots(snapshotResult);
        
        // Find active restore job
        const restoreJob = jobs.find(
          (j) => j.type === 'restore' && (j.status === 'running' || j.status === 'pending')
        );
        setActiveJob(restoreJob || null);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to load data');
      } finally {
        setIsLoading(false);
      }
    };
    load();
  }, [listSnapshots, listJobs]);

  // Poll for job updates when restore is running
  useEffect(() => {
    if (!activeJob) return;

    const pollJob = async () => {
      try {
        const job = await api.getJob(activeJob.id);
        setActiveJob(job);

        if (job.status === 'completed') {
          setSuccess('Restore completed successfully!');
          setActiveJob(null);
        } else if (job.status === 'failed') {
          setError(job.error || 'Restore failed');
          setActiveJob(null);
        }
      } catch (err) {
        console.error('Failed to poll job:', err);
      }
    };

    const interval = setInterval(pollJob, 1000);
    return () => clearInterval(interval);
  }, [activeJob?.id]);

  const handleRestoreClick = (snapshot: Snapshot) => {
    setSelectedSnapshot(snapshot);
    setRestoreTarget('');
    setShowRestoreModal(true);
  };

  const handleRestore = async () => {
    if (!selectedSnapshot || !restoreTarget.trim()) return;

    setIsRestoring(true);
    setError(null);

    try {
      const job = await startRestore(selectedSnapshot.id, restoreTarget.trim());
      setActiveJob(job);
      setShowRestoreModal(false);
      setSelectedSnapshot(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to start restore');
    } finally {
      setIsRestoring(false);
    }
  };

  const handleCancelRestore = async () => {
    if (!activeJob) return;

    try {
      await cancelJob(activeJob.id);
      setActiveJob(null);
      setError('Restore cancelled');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to cancel restore');
    }
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-8 w-8 border-2 border-primary-600 border-t-transparent"></div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-slate-900 dark:text-white">Restore</h1>
        <p className="text-slate-600 dark:text-slate-400 mt-1">
          Restore files from your backups
        </p>
      </div>

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

      {/* Active Restore Progress */}
      {activeJob && (
        <Card title="Restore in Progress">
          <div className="space-y-4">
            <div className="flex items-center justify-between">
              <div className="flex items-center space-x-3">
                <div className="p-2 rounded-lg bg-green-100 dark:bg-green-900/30">
                  <Download className="w-5 h-5 text-green-600" />
                </div>
                <div>
                  <p className="font-medium text-slate-900 dark:text-white">
                    Restoring files...
                  </p>
                  <p className="text-sm text-slate-500 dark:text-slate-400">
                    Started {formatRelativeTime(activeJob.started_at)}
                  </p>
                </div>
              </div>
              <button
                onClick={handleCancelRestore}
                className="btn-ghost text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20"
              >
                Cancel
              </button>
            </div>
            <ProgressBar value={activeJob.progress} size="lg" color="success" />
            <p className="text-sm text-slate-500 dark:text-slate-400 text-center">
              {activeJob.progress}% complete
            </p>
          </div>
        </Card>
      )}

      {/* Select Snapshot */}
      <Card title="Select Snapshot" subtitle="Choose a backup to restore from">
        {snapshots.length === 0 ? (
          <div className="text-center py-12">
            <Clock className="w-12 h-12 text-slate-300 dark:text-slate-600 mx-auto mb-3" />
            <p className="text-slate-500 dark:text-slate-400">No snapshots available</p>
            <p className="text-sm text-slate-400 dark:text-slate-500 mt-1">
              Create a backup first to restore from
            </p>
          </div>
        ) : (
          <div className="divide-y divide-slate-200 dark:divide-slate-700">
            {snapshots.map((snapshot) => (
              <div
                key={snapshot.id}
                className="py-4 flex items-center justify-between hover:bg-slate-50 dark:hover:bg-slate-700/50 -mx-6 px-6 transition-colors"
              >
                <div className="flex items-center space-x-4 min-w-0">
                  <div className="p-2 rounded-lg bg-slate-100 dark:bg-slate-700">
                    <FolderOpen className="w-5 h-5 text-slate-600 dark:text-slate-400" />
                  </div>
                  <div className="min-w-0">
                    <div className="flex items-center space-x-2">
                      <p className="font-mono text-sm font-medium text-slate-900 dark:text-white">
                        {snapshot.id.substring(0, 8)}
                      </p>
                      <span className="text-xs text-slate-500 dark:text-slate-400">
                        {formatRelativeTime(snapshot.time)}
                      </span>
                    </div>
                    <p className="text-sm text-slate-500 dark:text-slate-400 truncate">
                      {snapshot.paths.join(', ')}
                    </p>
                  </div>
                </div>
                <button
                  onClick={() => handleRestoreClick(snapshot)}
                  disabled={!!activeJob}
                  className="btn-secondary text-sm"
                >
                  <Download className="w-4 h-4 mr-1.5" />
                  Restore
                </button>
              </div>
            ))}
          </div>
        )}
      </Card>

      {/* Restore Modal */}
      <Modal
        isOpen={showRestoreModal}
        onClose={() => {
          setShowRestoreModal(false);
          setSelectedSnapshot(null);
        }}
        title="Restore Snapshot"
        size="lg"
      >
        {selectedSnapshot && (
          <div className="space-y-4">
            {/* Snapshot Info */}
            <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 mb-2">
                <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 items-center justify-between">
                <span className="text-sm text-slate-500 dark:text-slate-400">Paths</span>
                <span className="text-sm text-slate-900 dark:text-white">
                  {selectedSnapshot.paths.length} path(s)
                </span>
              </div>
            </div>

            {/* Target Directory */}
            <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
              />
              <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
                Files will be restored to this directory
              </p>
            </div>

            {/* Warning */}
            <Alert type="warning">
              Existing files in the target directory may be overwritten.
            </Alert>

            {/* Actions */}
            <div className="flex justify-end space-x-3 pt-2">
              <button
                onClick={() => {
                  setShowRestoreModal(false);
                  setSelectedSnapshot(null);
                }}
                className="btn-secondary"
              >
                Cancel
              </button>
              <button
                onClick={handleRestore}
                disabled={!restoreTarget.trim() || isRestoring}
                className="btn-primary"
              >
                {isRestoring ? (
                  <>
                    <div className="animate-spin rounded-full h-4 w-4 border-2 border-white border-t-transparent mr-2"></div>
                    Starting...
                  </>
                ) : (
                  <>
                    <Play className="w-4 h-4 mr-2" />
                    Start Restore
                  </>
                )}
              </button>
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
