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

import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import {
  Shield,
  Upload,
  Download,
  Clock,
  HardDrive,
  Wifi,
  WifiOff,
  CreditCard,
  RefreshCw,
  ChevronRight,
  Database,
  Globe,
  Server,
} from 'lucide-react';
import { useBackend } from '../contexts/BackendContext';
import { useToast } from '../components/Toast';
import Card from '../components/Card';
import StatusBadge from '../components/StatusBadge';
import ProgressBar from '../components/ProgressBar';
import Alert from '../components/Alert';
import { StatCardSkeleton, ListItemSkeleton } from '../components/Skeleton';
import { formatBytes, formatRelativeTime, formatCredits } from '../lib/utils';
import type { Job, CredentialsResponse } from '../lib/api';
import * as api from '../lib/api';

export default function Dashboard() {
  const {
    isConnected,
    account,
    torStatus,
    serverStatus,
    refresh,
    listJobs,
    isLoading: isBackendLoading,
  } = useBackend();
  const toast = useToast();
  const [jobs, setJobs] = useState<Job[]>([]);
  const [credentials, setCredentials] = useState<CredentialsResponse | null>(null);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [isJobsLoading, setIsJobsLoading] = useState(true);

  // Fetch jobs, credentials on mount and periodically
  useEffect(() => {
    const fetchData = async () => {
      try {
        const [jobList, creds] = await Promise.all([
          listJobs(),
          api.getCredentials().catch(() => null),
        ]);
        setJobs(jobList);
        if (creds) setCredentials(creds);
      } catch (err) {
        console.error('Failed to fetch dashboard data:', err);
      } finally {
        setIsJobsLoading(false);
      }
    };

    fetchData();
    const interval = setInterval(fetchData, 5000);
    return () => clearInterval(interval);
  }, [listJobs]);

  const handleRefresh = async () => {
    setIsRefreshing(true);
    try {
      await refresh();
      toast.success('Dashboard refreshed');
    } catch {
      toast.error('Failed to refresh dashboard');
    } finally {
      setIsRefreshing(false);
    }
  };

  // Get active jobs
  const activeJobs = jobs.filter((j) => j.status === 'running' || j.status === 'pending');
  const recentJobs = jobs.filter((j) => j.status === 'completed' || j.status === 'failed').slice(0, 5);

  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">Dashboard</h1>
          <p className="text-slate-600 dark:text-slate-400 mt-1">
            Overview of your backup status
          </p>
        </div>
        <button
          onClick={handleRefresh}
          disabled={isRefreshing}
          className="btn-secondary"
        >
          <RefreshCw className={`w-4 h-4 mr-2 ${isRefreshing ? 'animate-spin' : ''}`} />
          Refresh
        </button>
      </div>

      {/* Connection Warning */}
      {!isConnected && (
        <Alert type="error" title="Backend Not Connected">
          Cannot connect to the backup backend. Make sure the daemon is running.
        </Alert>
      )}

      {/* Active Jobs */}
      {activeJobs.length > 0 && (
        <Card title="Active Operations">
          <div className="space-y-4">
            {activeJobs.map((job) => (
              <div key={job.id} className="flex items-center justify-between">
                <div className="flex items-center space-x-3">
                  {job.type === 'backup' ? (
                    <Upload className="w-5 h-5 text-primary-600" />
                  ) : (
                    <Download className="w-5 h-5 text-primary-600" />
                  )}
                  <div>
                    <p className="font-medium text-slate-900 dark:text-white capitalize">
                      {job.type}
                    </p>
                    <p className="text-sm text-slate-500 dark:text-slate-400">
                      Started {formatRelativeTime(job.started_at)}
                    </p>
                  </div>
                </div>
                <div className="w-48">
                  <ProgressBar value={job.progress} size="sm" />
                </div>
              </div>
            ))}
          </div>
        </Card>
      )}

      {/* Status Cards */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
        {isBackendLoading ? (
          // Show skeleton loaders while loading
          <>
            <StatCardSkeleton />
            <StatCardSkeleton />
            <StatCardSkeleton />
            <StatCardSkeleton />
            <StatCardSkeleton />
          </>
        ) : (
          <>
            {/* Connection Status */}
            <Card>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm text-slate-500 dark:text-slate-400">Connection</p>
                  <p className="text-lg font-semibold text-slate-900 dark:text-white mt-1">
                    {isConnected ? 'Connected' : 'Disconnected'}
                  </p>
                </div>
                <div className={`p-3 rounded-lg ${isConnected ? 'bg-green-100 dark:bg-green-900/30' : 'bg-red-100 dark:bg-red-900/30'}`}>
                  {isConnected ? (
                    <Wifi className="w-6 h-6 text-green-600" />
                  ) : (
                    <WifiOff className="w-6 h-6 text-red-600" />
                  )}
                </div>
              </div>
            </Card>

            {/* Account Status */}
            <Card>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm text-slate-500 dark:text-slate-400">Account</p>
                  <p className="text-lg font-semibold text-slate-900 dark:text-white mt-1 capitalize">
                    {account?.status || 'Unknown'}
                  </p>
                </div>
                <div className="p-3 rounded-lg bg-primary-100 dark:bg-primary-900/30">
                  <Shield className="w-6 h-6 text-primary-600" />
                </div>
              </div>
            </Card>

            {/* Credits */}
            <Card>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm text-slate-500 dark:text-slate-400">Credits</p>
                  <p className="text-lg font-semibold text-slate-900 dark:text-white mt-1">
                    {formatCredits(account?.credits_remaining)}
                  </p>
                </div>
                <div className="p-3 rounded-lg bg-accent-100 dark:bg-accent-900/30">
                  <CreditCard className="w-6 h-6 text-accent-600" />
                </div>
              </div>
            </Card>

            {/* Storage Used */}
            <Card>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm text-slate-500 dark:text-slate-400">Storage Used</p>
                  <p className="text-lg font-semibold text-slate-900 dark:text-white mt-1">
                    {formatBytes(account?.storage_used_bytes)}
                  </p>
                </div>
                <div className="p-3 rounded-lg bg-slate-100 dark:bg-slate-700">
                  <HardDrive className="w-6 h-6 text-slate-600 dark:text-slate-400" />
                </div>
              </div>
            </Card>

            {/* Data Backend */}
            <Card>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm text-slate-500 dark:text-slate-400">Data Backend</p>
                  <p className="text-lg font-semibold text-slate-900 dark:text-white mt-1">
                    {credentials?.data_backend === 's3' ? 'S3 via Tor' : 'REST via Tor'}
                  </p>
                </div>
                <div className="p-3 rounded-lg bg-indigo-100 dark:bg-indigo-900/30">
                  <Database className="w-6 h-6 text-indigo-600" />
                </div>
              </div>
            </Card>
          </>
        )}
      </div>

      {/* Tor & Server Status */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {/* Tor Status */}
        <Card title="Tor Network">
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <span className="text-sm text-slate-500 dark:text-slate-400">Status</span>
              <span className="flex items-center">
                <Globe className={`w-4 h-4 mr-1.5 ${torStatus?.connected ? 'text-green-500' : 'text-red-500'}`} />
                <span className={`text-sm font-medium ${torStatus?.connected ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
                  {torStatus?.connected ? 'Connected' : 'Disconnected'}
                </span>
              </span>
            </div>
            {torStatus && (
              <>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Bootstrap</span>
                  <div className="flex items-center space-x-2">
                    <div className="w-24">
                      <ProgressBar value={torStatus.bootstrap_pct} size="sm" color={torStatus.bootstrap_pct === 100 ? 'success' : undefined} />
                    </div>
                    <span className="text-sm text-slate-600 dark:text-slate-300">{torStatus.bootstrap_pct}%</span>
                  </div>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Circuits</span>
                  <span className="text-sm text-slate-900 dark:text-white">{torStatus.circuit_count}</span>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Last Activity</span>
                  <span className="text-sm text-slate-600 dark:text-slate-300">{formatRelativeTime(torStatus.last_activity)}</span>
                </div>
              </>
            )}
          </div>
        </Card>

        {/* Server Status */}
        <Card title="Backup Server">
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <span className="text-sm text-slate-500 dark:text-slate-400">Status</span>
              <span className="flex items-center">
                <Server className={`w-4 h-4 mr-1.5 ${serverStatus?.connected ? 'text-green-500' : 'text-red-500'}`} />
                <span className={`text-sm font-medium ${serverStatus?.connected ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
                  {serverStatus?.connected ? 'Reachable' : 'Unreachable'}
                </span>
              </span>
            </div>
            {serverStatus && (
              <>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Account Status</span>
                  <StatusBadge status={serverStatus.account_status || 'unknown'} />
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Server Credits</span>
                  <span className="text-sm text-slate-900 dark:text-white">{formatCredits(serverStatus.credits_remaining)}</span>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-sm text-slate-500 dark:text-slate-400">Last Contact</span>
                  <span className="text-sm text-slate-600 dark:text-slate-300">{formatRelativeTime(serverStatus.last_contact_at)}</span>
                </div>
              </>
            )}
          </div>
        </Card>
      </div>

      {/* Quick Actions */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Link
          to="/backup"
          className="card p-6 hover:shadow-md transition-shadow group"
        >
          <div className="flex items-center justify-between">
            <div className="flex items-center">
              <div className="p-3 rounded-lg bg-primary-100 dark:bg-primary-900/30 mr-4">
                <Upload className="w-6 h-6 text-primary-600" />
              </div>
              <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">
                  Back up your configured paths
                </p>
              </div>
            </div>
            <ChevronRight className="w-5 h-5 text-slate-400 group-hover:text-primary-600 transition-colors" />
          </div>
        </Link>

        <Link
          to="/restore"
          className="card p-6 hover:shadow-md transition-shadow group"
        >
          <div className="flex items-center justify-between">
            <div className="flex items-center">
              <div className="p-3 rounded-lg bg-green-100 dark:bg-green-900/30 mr-4">
                <Download className="w-6 h-6 text-green-600" />
              </div>
              <div>
                <h3 className="font-semibold text-slate-900 dark:text-white">
                  Restore Files
                </h3>
                <p className="text-sm text-slate-500 dark:text-slate-400">
                  Restore from a backup snapshot
                </p>
              </div>
            </div>
            <ChevronRight className="w-5 h-5 text-slate-400 group-hover:text-green-600 transition-colors" />
          </div>
        </Link>
      </div>

      {/* Recent Activity */}
      <Card
        title="Recent Activity"
        action={
          <Link to="/jobs" className="text-sm text-primary-600 hover:text-primary-700">
            View all jobs
          </Link>
        }
      >
        {isJobsLoading ? (
          // Show skeleton loaders while loading
          <div className="space-y-1">
            <ListItemSkeleton />
            <ListItemSkeleton />
            <ListItemSkeleton />
          </div>
        ) : recentJobs.length === 0 ? (
          <div className="text-center py-8">
            <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 recent activity</p>
            <p className="text-sm text-slate-400 dark:text-slate-500 mt-1">
              Start a backup to see your history here
            </p>
          </div>
        ) : (
          <div className="divide-y divide-slate-200 dark:divide-slate-700">
            {recentJobs.map((job) => (
              <div key={job.id} className="py-3 flex items-center justify-between">
                <div className="flex items-center space-x-3">
                  {job.type === 'backup' ? (
                    <Upload className="w-4 h-4 text-slate-400" />
                  ) : (
                    <Download className="w-4 h-4 text-slate-400" />
                  )}
                  <div>
                    <p className="text-sm font-medium text-slate-900 dark:text-white capitalize">
                      {job.type}
                    </p>
                    <p className="text-xs text-slate-500 dark:text-slate-400">
                      {formatRelativeTime(job.completed_at || job.created_at)}
                    </p>
                  </div>
                </div>
                <StatusBadge status={job.status} />
              </div>
            ))}
          </div>
        )}
      </Card>

      {/* Low Credits Warning */}
      {account && account.credits_remaining < 1 && (
        <Alert type="warning" title="Low Credits">
          <p>
            You have less than 1 credit remaining. Add credits to continue backing up.
          </p>
          <Link to="/account" className="text-yellow-700 dark:text-yellow-300 font-medium hover:underline">
            View payment options →
          </Link>
        </Alert>
      )}
    </div>
  );
}
