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

import { useState, useEffect } from 'react';
import { Upload, Play, Square, CheckCircle, AlertCircle, FolderOpen } from 'lucide-react';
import { useBackend } from '../contexts/BackendContext';
import { useToast } from '../components/Toast';
import Card from '../components/Card';
import ProgressBar from '../components/ProgressBar';
import Alert from '../components/Alert';
import { CardSkeleton, ListItemSkeleton } from '../components/Skeleton';
import { formatRelativeTime } from '../lib/utils';
import type { Job, PathInfo } from '../lib/api';
import * as api from '../lib/api';

export default function Backup() {
  const { account, getPaths, startBackup, listJobs, cancelJob } = useBackend();
  const toast = useToast();
  const [paths, setPaths] = useState<PathInfo[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isStarting, setIsStarting] = useState(false);
  const [activeJob, setActiveJob] = useState<Job | null>(null);
  const [error, setError] = useState<string | null>(null);

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

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

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

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

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

  const handleStartBackup = async () => {
    setIsStarting(true);
    setError(null);

    try {
      // Get paths that exist
      const validPaths = paths.filter((p) => p.exists).map((p) => p.path);
      
      if (validPaths.length === 0) {
        throw new Error('No valid backup paths configured. Add paths in Settings.');
      }

      const job = await startBackup(validPaths);
      setActiveJob(job);
      toast.info('Backup started');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to start backup');
    } finally {
      setIsStarting(false);
    }
  };

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

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

  if (isLoading) {
    return (
      <div className="space-y-6">
        <div>
          <h1 className="text-2xl font-bold text-slate-900 dark:text-white">Backup</h1>
          <p className="text-slate-600 dark:text-slate-400 mt-1">
            Create encrypted backups of your files
          </p>
        </div>
        <CardSkeleton className="h-48" />
        <Card title="Backup Paths">
          <div className="space-y-1">
            <ListItemSkeleton />
            <ListItemSkeleton />
            <ListItemSkeleton />
          </div>
        </Card>
      </div>
    );
  }

  const hasValidPaths = paths.some((p) => p.exists);
  const hasCredits = account && account.credits_remaining > 0;

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

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

      {/* Active Backup Progress */}
      {activeJob && (
        <Card title="Backup 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-primary-100 dark:bg-primary-900/30">
                  <Upload className="w-5 h-5 text-primary-600" />
                </div>
                <div>
                  <p className="font-medium text-slate-900 dark:text-white">
                    Backing up files...
                  </p>
                  <p className="text-sm text-slate-500 dark:text-slate-400">
                    Started {formatRelativeTime(activeJob.started_at)}
                  </p>
                </div>
              </div>
              <button
                onClick={handleCancelBackup}
                className="btn-ghost text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20"
              >
                <Square className="w-4 h-4 mr-2" />
                Cancel
              </button>
            </div>
            <ProgressBar value={activeJob.progress} size="lg" />
            <p className="text-sm text-slate-500 dark:text-slate-400 text-center">
              {activeJob.progress}% complete
            </p>
          </div>
        </Card>
      )}

      {/* Backup Paths */}
      <Card
        title="Backup Paths"
        subtitle={`${paths.length} path${paths.length !== 1 ? 's' : ''} configured`}
      >
        {paths.length === 0 ? (
          <div className="text-center py-8">
            <FolderOpen 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 backup paths configured</p>
            <p className="text-sm text-slate-400 dark:text-slate-500 mt-1">
              Add paths in Settings to start backing up
            </p>
          </div>
        ) : (
          <div className="divide-y divide-slate-200 dark:divide-slate-700">
            {paths.map((path) => (
              <div key={path.path} className="py-3 flex items-center justify-between">
                <div className="flex items-center space-x-3 min-w-0">
                  <FolderOpen className={`w-5 h-5 flex-shrink-0 ${path.exists ? 'text-primary-600' : 'text-slate-400'}`} />
                  <div className="min-w-0">
                    <p className="text-sm font-medium text-slate-900 dark:text-white truncate">
                      {path.path}
                    </p>
                    {path.access_error && (
                      <p className="text-xs text-red-500">{path.access_error}</p>
                    )}
                  </div>
                </div>
                <div className="flex items-center space-x-2">
                  {path.exists ? (
                    <span className="flex items-center text-green-600 text-sm">
                      <CheckCircle className="w-4 h-4 mr-1" />
                      Ready
                    </span>
                  ) : (
                    <span className="flex items-center text-red-500 text-sm">
                      <AlertCircle className="w-4 h-4 mr-1" />
                      Not found
                    </span>
                  )}
                </div>
              </div>
            ))}
          </div>
        )}
      </Card>

      {/* Start Backup */}
      <Card>
        <div className="flex items-center justify-between">
          <div>
            <h3 className="font-semibold text-slate-900 dark:text-white">
              Start Backup
            </h3>
            <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
              Back up all configured paths to the server
            </p>
          </div>
          <button
            onClick={handleStartBackup}
            disabled={!hasValidPaths || !hasCredits || !!activeJob || isStarting}
            className="btn-primary"
          >
            {isStarting ? (
              <>
                <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 Backup
              </>
            )}
          </button>
        </div>

        {!hasValidPaths && (
          <p className="text-sm text-yellow-600 dark:text-yellow-400 mt-3">
            ⚠️ No valid backup paths. Add paths in Settings.
          </p>
        )}
        {!hasCredits && (
          <p className="text-sm text-yellow-600 dark:text-yellow-400 mt-3">
            ⚠️ No credits remaining. Add credits in Account.
          </p>
        )}
      </Card>
    </div>
  );
}
