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

import { useState, useEffect, useCallback } from 'react';
import { FolderPlus, Trash2, FolderOpen, CheckCircle, AlertCircle, Info, Play, Pause, Clock, Plus, Zap, Settings2, Shield } from 'lucide-react';
import { useBackend } from '../contexts/BackendContext';
import { useUpdates } from '../contexts/UpdateContext';
import { useToast } from '../components/Toast';
import Card from '../components/Card';
import Alert from '../components/Alert';
import Modal from '../components/Modal';
import { formatScheduleInterval, formatDateTime, capitalize } from '../lib/utils';
import type { PathInfo, ScheduleResponse } from '../lib/api';
import * as api from '../lib/api';

export default function Settings() {
  const { getPaths, addPath, removePath, getConfig, updateConfig, getMode, updateMode, getRetention, listSchedules, createSchedule, updateSchedule, deleteSchedule, triggerSchedule } = useBackend();
  const updates = useUpdates();
  const toast = useToast();
  const [paths, setPaths] = useState<PathInfo[]>([]);
  const [retention, setRetention] = useState<api.RetentionResponse | null>(null);
  const [config, setConfig] = useState<api.ConfigResponse | null>(null);
  const [mode, setMode] = useState<api.ModeResponse | null>(null);
  const [schedules, setSchedules] = useState<Record<string, ScheduleResponse>>({});
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  
  // Add path modal
  const [showAddModal, setShowAddModal] = useState(false);
  const [newPath, setNewPath] = useState('');
  const [isAdding, setIsAdding] = useState(false);

  // Mode switching
  const [showModeModal, setShowModeModal] = useState(false);
  const [pendingMode, setPendingMode] = useState('');
  const [isSwitchingMode, setIsSwitchingMode] = useState(false);

  // Config editing
  const [showConfigModal, setShowConfigModal] = useState(false);
  const [editExcludes, setEditExcludes] = useState('');
  const [editMissingBehavior, setEditMissingBehavior] = useState('error');
  const [isSavingConfig, setIsSavingConfig] = useState(false);

  // Schedule management
  const [showScheduleModal, setShowScheduleModal] = useState(false);
  const [newScheduleName, setNewScheduleName] = useState('');
  const [newScheduleType, setNewScheduleType] = useState('backup');
  const [newScheduleInterval, setNewScheduleInterval] = useState('24h');
  const [isCreatingSchedule, setIsCreatingSchedule] = useState(false);

  const loadAll = useCallback(async () => {
    try {
      const [pathsResult, retentionResult, configResult, modeResult, schedulesResult] = await Promise.all([
        getPaths(),
        getRetention(),
        getConfig(),
        getMode(),
        listSchedules(),
      ]);
      setPaths(pathsResult.paths);
      setRetention(retentionResult);
      setConfig(configResult);
      setMode(modeResult);
      setSchedules(schedulesResult);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load settings');
    } finally {
      setIsLoading(false);
    }
  }, [getPaths, getRetention, getConfig, getMode, listSchedules]);

  useEffect(() => {
    loadAll();
  }, [loadAll]);

  const handleAddPath = async () => {
    if (!newPath.trim()) return;
    
    setIsAdding(true);
    setError(null);

    try {
      const result = await addPath(newPath.trim());
      setPaths(result.paths);
      setNewPath('');
      setShowAddModal(false);
      setSuccess('Path added successfully');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to add path');
    } finally {
      setIsAdding(false);
    }
  };

  const handleRemovePath = async (path: string) => {
    setError(null);

    try {
      const result = await removePath(path);
      setPaths(result.paths);
      setSuccess('Path removed');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to remove path');
    }
  };

  // Mode switching
  const handleModeSwitch = async () => {
    setIsSwitchingMode(true);
    try {
      const result = await updateMode(pendingMode, true);
      setMode(result);
      setShowModeModal(false);
      toast.success(`Switched to ${result.mode} mode`);
      // Reload config since mode change may affect it
      const newConfig = await getConfig();
      setConfig(newConfig);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to switch mode');
    } finally {
      setIsSwitchingMode(false);
    }
  };

  // Config editing
  const openConfigEditor = () => {
    if (config) {
      setEditExcludes((config.exclude_patterns || []).join('\n'));
      setEditMissingBehavior(config.missing_path_behavior || 'error');
    }
    setShowConfigModal(true);
  };

  const handleSaveConfig = async () => {
    setIsSavingConfig(true);
    try {
      const excludes = editExcludes.split('\n').map(s => s.trim()).filter(Boolean);
      const result = await updateConfig({
        exclude_patterns: excludes,
        missing_path_behavior: editMissingBehavior,
      });
      setConfig(result);
      setShowConfigModal(false);
      toast.success('Configuration updated');
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to update config');
    } finally {
      setIsSavingConfig(false);
    }
  };

  // Schedule management
  const handleCreateSchedule = async () => {
    if (!newScheduleName.trim() || !newScheduleInterval.trim()) return;
    setIsCreatingSchedule(true);
    try {
      await createSchedule(newScheduleName.trim(), {
        type: newScheduleType,
        interval: newScheduleInterval,
        enabled: true,
      });
      toast.success(`Schedule "${newScheduleName}" created`);
      setShowScheduleModal(false);
      setNewScheduleName('');
      setNewScheduleType('backup');
      setNewScheduleInterval('24h');
      const updated = await listSchedules();
      setSchedules(updated);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to create schedule');
    } finally {
      setIsCreatingSchedule(false);
    }
  };

  const handleToggleSchedule = async (name: string, currentlyEnabled: boolean) => {
    try {
      await updateSchedule(name, { enabled: !currentlyEnabled });
      const updated = await listSchedules();
      setSchedules(updated);
      toast.success(`Schedule "${name}" ${currentlyEnabled ? 'disabled' : 'enabled'}`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to toggle schedule');
    }
  };

  const handleDeleteSchedule = async (name: string) => {
    try {
      await deleteSchedule(name);
      const updated = await listSchedules();
      setSchedules(updated);
      toast.success(`Schedule "${name}" deleted`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to delete schedule');
    }
  };

  const handleTriggerSchedule = async (name: string) => {
    try {
      await triggerSchedule(name);
      toast.info(`Schedule "${name}" triggered`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to trigger schedule');
    }
  };

  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">Settings</h1>
        <p className="text-slate-600 dark:text-slate-400 mt-1">
          Configure your backup preferences
        </p>
      </div>

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

      {/* Backup Paths */}
      <Card
        title="Backup Paths"
        subtitle="Directories to include in backups"
        action={
          <button
            onClick={() => setShowAddModal(true)}
            className="btn-primary text-sm"
          >
            <FolderPlus className="w-4 h-4 mr-2" />
            Add Path
          </button>
        }
      >
        {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>
            <button
              onClick={() => setShowAddModal(true)}
              className="text-primary-600 hover:text-primary-700 text-sm mt-2"
            >
              Add your first path
            </button>
          </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 flex-1">
                  <FolderOpen className={`w-5 h-5 flex-shrink-0 ${path.exists ? 'text-primary-600' : 'text-slate-400'}`} />
                  <div className="min-w-0 flex-1">
                    <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>
                    ) : path.exists ? (
                      <p className="text-xs text-slate-500 dark:text-slate-400">
                        {path.is_dir ? 'Directory' : 'File'}
                      </p>
                    ) : null}
                  </div>
                </div>
                <div className="flex items-center space-x-3">
                  {path.exists ? (
                    <span className="flex items-center text-green-600 text-xs">
                      <CheckCircle className="w-3.5 h-3.5 mr-1" />
                      Valid
                    </span>
                  ) : (
                    <span className="flex items-center text-red-500 text-xs">
                      <AlertCircle className="w-3.5 h-3.5 mr-1" />
                      Missing
                    </span>
                  )}
                  <button
                    onClick={() => handleRemovePath(path.path)}
                    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="Remove path"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                </div>
              </div>
            ))}
          </div>
        )}
      </Card>

      {/* Retention Policy */}
      <Card title="Retention Policy" subtitle="How long backups are kept">
        <Alert type="info">
          <div className="flex items-start">
            <Info className="w-4 h-4 mr-2 mt-0.5 flex-shrink-0" />
            <p className="text-sm">
              In Simple Mode, retention is managed automatically. Upgrade to Advanced Mode to customize.
            </p>
          </div>
        </Alert>
        
        {retention && (
          <div className="mt-4 grid grid-cols-2 gap-4">
            <div className="p-3 bg-slate-50 dark:bg-slate-700/50 rounded-lg">
              <p className="text-xs text-slate-500 dark:text-slate-400">Daily</p>
              <p className="text-sm font-medium text-slate-900 dark:text-white">
                {retention.keep_within_daily || '7 days'}
              </p>
            </div>
            <div className="p-3 bg-slate-50 dark:bg-slate-700/50 rounded-lg">
              <p className="text-xs text-slate-500 dark:text-slate-400">Weekly</p>
              <p className="text-sm font-medium text-slate-900 dark:text-white">
                {retention.keep_within_weekly || '4 weeks'}
              </p>
            </div>
            <div className="p-3 bg-slate-50 dark:bg-slate-700/50 rounded-lg">
              <p className="text-xs text-slate-500 dark:text-slate-400">Monthly</p>
              <p className="text-sm font-medium text-slate-900 dark:text-white">
                {retention.keep_within_monthly || '6 months'}
              </p>
            </div>
            <div className="p-3 bg-slate-50 dark:bg-slate-700/50 rounded-lg">
              <p className="text-xs text-slate-500 dark:text-slate-400">Yearly</p>
              <p className="text-sm font-medium text-slate-900 dark:text-white">
                {retention.keep_within_yearly || '2 years'}
              </p>
            </div>
          </div>
        )}
      </Card>

      {/* Backup Mode */}
      <Card
        title="Backup Mode"
        subtitle="Current operation mode"
        action={
          <button
            onClick={() => {
              const target = mode?.mode === 'advanced' ? 'simple' : 'advanced';
              setPendingMode(target);
              setShowModeModal(true);
            }}
            className="btn-secondary text-sm"
          >
            <Settings2 className="w-4 h-4 mr-2" />
            Switch Mode
          </button>
        }
      >
        <div className="flex items-center justify-between">
          <div>
            <div className="flex items-center space-x-2">
              {mode?.mode === 'advanced' ? (
                <Zap className="w-5 h-5 text-amber-500" />
              ) : (
                <Shield className="w-5 h-5 text-green-500" />
              )}
              <p className="text-lg font-medium text-slate-900 dark:text-white">
                {capitalize(mode?.mode || 'simple')} Mode
              </p>
            </div>
            <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
              {mode?.description || (mode?.mode === 'advanced' 
                ? 'Full control over backup operations'
                : 'Automatic retention and simplified interface')}
            </p>
            {mode?.features && mode.features.length > 0 && (
              <div className="flex flex-wrap gap-2 mt-3">
                {mode.features.map((feature) => (
                  <span key={feature} className="px-2 py-1 text-xs rounded-full bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300">
                    {feature}
                  </span>
                ))}
              </div>
            )}
          </div>
        </div>
      </Card>

      {/* Configuration */}
      <Card
        title="Configuration"
        subtitle="Exclude patterns and backup behavior"
        action={
          <button onClick={openConfigEditor} className="btn-secondary text-sm">
            <Settings2 className="w-4 h-4 mr-2" />
            Edit
          </button>
        }
      >
        <div className="space-y-4">
          <div>
            <h4 className="text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Exclude Patterns</h4>
            {config?.exclude_patterns && config.exclude_patterns.length > 0 ? (
              <div className="space-y-1">
                {config.exclude_patterns.map((pattern) => (
                  <p key={pattern} className="text-sm font-mono text-slate-600 dark:text-slate-400">{pattern}</p>
                ))}
              </div>
            ) : (
              <p className="text-sm text-slate-400 dark:text-slate-500 italic">No exclude patterns configured</p>
            )}
          </div>
          <div className="border-t border-slate-200 dark:border-slate-700 pt-4">
            <div className="flex justify-between">
              <span className="text-sm text-slate-600 dark:text-slate-400">Missing Path Behavior</span>
              <span className="text-sm font-medium text-slate-900 dark:text-white">
                {capitalize(config?.missing_path_behavior || 'error')}
              </span>
            </div>
          </div>
        </div>
      </Card>

      {/* Schedules */}
      <Card
        title="Schedules"
        subtitle="Automated backup schedules"
        action={
          <button onClick={() => setShowScheduleModal(true)} className="btn-primary text-sm">
            <Plus className="w-4 h-4 mr-2" />
            New Schedule
          </button>
        }
      >
        {Object.keys(schedules).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 schedules configured</p>
            <button
              onClick={() => setShowScheduleModal(true)}
              className="text-primary-600 hover:text-primary-700 text-sm mt-2"
            >
              Create your first schedule
            </button>
          </div>
        ) : (
          <div className="divide-y divide-slate-200 dark:divide-slate-700">
            {Object.entries(schedules).map(([name, schedule]) => (
              <div key={name} className="py-3">
                <div className="flex items-center justify-between">
                  <div className="flex items-center space-x-3">
                    <div className={`w-2 h-2 rounded-full ${schedule.enabled ? 'bg-green-400' : 'bg-slate-300 dark:bg-slate-600'}`} />
                    <div>
                      <p className="text-sm font-medium text-slate-900 dark:text-white">{name}</p>
                      <p className="text-xs text-slate-500 dark:text-slate-400">
                        {capitalize(schedule.type)} &middot; every {formatScheduleInterval(schedule.interval)}
                      </p>
                    </div>
                  </div>
                  <div className="flex items-center space-x-1">
                    <button
                      onClick={() => handleTriggerSchedule(name)}
                      className="p-1.5 rounded hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-400 hover:text-primary-600 transition-colors"
                      title="Run now"
                    >
                      <Play className="w-4 h-4" />
                    </button>
                    <button
                      onClick={() => handleToggleSchedule(name, schedule.enabled)}
                      className={`p-1.5 rounded hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors ${
                        schedule.enabled ? 'text-green-500 hover:text-amber-500' : 'text-slate-400 hover:text-green-500'
                      }`}
                      title={schedule.enabled ? 'Disable' : 'Enable'}
                    >
                      {schedule.enabled ? <Pause className="w-4 h-4" /> : <Play className="w-4 h-4" />}
                    </button>
                    <button
                      onClick={() => handleDeleteSchedule(name)}
                      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 schedule"
                    >
                      <Trash2 className="w-4 h-4" />
                    </button>
                  </div>
                </div>
                {(schedule.last_run || schedule.next_run) && (
                  <div className="mt-2 ml-5 flex space-x-4">
                    {schedule.last_run && (
                      <p className="text-xs text-slate-400 dark:text-slate-500">
                        Last: {formatDateTime(schedule.last_run)}
                      </p>
                    )}
                    {schedule.next_run && (
                      <p className="text-xs text-slate-400 dark:text-slate-500">
                        Next: {formatDateTime(schedule.next_run)}
                      </p>
                    )}
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </Card>

      <Card title="Automatic Updates" subtitle="Keep the client compatible with the server">
        {!updates.state ? (
          <p className="text-sm text-slate-500 dark:text-slate-400">
            Update status unavailable.
            {updates.error && <span className="block mt-1 text-xs">{updates.error}</span>}
          </p>
        ) : (
          <div className="space-y-4">
            <div className="flex items-center justify-between gap-4">
              <div>
                <div className="font-medium text-slate-900 dark:text-slate-100">Install signed updates automatically</div>
                <p className="text-sm text-slate-500 dark:text-slate-400 mt-1 max-w-prose">
                  When enabled, the client checks <span className="font-mono">privatearchive.xyz</span> through Tor every few hours and applies signed updates without prompting. Disabling means you must run updates manually; older clients may eventually be rejected by the server.
                </p>
              </div>
              <label className="inline-flex items-center cursor-pointer flex-shrink-0">
                <input
                  type="checkbox"
                  className="sr-only peer"
                  checked={updates.state.auto_update}
                  onChange={async (e) => {
                    try {
                      await updates.setAutoUpdate(e.target.checked);
                      toast.success(e.target.checked ? 'Automatic updates enabled' : 'Automatic updates disabled');
                    } catch (err) {
                      toast.error(err instanceof Error ? err.message : 'Failed to update setting');
                    }
                  }}
                />
                <div className="w-11 h-6 bg-slate-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary-300 rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-600 relative" />
              </label>
            </div>

            {!updates.state.auto_update && (
              <Alert type="warning" title="Compatibility warning">
                Automatic updates are off. The server may refuse to serve clients that fall behind a minimum version, which would break backups and restores until you install a newer release.
              </Alert>
            )}

            <div className="grid grid-cols-2 gap-4 pt-2 text-sm border-t border-slate-100 dark:border-slate-800">
              <div>
                <div className="text-slate-500 dark:text-slate-400">Current version</div>
                <div className="font-mono text-slate-900 dark:text-slate-100">{updates.state.current_version}</div>
              </div>
              {updates.state.latest_version && (
                <div>
                  <div className="text-slate-500 dark:text-slate-400">Latest available</div>
                  <div className="font-mono text-slate-900 dark:text-slate-100">{updates.state.latest_version}</div>
                </div>
              )}
              <div>
                <div className="text-slate-500 dark:text-slate-400">Channel</div>
                <div className="text-slate-900 dark:text-slate-100">{updates.state.channel}</div>
              </div>
              {updates.state.last_checked && (
                <div>
                  <div className="text-slate-500 dark:text-slate-400">Last checked</div>
                  <div className="text-slate-900 dark:text-slate-100">{formatDateTime(updates.state.last_checked)}</div>
                </div>
              )}
            </div>

            <div className="flex gap-2">
              <button
                type="button"
                onClick={async () => {
                  try {
                    await updates.refresh();
                    toast.success('Update status refreshed');
                  } catch (err) {
                    toast.error(err instanceof Error ? err.message : 'Refresh failed');
                  }
                }}
                className="px-3 py-1.5 text-sm rounded-md border border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800"
              >
                Check now
              </button>
              {updates.state.update_available && (
                <button
                  type="button"
                  onClick={async () => {
                    try {
                      await updates.install();
                      toast.success('Update installed; the daemon will restart shortly.');
                    } catch (err) {
                      toast.error(err instanceof Error ? err.message : 'Install failed');
                    }
                  }}
                  className="px-3 py-1.5 text-sm rounded-md bg-primary-600 text-white hover:bg-primary-700"
                >
                  Install update
                </button>
              )}
            </div>

            {updates.state.last_error && (
              <p className="text-xs text-red-600 dark:text-red-400">Last error: {updates.state.last_error}</p>
            )}
          </div>
        )}
      </Card>

      {/* Add Path Modal */}
      <Modal
        isOpen={showAddModal}
        onClose={() => {
          setShowAddModal(false);
          setNewPath('');
        }}
        title="Add Backup Path"
      >
        <div className="space-y-4">
          <div>
            <label className="label">Directory Path</label>
            <input
              type="text"
              value={newPath}
              onChange={(e) => setNewPath(e.target.value)}
              placeholder="/home/user/documents"
              className="input"
              autoFocus
            />
            <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
              Enter the full path to the directory you want to back up
            </p>
          </div>
          <div className="flex justify-end space-x-3">
            <button
              onClick={() => {
                setShowAddModal(false);
                setNewPath('');
              }}
              className="btn-secondary"
            >
              Cancel
            </button>
            <button
              onClick={handleAddPath}
              disabled={!newPath.trim() || isAdding}
              className="btn-primary"
            >
              {isAdding ? 'Adding...' : 'Add Path'}
            </button>
          </div>
        </div>
      </Modal>

      {/* Mode Switch Confirmation Modal */}
      <Modal
        isOpen={showModeModal}
        onClose={() => setShowModeModal(false)}
        title="Switch Backup Mode"
      >
        <div className="space-y-4">
          <Alert type={pendingMode === 'advanced' ? 'warning' : 'info'}>
            {pendingMode === 'advanced' ? (
              <>
                <p className="font-medium">Switching to Advanced Mode</p>
                <p className="text-sm mt-1">
                  In Advanced Mode you have full control over retention policies, pruning, 
                  and backup operations. This requires more manual management.
                </p>
              </>
            ) : (
              <>
                <p className="font-medium">Switching to Simple Mode</p>
                <p className="text-sm mt-1">
                  In Simple Mode, retention is managed automatically. Custom retention 
                  settings will be replaced with defaults.
                </p>
              </>
            )}
          </Alert>
          <div className="flex justify-end space-x-3">
            <button onClick={() => setShowModeModal(false)} className="btn-secondary">Cancel</button>
            <button
              onClick={handleModeSwitch}
              disabled={isSwitchingMode}
              className="btn-primary"
            >
              {isSwitchingMode ? 'Switching...' : `Switch to ${capitalize(pendingMode)}`}
            </button>
          </div>
        </div>
      </Modal>

      {/* Config Editor Modal */}
      <Modal
        isOpen={showConfigModal}
        onClose={() => setShowConfigModal(false)}
        title="Edit Configuration"
        size="lg"
      >
        <div className="space-y-4">
          <div>
            <label className="label">Exclude Patterns</label>
            <textarea
              value={editExcludes}
              onChange={(e) => setEditExcludes(e.target.value)}
              placeholder={"*.tmp\n.cache/**\nnode_modules/**"}
              className="input font-mono text-sm"
              rows={6}
            />
            <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
              One pattern per line. Patterns follow restic exclude syntax.
            </p>
          </div>
          <div>
            <label className="label">Missing Path Behavior</label>
            <select
              value={editMissingBehavior}
              onChange={(e) => setEditMissingBehavior(e.target.value)}
              className="input"
            >
              <option value="error">Error &mdash; fail backup if path is missing</option>
              <option value="warn">Warn &mdash; continue with warning</option>
              <option value="ignore">Ignore &mdash; skip silently</option>
            </select>
          </div>
          <div className="flex justify-end space-x-3 pt-2">
            <button onClick={() => setShowConfigModal(false)} className="btn-secondary">Cancel</button>
            <button
              onClick={handleSaveConfig}
              disabled={isSavingConfig}
              className="btn-primary"
            >
              {isSavingConfig ? 'Saving...' : 'Save Configuration'}
            </button>
          </div>
        </div>
      </Modal>

      {/* Create Schedule Modal */}
      <Modal
        isOpen={showScheduleModal}
        onClose={() => { setShowScheduleModal(false); setNewScheduleName(''); }}
        title="Create Schedule"
      >
        <div className="space-y-4">
          <div>
            <label className="label">Schedule Name</label>
            <input
              type="text"
              value={newScheduleName}
              onChange={(e) => setNewScheduleName(e.target.value)}
              placeholder="daily-backup"
              className="input"
              autoFocus
            />
          </div>
          <div>
            <label className="label">Type</label>
            <select
              value={newScheduleType}
              onChange={(e) => setNewScheduleType(e.target.value)}
              className="input"
            >
              <option value="backup">Backup</option>
              <option value="prune">Prune</option>
              <option value="check">Check</option>
            </select>
          </div>
          <div>
            <label className="label">Interval</label>
            <input
              type="text"
              value={newScheduleInterval}
              onChange={(e) => setNewScheduleInterval(e.target.value)}
              placeholder="24h"
              className="input"
            />
            <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
              Go duration format: 24h, 12h, 168h (1 week), 720h (30 days)
            </p>
          </div>
          <div className="flex justify-end space-x-3 pt-2">
            <button onClick={() => { setShowScheduleModal(false); setNewScheduleName(''); }} className="btn-secondary">
              Cancel
            </button>
            <button
              onClick={handleCreateSchedule}
              disabled={!newScheduleName.trim() || !newScheduleInterval.trim() || isCreatingSchedule}
              className="btn-primary"
            >
              {isCreatingSchedule ? 'Creating...' : 'Create Schedule'}
            </button>
          </div>
        </div>
      </Modal>
    </div>
  );
}
