/**
 * Component: Admin Settings Page
 * Documentation: documentation/settings-pages.md
 */

'use client';

import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import Link from 'next/link';
import { fetchWithAuth } from '@/lib/utils/api';

interface PlexLibrary {
  id: string;
  title: string;
  type: string;
}

interface IndexerConfig {
  id: number;
  name: string;
  protocol: string;
  privacy: string;
  enabled: boolean;
  priority: number;
  seedingTimeMinutes: number;
  rssEnabled: boolean;
  supportsRss?: boolean;
}

interface Settings {
  backendMode: 'plex' | 'audiobookshelf';
  hasLocalUsers: boolean;
  plex: {
    url: string;
    token: string;
    libraryId: string;
  };
  audiobookshelf: {
    serverUrl: string;
    apiToken: string;
    libraryId: string;
  };
  oidc: {
    enabled: boolean;
    providerName: string;
    issuerUrl: string;
    clientId: string;
    clientSecret: string;
    accessControlMethod: string;
    accessGroupClaim: string;
    accessGroupValue: string;
    allowedEmails: string;
    allowedUsernames: string;
    adminClaimEnabled: boolean;
    adminClaimName: string;
    adminClaimValue: string;
  };
  registration: {
    enabled: boolean;
    requireAdminApproval: boolean;
  };
  prowlarr: {
    url: string;
    apiKey: string;
  };
  downloadClient: {
    type: string;
    url: string;
    username: string;
    password: string;
    remotePathMappingEnabled: boolean;
    remotePath: string;
    localPath: string;
  };
  paths: {
    downloadDir: string;
    mediaDir: string;
    metadataTaggingEnabled: boolean;
  };
}

interface PendingUser {
  id: string;
  plexUsername: string;
  plexEmail: string | null;
  authProvider: string | null;
  createdAt: string;
}

interface ABSLibrary {
  id: string;
  name: string;
  type: string;
  itemCount: number;
}

export default function AdminSettings() {
  const [settings, setSettings] = useState<Settings | null>(null);
  const [originalSettings, setOriginalSettings] = useState<Settings | null>(null); // Track original values
  const [plexLibraries, setPlexLibraries] = useState<PlexLibrary[]>([]);
  const [absLibraries, setAbsLibraries] = useState<ABSLibrary[]>([]);
  const [indexers, setIndexers] = useState<IndexerConfig[]>([]);
  const [pendingUsers, setPendingUsers] = useState<PendingUser[]>([]);
  const [isLocalAdmin, setIsLocalAdmin] = useState(false);
  const [loading, setLoading] = useState(true);
  const [loadingLibraries, setLoadingLibraries] = useState(false);
  const [loadingIndexers, setLoadingIndexers] = useState(false);
  const [loadingPendingUsers, setLoadingPendingUsers] = useState(false);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [validated, setValidated] = useState({
    plex: false,
    audiobookshelf: false,
    oidc: false,
    registration: false,
    prowlarr: false,
    download: false,
    paths: false,
  });
  const [testResults, setTestResults] = useState<Record<string, { success: boolean; message: string }>>({});
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(
    null
  );
  const [activeTab, setActiveTab] = useState<'library' | 'auth' | 'prowlarr' | 'download' | 'paths' | 'account' | 'bookdate'>('library');

  // Password change form state
  const [passwordForm, setPasswordForm] = useState({
    currentPassword: '',
    newPassword: '',
    confirmPassword: '',
  });
  const [changingPassword, setChangingPassword] = useState(false);

  // BookDate configuration state
  const [bookdateProvider, setBookdateProvider] = useState<string>('openai');
  const [bookdateApiKey, setBookdateApiKey] = useState<string>('');
  const [bookdateModel, setBookdateModel] = useState<string>('');
  const [bookdateEnabled, setBookdateEnabled] = useState<boolean>(true);
  const [bookdateConfigured, setBookdateConfigured] = useState<boolean>(false);
  const [bookdateModels, setBookdateModels] = useState<{ id: string; name: string }[]>([]);
  const [testingBookdate, setTestingBookdate] = useState(false);
  const [clearingBookdateSwipes, setClearingBookdateSwipes] = useState(false);

  useEffect(() => {
    fetchSettings();
    fetchCurrentUser();
  }, []);

  const fetchCurrentUser = async () => {
    try {
      const response = await fetchWithAuth('/api/auth/me');
      if (response.ok) {
        const data = await response.json();
        setIsLocalAdmin(data.user?.isLocalAdmin || false);
      }
    } catch (error) {
      console.error('Failed to fetch current user:', error);
    }
  };

  // Fetch libraries/indexers when tabs become active or when page first loads
  useEffect(() => {
    if (!settings) return;

    if (activeTab === 'library' && settings.backendMode === 'plex' && settings.plex.url && settings.plex.token) {
      fetchPlexLibraries();
    } else if (activeTab === 'library' && settings.backendMode === 'audiobookshelf' && settings.audiobookshelf.serverUrl && settings.audiobookshelf.apiToken) {
      fetchABSLibraries();
    }
  }, [activeTab, settings?.plex.url, settings?.plex.token, settings?.audiobookshelf.serverUrl, settings?.audiobookshelf.apiToken, settings?.backendMode]);

  useEffect(() => {
    if (!settings) return;

    if (activeTab === 'prowlarr' && settings.prowlarr.url && settings.prowlarr.apiKey) {
      fetchIndexers();
    }
  }, [activeTab, settings?.prowlarr.url, settings?.prowlarr.apiKey]);

  useEffect(() => {
    if (activeTab === 'bookdate') {
      fetchBookdateConfig();
    }
  }, [activeTab]);

  useEffect(() => {
    if (activeTab === 'auth' && settings?.registration.requireAdminApproval) {
      fetchPendingUsers();
    }
  }, [activeTab, settings?.registration.requireAdminApproval]);

  const fetchSettings = async () => {
    try {
      const response = await fetchWithAuth('/api/admin/settings');
      if (response.ok) {
        const data = await response.json();

        // Convert OIDC allowed lists from JSON arrays to comma-separated strings for display
        if (data.oidc) {
          const parseArrayToCommaSeparated = (jsonStr: string): string => {
            try {
              const arr = JSON.parse(jsonStr);
              return Array.isArray(arr) ? arr.join(', ') : '';
            } catch {
              return '';
            }
          };

          data.oidc.allowedEmails = parseArrayToCommaSeparated(data.oidc.allowedEmails);
          data.oidc.allowedUsernames = parseArrayToCommaSeparated(data.oidc.allowedUsernames);
        }

        setSettings(data);
        setOriginalSettings(JSON.parse(JSON.stringify(data))); // Deep copy for comparison
      } else {
        console.error('Failed to fetch settings:', response.status, response.statusText);
      }
    } catch (error) {
      console.error('Failed to fetch settings:', error);
    } finally {
      setLoading(false);
    }
  };

  const fetchPlexLibraries = async (force = false) => {
    if (!force && plexLibraries.length > 0) return; // Already loaded

    setLoadingLibraries(true);
    try {
      const response = await fetchWithAuth('/api/admin/settings/plex/libraries');
      if (response.ok) {
        const data = await response.json();
        setPlexLibraries(data.libraries || []);
      } else {
        const data = await response.json();
        console.error('Failed to fetch Plex libraries:', data);
        setMessage({ type: 'error', text: data.message || 'Failed to load Plex libraries. Check your Plex URL and token.' });
      }
    } catch (error) {
      console.error('Failed to fetch Plex libraries:', error);
      setMessage({ type: 'error', text: 'Failed to load Plex libraries. Check your Plex URL and token.' });
    } finally {
      setLoadingLibraries(false);
    }
  };

  const fetchABSLibraries = async (force = false) => {
    if (!force && absLibraries.length > 0) return; // Already loaded

    setLoadingLibraries(true);
    try {
      const response = await fetchWithAuth('/api/admin/settings/audiobookshelf/libraries');
      if (response.ok) {
        const data = await response.json();
        setAbsLibraries(data.libraries || []);
      } else {
        const data = await response.json();
        console.error('Failed to fetch ABS libraries:', data);
        setMessage({ type: 'error', text: data.message || 'Failed to load Audiobookshelf libraries. Check your server URL and API token.' });
      }
    } catch (error) {
      console.error('Failed to fetch ABS libraries:', error);
      setMessage({ type: 'error', text: 'Failed to load Audiobookshelf libraries. Check your server URL and API token.' });
    } finally {
      setLoadingLibraries(false);
    }
  };

  const fetchPendingUsers = async () => {
    setLoadingPendingUsers(true);
    try {
      const response = await fetchWithAuth('/api/admin/users/pending');
      if (response.ok) {
        const data = await response.json();
        setPendingUsers(data.users || []);
      } else {
        console.error('Failed to fetch pending users:', response.status);
      }
    } catch (error) {
      console.error('Failed to fetch pending users:', error);
    } finally {
      setLoadingPendingUsers(false);
    }
  };

  const fetchIndexers = async (force = false) => {
    if (!force && indexers.length > 0) return; // Already loaded

    setLoadingIndexers(true);
    try {
      const response = await fetchWithAuth('/api/admin/settings/prowlarr/indexers');
      if (response.ok) {
        const data = await response.json();
        setIndexers(data.indexers || []);
      } else {
        console.error('Failed to fetch indexers:', response.status);
        // Don't show error on initial load, only if user explicitly tries to load
        if (force) {
          setMessage({ type: 'error', text: 'Failed to load indexers. Check your Prowlarr settings.' });
        }
      }
    } catch (error) {
      console.error('Failed to fetch indexers:', error);
      if (force) {
        setMessage({ type: 'error', text: 'Failed to load Prowlarr indexers. Check your Prowlarr URL and API key.' });
      }
    } finally {
      setLoadingIndexers(false);
    }
  };

  const fetchBookdateConfig = async () => {
    try {
      const response = await fetchWithAuth('/api/bookdate/config');
      const data = await response.json();

      if (data.config) {
        setBookdateProvider(data.config.provider || 'openai');
        setBookdateModel(data.config.model || '');
        setBookdateEnabled(data.config.isEnabled !== false); // Default to true
        setBookdateConfigured(data.config.isVerified || false);
      }
    } catch (error) {
      console.error('Failed to load BookDate config:', error);
    }
  };

  const handleTestBookdateConnection = async () => {
    const hasApiKey = bookdateApiKey.trim().length > 0;

    // Allow testing with saved API key if already configured
    if (!hasApiKey && !bookdateConfigured) {
      setMessage({ type: 'error', text: 'Please enter an API key' });
      return;
    }

    setTestingBookdate(true);
    setMessage(null);

    try {
      const payload: any = {
        provider: bookdateProvider,
      };

      // Include API key if user entered a new one, otherwise use saved key
      if (hasApiKey) {
        payload.apiKey = bookdateApiKey;
      } else {
        payload.useSavedKey = true;
      }

      const response = await fetchWithAuth('/api/bookdate/test-connection', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Connection test failed');
      }

      setBookdateModels(data.models || []);
      setMessage({ type: 'success', text: 'Connection successful! Please select a model.' });

      // Auto-select first model if none selected
      if (!bookdateModel && data.models?.length > 0) {
        setBookdateModel(data.models[0].id);
      }
    } catch (error) {
      setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Connection test failed' });
    } finally {
      setTestingBookdate(false);
    }
  };

  const handleSaveBookdateConfig = async () => {
    // Validate: model is required
    if (!bookdateModel) {
      setMessage({ type: 'error', text: 'Please select a model' });
      return;
    }

    // Only require API key if not already configured OR if user entered one
    const hasApiKey = bookdateApiKey.trim().length > 0;
    if (!bookdateConfigured && !hasApiKey) {
      setMessage({ type: 'error', text: 'Please enter an API key for initial setup' });
      return;
    }

    setSaving(true);
    setMessage(null);

    try {
      const payload: any = {
        provider: bookdateProvider,
        model: bookdateModel,
        isEnabled: bookdateEnabled,
      };

      // Only include API key if user entered a new one
      if (hasApiKey) {
        payload.apiKey = bookdateApiKey;
      }

      const response = await fetchWithAuth('/api/bookdate/config', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Failed to save configuration');
      }

      setMessage({ type: 'success', text: 'BookDate configuration saved successfully!' });
      setBookdateConfigured(true);
      setBookdateApiKey(''); // Clear API key from UI after save
    } catch (error) {
      setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Failed to save configuration' });
    } finally {
      setSaving(false);
    }
  };

  const handleClearBookdateSwipes = async () => {
    if (!confirm('This will clear all swipe history. Continue?')) {
      return;
    }

    setClearingBookdateSwipes(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/bookdate/swipes', {
        method: 'DELETE',
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Failed to clear swipe history');
      }

      setMessage({ type: 'success', text: 'Swipe history cleared successfully!' });
    } catch (error) {
      setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Failed to clear swipe history' });
    } finally {
      setClearingBookdateSwipes(false);
    }
  };

  const testPlexConnection = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/admin/settings/test-plex', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          url: settings.plex.url,
          token: settings.plex.token,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, plex: true });
        setTestResults({ ...testResults, plex: { success: true, message: `Connected to ${data.serverName}` } });
        setMessage({ type: 'success', text: `Connected to ${data.serverName}. You can now save.` });
        // Update libraries
        if (data.libraries) {
          setPlexLibraries(data.libraries);
        }
      } else {
        setValidated({ ...validated, plex: false });
        setTestResults({ ...testResults, plex: { success: false, message: data.error || 'Connection failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to connect to Plex' });
      }
    } catch (error) {
      setValidated({ ...validated, plex: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test connection';
      setTestResults({ ...testResults, plex: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const testABSConnection = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/setup/test-abs', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          serverUrl: settings.audiobookshelf.serverUrl,
          apiToken: settings.audiobookshelf.apiToken,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, audiobookshelf: true });
        setTestResults({ ...testResults, audiobookshelf: { success: true, message: `Connected to Audiobookshelf` } });
        setMessage({ type: 'success', text: 'Connected to Audiobookshelf. You can now save.' });
        // Update libraries
        if (data.libraries) {
          setAbsLibraries(data.libraries);
        }
      } else {
        setValidated({ ...validated, audiobookshelf: false });
        setTestResults({ ...testResults, audiobookshelf: { success: false, message: data.error || 'Connection failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to connect to Audiobookshelf' });
      }
    } catch (error) {
      setValidated({ ...validated, audiobookshelf: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test connection';
      setTestResults({ ...testResults, audiobookshelf: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const testOIDCConnection = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/setup/test-oidc', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          issuerUrl: settings.oidc.issuerUrl,
          clientId: settings.oidc.clientId,
          clientSecret: settings.oidc.clientSecret,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, oidc: true });
        setTestResults({ ...testResults, oidc: { success: true, message: 'OIDC configuration is valid' } });
        setMessage({ type: 'success', text: 'OIDC configuration is valid. You can now save.' });
      } else {
        setValidated({ ...validated, oidc: false });
        setTestResults({ ...testResults, oidc: { success: false, message: data.error || 'Connection failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to validate OIDC configuration' });
      }
    } catch (error) {
      setValidated({ ...validated, oidc: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test OIDC connection';
      setTestResults({ ...testResults, oidc: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const approveUser = async (userId: string, approve: boolean) => {
    try {
      const response = await fetchWithAuth(`/api/admin/users/${userId}/approve`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ approve }),
      });

      const data = await response.json();

      if (data.success) {
        setMessage({ type: 'success', text: data.message });
        // Refresh pending users list
        await fetchPendingUsers();
      } else {
        setMessage({ type: 'error', text: data.error || 'Failed to process user approval' });
      }
    } catch (error) {
      setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Failed to process user approval' });
    }
  };

  const testProwlarrConnection = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/admin/settings/test-prowlarr', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          url: settings.prowlarr.url,
          apiKey: settings.prowlarr.apiKey,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, prowlarr: true });
        setTestResults({ ...testResults, prowlarr: { success: true, message: `Connected to Prowlarr. Found ${data.indexers?.length || 0} indexers` } });
        setMessage({ type: 'success', text: `Connected to Prowlarr. Found ${data.indexers?.length || 0} indexers. You can now save.` });
        // Refresh indexers from database (merges saved config with available indexers)
        await fetchIndexers(true);
      } else {
        setValidated({ ...validated, prowlarr: false });
        setTestResults({ ...testResults, prowlarr: { success: false, message: data.error || 'Connection failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to connect to Prowlarr' });
      }
    } catch (error) {
      setValidated({ ...validated, prowlarr: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test connection';
      setTestResults({ ...testResults, prowlarr: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const testDownloadClientConnection = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/admin/settings/test-download-client', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          type: settings.downloadClient.type,
          url: settings.downloadClient.url,
          username: settings.downloadClient.username,
          password: settings.downloadClient.password,
          remotePathMappingEnabled: settings.downloadClient.remotePathMappingEnabled,
          remotePath: settings.downloadClient.remotePath,
          localPath: settings.downloadClient.localPath,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, download: true });
        setTestResults({ ...testResults, download: { success: true, message: `Connected to ${settings.downloadClient.type} (${data.version || 'version unknown'})` } });
        setMessage({ type: 'success', text: `Connected to ${settings.downloadClient.type}. You can now save.` });
      } else {
        setValidated({ ...validated, download: false });
        setTestResults({ ...testResults, download: { success: false, message: data.error || 'Connection failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to connect to download client' });
      }
    } catch (error) {
      setValidated({ ...validated, download: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test connection';
      setTestResults({ ...testResults, download: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const testPaths = async () => {
    if (!settings) return;

    setTesting(true);
    setMessage(null);

    try {
      const response = await fetch('/api/setup/test-paths', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          downloadDir: settings.paths.downloadDir,
          mediaDir: settings.paths.mediaDir,
        }),
      });

      const data = await response.json();

      if (data.success) {
        setValidated({ ...validated, paths: true });
        setTestResults({ ...testResults, paths: { success: true, message: 'All paths are valid and writable' } });
        setMessage({ type: 'success', text: 'All paths are valid and writable. You can now save.' });
      } else {
        setValidated({ ...validated, paths: false });
        setTestResults({ ...testResults, paths: { success: false, message: data.error || 'Path validation failed' } });
        setMessage({ type: 'error', text: data.error || 'Failed to validate paths' });
      }
    } catch (error) {
      setValidated({ ...validated, paths: false });
      const errorMsg = error instanceof Error ? error.message : 'Failed to test paths';
      setTestResults({ ...testResults, paths: { success: false, message: errorMsg } });
      setMessage({ type: 'error', text: errorMsg });
    } finally {
      setTesting(false);
    }
  };

  const changePassword = async () => {
    setChangingPassword(true);
    setMessage(null);

    try {
      const response = await fetchWithAuth('/api/admin/settings/change-password', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(passwordForm),
      });

      const data = await response.json();

      if (data.success) {
        setMessage({ type: 'success', text: 'Password changed successfully!' });
        // Clear form
        setPasswordForm({
          currentPassword: '',
          newPassword: '',
          confirmPassword: '',
        });
        setTimeout(() => setMessage(null), 5000);
      } else {
        setMessage({ type: 'error', text: data.error || 'Failed to change password' });
      }
    } catch (error) {
      setMessage({
        type: 'error',
        text: error instanceof Error ? error.message : 'Failed to change password',
      });
    } finally {
      setChangingPassword(false);
    }
  };

  const saveSettings = async () => {
    if (!settings) return;

    setSaving(true);
    setMessage(null);

    try {
      // Save settings based on active tab
      switch (activeTab) {
        case 'library':
          if (settings.backendMode === 'plex') {
            const plexResponse = await fetchWithAuth('/api/admin/settings/plex', {
              method: 'PUT',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify(settings.plex),
            });

            if (!plexResponse.ok) {
              throw new Error('Failed to save Plex settings');
            }
          } else {
            const absResponse = await fetchWithAuth('/api/admin/settings/audiobookshelf', {
              method: 'PUT',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify(settings.audiobookshelf),
            });

            if (!absResponse.ok) {
              throw new Error('Failed to save Audiobookshelf settings');
            }
          }
          break;

        case 'auth':
          // Validate: In Audiobookshelf mode, at least one auth method must be enabled OR local users must exist
          if (settings.backendMode === 'audiobookshelf') {
            if (!settings.oidc.enabled && !settings.registration.enabled && !settings.hasLocalUsers) {
              setMessage({
                type: 'error',
                text: 'At least one authentication method must be enabled (OIDC or Manual Registration) since no local users exist. Otherwise, you will be locked out of the system.',
              });
              setSaving(false);
              return;
            }
          }

          // Save OIDC settings if OIDC is enabled
          if (settings.oidc.enabled) {
            // Helper function to parse comma-separated strings into JSON arrays
            const parseCommaSeparatedToArray = (str: string): string => {
              if (!str || str.trim() === '') return '[]';
              const items = str.split(',').map(s => s.trim()).filter(s => s.length > 0);
              return JSON.stringify(items);
            };

            const oidcPayload = {
              ...settings.oidc,
              allowedEmails: parseCommaSeparatedToArray(settings.oidc.allowedEmails),
              allowedUsernames: parseCommaSeparatedToArray(settings.oidc.allowedUsernames),
            };

            const oidcResponse = await fetchWithAuth('/api/admin/settings/oidc', {
              method: 'PUT',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify(oidcPayload),
            });

            if (!oidcResponse.ok) {
              throw new Error('Failed to save OIDC settings');
            }
          }

          // Save registration settings
          const registrationResponse = await fetchWithAuth('/api/admin/settings/registration', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(settings.registration),
          });

          if (!registrationResponse.ok) {
            throw new Error('Failed to save registration settings');
          }
          break;

        case 'prowlarr':
          // Save Prowlarr URL and API key
          const prowlarrResponse = await fetchWithAuth('/api/admin/settings/prowlarr', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(settings.prowlarr),
          });

          if (!prowlarrResponse.ok) {
            throw new Error('Failed to save Prowlarr settings');
          }

          // Save indexer configuration if indexers are loaded
          if (indexers.length > 0) {
            const indexersResponse = await fetchWithAuth('/api/admin/settings/prowlarr/indexers', {
              method: 'PUT',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ indexers }),
            });

            if (!indexersResponse.ok) {
              throw new Error('Failed to save indexer configuration');
            }
          }
          break;

        case 'download':
          const downloadResponse = await fetchWithAuth('/api/admin/settings/download-client', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(settings.downloadClient),
          });

          if (!downloadResponse.ok) {
            throw new Error('Failed to save download client settings');
          }
          break;

        case 'paths':
          const pathsResponse = await fetchWithAuth('/api/admin/settings/paths', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(settings.paths),
          });

          if (!pathsResponse.ok) {
            throw new Error('Failed to save paths settings');
          }
          break;

        default:
          throw new Error('Unknown settings tab');
      }

      setMessage({ type: 'success', text: 'Settings saved successfully!' });
      // Update original settings to reflect the saved state
      if (settings) {
        setOriginalSettings(JSON.parse(JSON.stringify(settings)));
      }
      setTimeout(() => setMessage(null), 3000);
    } catch (error) {
      setMessage({
        type: 'error',
        text: error instanceof Error ? error.message : 'Failed to save settings',
      });
    } finally {
      setSaving(false);
    }
  };

  if (loading || !settings) {
    return (
      <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
      </div>
    );
  }

  const tabs = [
    { id: 'library', label: settings?.backendMode === 'plex' ? 'Plex' : 'Audiobookshelf', icon: '📺' },
    ...(settings?.backendMode === 'audiobookshelf' ? [{ id: 'auth', label: 'Authentication', icon: '🔐' }] : []),
    { id: 'prowlarr', label: 'Indexers', icon: '🔍' },
    { id: 'download', label: 'Download Client', icon: '⬇️' },
    { id: 'paths', label: 'Paths', icon: '📁' },
    { id: 'bookdate', label: 'BookDate', icon: '📚' },
    ...(isLocalAdmin ? [{ id: 'account', label: 'Account', icon: '🔒' }] : []),
  ];

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        {/* Header */}
        <div className="mb-8">
          <div className="flex items-center gap-4 mb-4">
            <Link
              href="/admin"
              className="text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100"
            >
              <svg className="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
                <path
                  fillRule="evenodd"
                  d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z"
                  clipRule="evenodd"
                />
              </svg>
            </Link>
            <h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100">Settings</h1>
          </div>
          <p className="text-gray-600 dark:text-gray-400">
            Configure external services and system preferences
          </p>
        </div>

        {/* Backend Mode Display */}
        <div className="mb-6 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
          <div className="flex items-start gap-3">
            <div className="flex-shrink-0 mt-0.5">
              <svg className="w-5 h-5 text-blue-600 dark:text-blue-400" fill="currentColor" viewBox="0 0 20 20">
                <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
              </svg>
            </div>
            <div className="text-sm text-blue-800 dark:text-blue-200">
              <p className="font-medium mb-1">Backend Mode: {settings?.backendMode === 'plex' ? 'Plex' : 'Audiobookshelf'}</p>
              <p>
                ⚠️ Backend mode cannot be changed after setup. To switch backends, you must reset the instance and run the setup wizard again.
              </p>
            </div>
          </div>
        </div>

        {/* Message Banner */}
        {message && (
          <div
            className={`mb-6 rounded-lg p-4 ${
              message.type === 'success'
                ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800'
                : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800'
            }`}
          >
            <p
              className={`text-sm ${
                message.type === 'success'
                  ? 'text-green-800 dark:text-green-200'
                  : 'text-red-800 dark:text-red-200'
              }`}
            >
              {message.text}
            </p>
          </div>
        )}

        <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
          {/* Tabs */}
          <div className="border-b border-gray-200 dark:border-gray-700">
            <nav className="flex -mb-px">
              {tabs.map((tab) => (
                <button
                  key={tab.id}
                  onClick={() => {
                    setActiveTab(tab.id as any);
                    if (tab.id === 'library') {
                      if (settings?.backendMode === 'plex') {
                        fetchPlexLibraries();
                      } else {
                        fetchABSLibraries();
                      }
                    }
                    if (tab.id === 'prowlarr') fetchIndexers();
                  }}
                  className={`px-6 py-4 text-sm font-medium border-b-2 transition-colors ${
                    activeTab === tab.id
                      ? 'border-blue-500 text-blue-600 dark:text-blue-400'
                      : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600'
                  }`}
                >
                  <span className="mr-2">{tab.icon}</span>
                  {tab.label}
                </button>
              ))}
            </nav>
          </div>

          {/* Content */}
          <div className="p-8">
            {/* Library Tab - Conditional (Plex or Audiobookshelf) */}
            {activeTab === 'library' && settings?.backendMode === 'plex' && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Plex Media Server
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure your Plex server connection and audiobook library.
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Server URL
                  </label>
                  <Input
                    type="url"
                    value={settings.plex.url}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        plex: { ...settings.plex, url: e.target.value },
                      });
                      setValidated({ ...validated, plex: false });
                    }}
                    placeholder="http://localhost:32400"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Authentication Token
                  </label>
                  <Input
                    type="password"
                    value={settings.plex.token}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        plex: { ...settings.plex, token: e.target.value },
                      });
                      setValidated({ ...validated, plex: false });
                    }}
                    placeholder="Enter your Plex token"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Find your token in Plex settings → Network → Show Advanced
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Audiobook Library
                  </label>
                  {loadingLibraries ? (
                    <div className="flex items-center gap-2 py-2">
                      <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div>
                      <span className="text-sm text-gray-500">Loading libraries...</span>
                    </div>
                  ) : plexLibraries.length > 0 ? (
                    <select
                      value={settings.plex.libraryId}
                      onChange={(e) => {
                        setSettings({
                          ...settings,
                          plex: { ...settings.plex, libraryId: e.target.value },
                        });
                        setValidated({ ...validated, plex: false });
                      }}
                      className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
                    >
                      <option value="">Select a library...</option>
                      {plexLibraries.map((lib) => (
                        <option key={lib.id} value={lib.id}>
                          {lib.title} ({lib.type})
                        </option>
                      ))}
                    </select>
                  ) : (
                    <div className="text-sm text-gray-500 py-2">
                      Test your connection to load libraries.
                    </div>
                  )}
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={testPlexConnection}
                    loading={testing}
                    disabled={!settings.plex.url || !settings.plex.token}
                    variant="outline"
                    className="w-full"
                  >
                    Test Connection
                  </Button>
                  {testResults.plex && (
                    <div className={`mt-3 p-3 rounded-lg text-sm ${
                      testResults.plex.success
                        ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                        : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                    }`}>
                      {testResults.plex.message}
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* Audiobookshelf Tab */}
            {activeTab === 'library' && settings?.backendMode === 'audiobookshelf' && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Audiobookshelf Server
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure your Audiobookshelf server connection and audiobook library.
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Server URL
                  </label>
                  <Input
                    type="url"
                    value={settings.audiobookshelf.serverUrl}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        audiobookshelf: { ...settings.audiobookshelf, serverUrl: e.target.value },
                      });
                      setValidated({ ...validated, audiobookshelf: false });
                    }}
                    placeholder="http://localhost:13378"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    API Token
                  </label>
                  <Input
                    type="password"
                    value={settings.audiobookshelf.apiToken}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        audiobookshelf: { ...settings.audiobookshelf, apiToken: e.target.value },
                      });
                      setValidated({ ...validated, audiobookshelf: false });
                    }}
                    placeholder="Enter your Audiobookshelf API token"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Found in Audiobookshelf Settings → Users → Your Account → API Tokens
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Audiobook Library
                  </label>
                  {loadingLibraries ? (
                    <div className="flex items-center gap-2 py-2">
                      <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div>
                      <span className="text-sm text-gray-500">Loading libraries...</span>
                    </div>
                  ) : absLibraries.length > 0 ? (
                    <select
                      value={settings.audiobookshelf.libraryId}
                      onChange={(e) => {
                        setSettings({
                          ...settings,
                          audiobookshelf: { ...settings.audiobookshelf, libraryId: e.target.value },
                        });
                        setValidated({ ...validated, audiobookshelf: false });
                      }}
                      className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
                    >
                      <option value="">Select a library...</option>
                      {absLibraries.map((lib) => (
                        <option key={lib.id} value={lib.id}>
                          {lib.name}
                        </option>
                      ))}
                    </select>
                  ) : (
                    <div className="text-sm text-gray-500 py-2">
                      Test your connection to load libraries.
                    </div>
                  )}
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={testABSConnection}
                    loading={testing}
                    disabled={!settings.audiobookshelf.serverUrl || !settings.audiobookshelf.apiToken}
                    variant="outline"
                    className="w-full"
                  >
                    Test Connection
                  </Button>
                  {testResults.audiobookshelf && (
                    <div className={`mt-3 p-3 rounded-lg text-sm ${
                      testResults.audiobookshelf.success
                        ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                        : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                    }`}>
                      {testResults.audiobookshelf.message}
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* Prowlarr/Indexers Tab */}
            {activeTab === 'prowlarr' && (
              <div className="space-y-6 max-w-4xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Indexer Configuration
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure your Prowlarr connection and select which indexers to use with priority and seeding time.
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Prowlarr Server URL
                  </label>
                  <Input
                    type="url"
                    value={settings.prowlarr.url}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        prowlarr: { ...settings.prowlarr, url: e.target.value },
                      });
                      // Only invalidate if URL actually changed from original
                      if (originalSettings && e.target.value !== originalSettings.prowlarr.url) {
                        setValidated({ ...validated, prowlarr: false });
                      }
                    }}
                    placeholder="http://localhost:9696"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Prowlarr API Key
                  </label>
                  <Input
                    type="password"
                    value={settings.prowlarr.apiKey}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        prowlarr: { ...settings.prowlarr, apiKey: e.target.value },
                      });
                      // Only invalidate if API key actually changed from original
                      if (originalSettings && e.target.value !== originalSettings.prowlarr.apiKey) {
                        setValidated({ ...validated, prowlarr: false });
                      }
                    }}
                    placeholder="Enter API key"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Found in Prowlarr Settings → General → Security → API Key
                  </p>
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={testProwlarrConnection}
                    loading={testing}
                    disabled={!settings.prowlarr.url || !settings.prowlarr.apiKey}
                    variant="outline"
                    className="w-full"
                  >
                    {(() => {
                      if (originalSettings &&
                          settings.prowlarr.url === originalSettings.prowlarr.url &&
                          settings.prowlarr.apiKey === originalSettings.prowlarr.apiKey) {
                        return 'Refresh Indexers';
                      }
                      return 'Test Connection';
                    })()}
                  </Button>
                  {testResults.prowlarr && (
                    <div className={`mt-3 p-3 rounded-lg text-sm ${
                      testResults.prowlarr.success
                        ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                        : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                    }`}>
                      {testResults.prowlarr.message}
                    </div>
                  )}
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <div className="flex items-center justify-between mb-4">
                    <h3 className="text-lg font-medium text-gray-900 dark:text-gray-100">
                      Indexer Configuration
                    </h3>
                    {indexers.length > 0 && !loadingIndexers && (
                      <span className="text-sm text-gray-500 dark:text-gray-400">
                        {indexers.filter(idx => idx.enabled).length} enabled
                      </span>
                    )}
                  </div>
                  {loadingIndexers ? (
                    <div className="flex items-center gap-2 py-4">
                      <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div>
                      <span className="text-sm text-gray-500">Loading indexers...</span>
                    </div>
                  ) : indexers.length > 0 ? (
                    <div className="space-y-4">
                      {indexers.map((indexer) => (
                        <div
                          key={indexer.id}
                          className="border border-gray-200 dark:border-gray-700 rounded-lg p-4"
                        >
                          <div className="flex items-start gap-4">
                            <input
                              type="checkbox"
                              checked={indexer.enabled}
                              onChange={(e) => {
                                setIndexers(
                                  indexers.map((idx) =>
                                    idx.id === indexer.id
                                      ? { ...idx, enabled: e.target.checked }
                                      : idx
                                  )
                                );
                              }}
                              className="mt-1 h-5 w-5 rounded border-gray-300"
                            />
                            <div className="flex-1">
                              <div className="flex items-center gap-2 mb-2">
                                <h4 className="font-medium text-gray-900 dark:text-gray-100">
                                  {indexer.name}
                                </h4>
                                <span className="text-xs px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400">
                                  {indexer.protocol}
                                </span>
                              </div>
                              <div className="grid grid-cols-3 gap-4">
                                <div>
                                  <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
                                    Priority (1-25)
                                  </label>
                                  <input
                                    type="number"
                                    min="1"
                                    max="25"
                                    value={indexer.priority}
                                    onChange={(e) => {
                                      const value = parseInt(e.target.value) || 10;
                                      setIndexers(
                                        indexers.map((idx) =>
                                          idx.id === indexer.id
                                            ? { ...idx, priority: Math.max(1, Math.min(25, value)) }
                                            : idx
                                        )
                                      );
                                    }}
                                    disabled={!indexer.enabled}
                                    className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 disabled:opacity-50"
                                  />
                                  <p className="text-xs text-gray-500 mt-1">Higher = preferred</p>
                                </div>
                                <div>
                                  <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
                                    Seeding Time (minutes)
                                  </label>
                                  <input
                                    type="number"
                                    min="0"
                                    value={indexer.seedingTimeMinutes}
                                    onChange={(e) => {
                                      const value = e.target.value === '' ? 0 : parseInt(e.target.value);
                                      setIndexers(
                                        indexers.map((idx) =>
                                          idx.id === indexer.id
                                            ? { ...idx, seedingTimeMinutes: isNaN(value) ? 0 : value }
                                            : idx
                                        )
                                      );
                                    }}
                                    disabled={!indexer.enabled}
                                    className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 disabled:opacity-50"
                                  />
                                  <p className="text-xs text-gray-500 mt-1">0 = unlimited</p>
                                </div>
                                <div>
                                  <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
                                    RSS Monitoring
                                  </label>
                                  <div className="flex items-center h-[42px]">
                                    <input
                                      type="checkbox"
                                      checked={indexer.rssEnabled || false}
                                      onChange={(e) => {
                                        setIndexers(
                                          indexers.map((idx) =>
                                            idx.id === indexer.id
                                              ? { ...idx, rssEnabled: e.target.checked }
                                              : idx
                                          )
                                        );
                                      }}
                                      disabled={!indexer.enabled || indexer.supportsRss === false}
                                      className="h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500 disabled:opacity-50"
                                    />
                                  </div>
                                  <p className="text-xs text-gray-500 mt-1">Auto check for new releases</p>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <div className="text-sm text-gray-500 py-6 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-lg">
                      <p className="mb-2">No indexers configured.</p>
                      <p className="text-xs">
                        {settings.prowlarr.url && settings.prowlarr.apiKey
                          ? 'Click "Refresh Indexers" above to load available indexers from Prowlarr.'
                          : 'Enter your Prowlarr URL and API key above, then click "Test Connection" to load indexers.'}
                      </p>
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* Download Client Tab */}
            {activeTab === 'download' && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Download Client
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure your torrent download client (qBittorrent/Transmission).
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Client Type
                  </label>
                  <select
                    value={settings.downloadClient.type}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        downloadClient: { ...settings.downloadClient, type: e.target.value },
                      });
                      setValidated({ ...validated, download: false });
                    }}
                    className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
                  >
                    <option value="qbittorrent">qBittorrent</option>
                    <option value="transmission">Transmission</option>
                  </select>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Server URL
                  </label>
                  <Input
                    type="url"
                    value={settings.downloadClient.url}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        downloadClient: { ...settings.downloadClient, url: e.target.value },
                      });
                      setValidated({ ...validated, download: false });
                    }}
                    placeholder="http://localhost:8080"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Username
                  </label>
                  <Input
                    type="text"
                    value={settings.downloadClient.username}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        downloadClient: {
                          ...settings.downloadClient,
                          username: e.target.value,
                        },
                      });
                      setValidated({ ...validated, download: false });
                    }}
                    placeholder="admin"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Password
                  </label>
                  <Input
                    type="password"
                    value={settings.downloadClient.password}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        downloadClient: {
                          ...settings.downloadClient,
                          password: e.target.value,
                        },
                      });
                      setValidated({ ...validated, download: false });
                    }}
                    placeholder="Enter password"
                  />
                </div>

                {/* Remote Path Mapping */}
                <div className="mt-6 bg-gray-50 dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
                  <div className="flex items-start gap-4">
                    <input
                      type="checkbox"
                      id="remote-path-mapping"
                      checked={settings.downloadClient.remotePathMappingEnabled}
                      onChange={(e) => {
                        setSettings({
                          ...settings,
                          downloadClient: {
                            ...settings.downloadClient,
                            remotePathMappingEnabled: e.target.checked,
                          },
                        });
                        setValidated({ ...validated, download: false });
                      }}
                      className="mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700"
                    />
                    <div className="flex-1">
                      <label
                        htmlFor="remote-path-mapping"
                        className="block text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
                      >
                        Enable Remote Path Mapping
                      </label>
                      <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                        Use this when qBittorrent runs on a different machine or uses different mount points (e.g., remote seedbox, Docker containers)
                      </p>
                      <p className="text-xs text-gray-500 dark:text-gray-400 mt-2 font-mono">
                        Example: Remote <span className="text-blue-600 dark:text-blue-400">/remote/mnt/d/done</span> → Local <span className="text-green-600 dark:text-green-400">/downloads</span>
                      </p>

                      {/* Warning for existing downloads */}
                      {settings.downloadClient.remotePathMappingEnabled && (
                        <div className="mt-3 p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
                          <p className="text-sm text-yellow-800 dark:text-yellow-200">
                            ⚠️ <strong>Note:</strong> Path mapping only affects new downloads. In-progress downloads will continue using their original paths.
                          </p>
                        </div>
                      )}

                      {/* Conditional Fields */}
                      {settings.downloadClient.remotePathMappingEnabled && (
                        <div className="mt-4 grid grid-cols-2 gap-4">
                          <div>
                            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                              Remote Path (from qBittorrent)
                            </label>
                            <Input
                              type="text"
                              placeholder="/remote/mnt/d/done"
                              value={settings.downloadClient.remotePath}
                              onChange={(e) => {
                                setSettings({
                                  ...settings,
                                  downloadClient: {
                                    ...settings.downloadClient,
                                    remotePath: e.target.value,
                                  },
                                });
                                setValidated({ ...validated, download: false });
                              }}
                            />
                            <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                              The path prefix as reported by qBittorrent
                            </p>
                          </div>

                          <div>
                            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                              Local Path (for ReadMeABook)
                            </label>
                            <Input
                              type="text"
                              placeholder="/downloads"
                              value={settings.downloadClient.localPath}
                              onChange={(e) => {
                                setSettings({
                                  ...settings,
                                  downloadClient: {
                                    ...settings.downloadClient,
                                    localPath: e.target.value,
                                  },
                                });
                                setValidated({ ...validated, download: false });
                              }}
                            />
                            <p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                              The actual path where files are accessible
                            </p>
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={testDownloadClientConnection}
                    loading={testing}
                    disabled={!settings.downloadClient.url || !settings.downloadClient.username || !settings.downloadClient.password}
                    variant="outline"
                    className="w-full"
                  >
                    Test Connection
                  </Button>
                  {testResults.download && (
                    <div className={`mt-3 p-3 rounded-lg text-sm ${
                      testResults.download.success
                        ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                        : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                    }`}>
                      {testResults.download.message}
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* Paths Tab */}
            {activeTab === 'paths' && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Directory Paths
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure download and media directory paths.
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Download Directory
                  </label>
                  <Input
                    type="text"
                    value={settings.paths.downloadDir}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        paths: { ...settings.paths, downloadDir: e.target.value },
                      });
                      setValidated({ ...validated, paths: false });
                    }}
                    placeholder="/downloads"
                    className="font-mono"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Temporary location for torrent downloads (kept for seeding)
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Media Directory
                  </label>
                  <Input
                    type="text"
                    value={settings.paths.mediaDir}
                    onChange={(e) => {
                      setSettings({
                        ...settings,
                        paths: { ...settings.paths, mediaDir: e.target.value },
                      });
                      setValidated({ ...validated, paths: false });
                    }}
                    placeholder="/media/audiobooks"
                    className="font-mono"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Final location for organized audiobook library (Plex scans this directory)
                  </p>
                </div>

                {/* Metadata Tagging Toggle */}
                <div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
                  <div className="flex items-start gap-4">
                    <input
                      type="checkbox"
                      id="metadata-tagging-settings"
                      checked={settings.paths.metadataTaggingEnabled}
                      onChange={(e) => {
                        setSettings({
                          ...settings,
                          paths: { ...settings.paths, metadataTaggingEnabled: e.target.checked },
                        });
                        setValidated({ ...validated, paths: false });
                      }}
                      className="mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                    />
                    <div className="flex-1">
                      <label
                        htmlFor="metadata-tagging-settings"
                        className="block text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
                      >
                        Auto-tag audio files with metadata
                      </label>
                      <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                        Automatically write correct title, author, and narrator metadata to m4b and mp3 files
                        during file organization. This significantly improves Plex matching accuracy for audiobooks
                        with missing or incorrect metadata.
                      </p>
                    </div>
                  </div>
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={testPaths}
                    loading={testing}
                    disabled={!settings.paths.downloadDir || !settings.paths.mediaDir}
                    variant="outline"
                    className="w-full"
                  >
                    Test Paths
                  </Button>
                  {testResults.paths && (
                    <div className={`mt-3 p-3 rounded-lg text-sm ${
                      testResults.paths.success
                        ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                        : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                    }`}>
                      {testResults.paths.message}
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* BookDate Tab */}
            {activeTab === 'bookdate' && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    BookDate Configuration
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure global AI-powered audiobook recommendations. All users share this API key, but receive personalized recommendations based on their individual library and ratings.
                  </p>
                </div>

                {/* Enable/Disable Toggle */}
                {bookdateConfigured && (
                  <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
                    <div className="flex items-center justify-between">
                      <div>
                        <h3 className="font-medium text-gray-900 dark:text-white mb-1">
                          BookDate Feature
                        </h3>
                        <p className="text-sm text-gray-600 dark:text-gray-400">
                          {bookdateEnabled ? 'Feature is currently enabled' : 'Feature is currently disabled'}
                        </p>
                      </div>
                      <label className="relative inline-flex items-center cursor-pointer">
                        <input
                          type="checkbox"
                          checked={bookdateEnabled}
                          onChange={(e) => setBookdateEnabled(e.target.checked)}
                          className="sr-only peer"
                        />
                        <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                      </label>
                    </div>
                  </div>
                )}

                {/* AI Provider */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    AI Provider
                  </label>
                  <select
                    value={bookdateProvider}
                    onChange={(e) => {
                      setBookdateProvider(e.target.value);
                      setBookdateModels([]);
                    }}
                    className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
                  >
                    <option value="openai">OpenAI</option>
                    <option value="claude">Claude (Anthropic)</option>
                  </select>
                </div>

                {/* API Key */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    API Key
                  </label>
                  <Input
                    type="password"
                    value={bookdateApiKey}
                    onChange={(e) => {
                      setBookdateApiKey(e.target.value);
                      setBookdateModels([]);
                    }}
                    placeholder={
                      bookdateConfigured
                        ? '••••••••••••••••'
                        : (bookdateProvider === 'openai' ? 'sk-...' : 'sk-ant-...')
                    }
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    The API key is stored securely and encrypted. Leave blank to keep existing key.
                  </p>
                </div>

                {/* Test Connection Button */}
                <Button
                  onClick={handleTestBookdateConnection}
                  loading={testingBookdate}
                  disabled={!bookdateApiKey.trim() && !bookdateConfigured}
                  variant="outline"
                  className="w-full"
                >
                  {bookdateConfigured && !bookdateApiKey.trim()
                    ? 'Test Connection & Fetch Models (using saved API key)'
                    : 'Test Connection & Fetch Models'}
                </Button>

                {/* Model Selection */}
                {bookdateModels.length > 0 && (
                  <div>
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                      Select Model
                    </label>
                    <select
                      value={bookdateModel}
                      onChange={(e) => setBookdateModel(e.target.value)}
                      className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500"
                    >
                      <option value="">-- Choose a model --</option>
                      {bookdateModels.map((m) => (
                        <option key={m.id} value={m.id}>
                          {m.name}
                        </option>
                      ))}
                    </select>
                  </div>
                )}

                {/* Note about per-user settings */}
                {(bookdateModels.length > 0 || bookdateConfigured) && bookdateModel && (
                  <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
                    <p className="text-sm text-blue-800 dark:text-blue-300">
                      <strong>Note:</strong> Library scope and custom prompt preferences are now configured per-user.
                      Users can adjust these settings in their BookDate preferences (settings icon on the BookDate page).
                    </p>
                  </div>
                )}

                {/* Save Button */}
                {bookdateModel && (
                  <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                    <Button
                      onClick={handleSaveBookdateConfig}
                      loading={saving}
                      disabled={!bookdateModel}
                      className="w-full"
                    >
                      Save BookDate Configuration
                    </Button>
                  </div>
                )}

                {/* Clear Swipe History */}
                {bookdateConfigured && (
                  <div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
                    <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                      Clear All Swipe History
                    </h3>
                    <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
                      Remove all swipe history and cached recommendations for ALL users. This will reset everyone's BookDate recommendations.
                    </p>
                    <Button
                      onClick={handleClearBookdateSwipes}
                      loading={clearingBookdateSwipes}
                      variant="outline"
                      className="border-red-300 text-red-600 hover:bg-red-50 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900/20"
                    >
                      Clear Swipe History
                    </Button>
                  </div>
                )}
              </div>
            )}

            {/* Authentication Tab - Only visible in ABS mode */}
            {activeTab === 'auth' && settings?.backendMode === 'audiobookshelf' && (
              <div className="space-y-8 max-w-2xl">
                {/* OIDC Settings Section */}
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    OIDC Authentication
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure OpenID Connect (OIDC) authentication for single sign-on with Authentik, Keycloak, or other providers.
                  </p>

                  <div className="space-y-4">
                    <div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
                      <div className="flex items-start gap-4">
                        <input
                          type="checkbox"
                          id="oidc-enabled"
                          checked={settings.oidc.enabled}
                          onChange={(e) => {
                            setSettings({
                              ...settings,
                              oidc: { ...settings.oidc, enabled: e.target.checked },
                            });
                            setValidated({ ...validated, oidc: false });
                          }}
                          className="mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <div className="flex-1">
                          <label
                            htmlFor="oidc-enabled"
                            className="block text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
                          >
                            Enable OIDC Authentication
                          </label>
                          <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                            Allow users to log in using an external OIDC provider
                          </p>
                        </div>
                      </div>
                    </div>

                    {settings.oidc.enabled && (
                      <>
                        <div>
                          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                            Provider Name
                          </label>
                          <Input
                            type="text"
                            value={settings.oidc.providerName}
                            onChange={(e) => {
                              setSettings({
                                ...settings,
                                oidc: { ...settings.oidc, providerName: e.target.value },
                              });
                              setValidated({ ...validated, oidc: false });
                            }}
                            placeholder="Authentik"
                          />
                          <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                            Display name for the login button
                          </p>
                        </div>

                        <div>
                          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                            Issuer URL
                          </label>
                          <Input
                            type="url"
                            value={settings.oidc.issuerUrl}
                            onChange={(e) => {
                              setSettings({
                                ...settings,
                                oidc: { ...settings.oidc, issuerUrl: e.target.value },
                              });
                              setValidated({ ...validated, oidc: false });
                            }}
                            placeholder="https://auth.example.com/application/o/readmeabook/"
                          />
                          <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                            OIDC provider's issuer URL (must support .well-known/openid-configuration)
                          </p>
                        </div>

                        <div>
                          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                            Client ID
                          </label>
                          <Input
                            type="text"
                            value={settings.oidc.clientId}
                            onChange={(e) => {
                              setSettings({
                                ...settings,
                                oidc: { ...settings.oidc, clientId: e.target.value },
                              });
                              setValidated({ ...validated, oidc: false });
                            }}
                            placeholder="readmeabook-client"
                          />
                        </div>

                        <div>
                          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                            Client Secret
                          </label>
                          <Input
                            type="password"
                            value={settings.oidc.clientSecret}
                            onChange={(e) => {
                              setSettings({
                                ...settings,
                                oidc: { ...settings.oidc, clientSecret: e.target.value },
                              });
                              setValidated({ ...validated, oidc: false });
                            }}
                            placeholder="Enter client secret"
                          />
                        </div>

                        <div className="border-t border-gray-200 dark:border-gray-700 pt-4">
                          <Button
                            onClick={testOIDCConnection}
                            loading={testing}
                            disabled={!settings.oidc.issuerUrl || !settings.oidc.clientId || !settings.oidc.clientSecret}
                            variant="outline"
                            className="w-full"
                          >
                            Test OIDC Configuration
                          </Button>
                          {testResults.oidc && (
                            <div className={`mt-3 p-3 rounded-lg text-sm ${
                              testResults.oidc.success
                                ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
                                : 'bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200'
                            }`}>
                              {testResults.oidc.message}
                            </div>
                          )}
                        </div>

                        {/* Access Control Section */}
                        <div className="border-t border-gray-200 dark:border-gray-700 pt-6 mt-6">
                          <h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">
                            Access Control
                          </h3>
                          <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
                            Control who can log in to your application. This is separate from admin permissions.
                          </p>

                          <div className="space-y-4">
                            <div>
                              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                Access Control Method
                              </label>
                              <select
                                value={settings.oidc.accessControlMethod}
                                onChange={(e) => {
                                  setSettings({
                                    ...settings,
                                    oidc: { ...settings.oidc, accessControlMethod: e.target.value },
                                  });
                                  setValidated({ ...validated, oidc: false });
                                }}
                                className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
                              >
                                <option value="open">Open Access (anyone can log in)</option>
                                <option value="group_claim">Group/Claim Based</option>
                                <option value="allowed_list">Allowed List (emails/usernames)</option>
                                <option value="admin_approval">Admin Approval Required</option>
                              </select>
                              <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                {settings.oidc.accessControlMethod === 'open' && 'Anyone who can authenticate with your OIDC provider will have access'}
                                {settings.oidc.accessControlMethod === 'group_claim' && 'Only users with a specific group/claim can access'}
                                {settings.oidc.accessControlMethod === 'allowed_list' && 'Only explicitly allowed users can access'}
                                {settings.oidc.accessControlMethod === 'admin_approval' && 'New users must be approved by an admin before access is granted'}
                              </p>
                            </div>

                            {settings.oidc.accessControlMethod === 'group_claim' && (
                              <>
                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Group Claim Name
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.accessGroupClaim}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, accessGroupClaim: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="groups"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    The OIDC claim field that contains group membership (usually "groups" or "roles")
                                  </p>
                                </div>

                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Required Group
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.accessGroupValue}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, accessGroupValue: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="readmeabook-users"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    Users must be in this group to access the application
                                  </p>
                                </div>
                              </>
                            )}

                            {settings.oidc.accessControlMethod === 'allowed_list' && (
                              <>
                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Allowed Emails (comma-separated)
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.allowedEmails}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, allowedEmails: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="user1@example.com, user2@example.com"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    Enter email addresses separated by commas
                                  </p>
                                </div>

                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Allowed Usernames (comma-separated)
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.allowedUsernames}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, allowedUsernames: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="john_doe, jane_smith"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    Enter usernames separated by commas
                                  </p>
                                </div>
                              </>
                            )}
                          </div>
                        </div>

                        {/* Admin Role Mapping Section */}
                        <div className="border-t border-gray-200 dark:border-gray-700 pt-6 mt-6">
                          <h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">
                            Admin Role Mapping
                          </h3>
                          <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
                            Automatically grant admin permissions based on OIDC claims (e.g., group membership). The first user will always become admin.
                          </p>

                          <div className="space-y-4">
                            <div className="flex items-start gap-3">
                              <input
                                type="checkbox"
                                id="admin-claim-enabled"
                                checked={settings.oidc.adminClaimEnabled}
                                onChange={(e) => {
                                  setSettings({
                                    ...settings,
                                    oidc: { ...settings.oidc, adminClaimEnabled: e.target.checked },
                                  });
                                  setValidated({ ...validated, oidc: false });
                                }}
                                className="mt-1 h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
                              />
                              <div className="flex-1">
                                <label
                                  htmlFor="admin-claim-enabled"
                                  className="text-sm font-medium text-gray-700 dark:text-gray-300 cursor-pointer"
                                >
                                  Enable Admin Role Mapping
                                </label>
                                <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                  Automatically grant admin role to users with specific OIDC claim values
                                </p>
                              </div>
                            </div>

                            {settings.oidc.adminClaimEnabled && (
                              <>
                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Admin Claim Name
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.adminClaimName}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, adminClaimName: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="groups"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    The OIDC claim field to check for admin role (usually "groups" or "roles")
                                  </p>
                                </div>

                                <div>
                                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                                    Admin Claim Value
                                  </label>
                                  <Input
                                    type="text"
                                    value={settings.oidc.adminClaimValue}
                                    onChange={(e) => {
                                      setSettings({
                                        ...settings,
                                        oidc: { ...settings.oidc, adminClaimValue: e.target.value },
                                      });
                                      setValidated({ ...validated, oidc: false });
                                    }}
                                    placeholder="readmeabook-admin"
                                  />
                                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                                    Users with this value in their claim will be granted admin role
                                  </p>
                                </div>

                                <div className="bg-amber-50 dark:bg-amber-900/20 rounded-lg p-4 border border-amber-200 dark:border-amber-800">
                                  <div className="flex gap-3">
                                    <svg
                                      className="w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5"
                                      fill="currentColor"
                                      viewBox="0 0 20 20"
                                    >
                                      <path
                                        fillRule="evenodd"
                                        d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
                                        clipRule="evenodd"
                                      />
                                    </svg>
                                    <div>
                                      <p className="text-sm font-medium text-amber-900 dark:text-amber-100">
                                        Example Configuration
                                      </p>
                                      <p className="text-sm text-amber-700 dark:text-amber-300 mt-1">
                                        In Authentik: Create a group called "readmeabook-admin", add users to it, and set "Admin Claim Value" to "readmeabook-admin"
                                      </p>
                                    </div>
                                  </div>
                                </div>
                              </>
                            )}
                          </div>
                        </div>
                      </>
                    )}
                  </div>
                </div>

                {/* Registration Settings Section */}
                <div className="border-t border-gray-200 dark:border-gray-700 pt-8">
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Manual Registration
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Configure manual user registration settings.
                  </p>

                  <div className="space-y-4">
                    <div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
                      <div className="flex items-start gap-4">
                        <input
                          type="checkbox"
                          id="registration-enabled"
                          checked={settings.registration.enabled}
                          onChange={(e) => {
                            setSettings({
                              ...settings,
                              registration: { ...settings.registration, enabled: e.target.checked },
                            });
                            setValidated({ ...validated, registration: false });
                          }}
                          className="mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <div className="flex-1">
                          <label
                            htmlFor="registration-enabled"
                            className="block text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
                          >
                            Enable Manual Registration
                          </label>
                          <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                            Allow users to create accounts manually with username/password
                          </p>
                        </div>
                      </div>
                    </div>

                    {settings.registration.enabled && (
                      <div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
                        <div className="flex items-start gap-4">
                          <input
                            type="checkbox"
                            id="require-approval"
                            checked={settings.registration.requireAdminApproval}
                            onChange={(e) => {
                              setSettings({
                                ...settings,
                                registration: { ...settings.registration, requireAdminApproval: e.target.checked },
                              });
                              setValidated({ ...validated, registration: false });
                            }}
                            className="mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                          />
                          <div className="flex-1">
                            <label
                              htmlFor="require-approval"
                              className="block text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
                            >
                              Require Admin Approval
                            </label>
                            <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                              New users must be approved by an admin before they can log in
                            </p>
                          </div>
                        </div>
                      </div>
                    )}
                  </div>
                </div>

                {/* Warning: No auth methods enabled AND no local users exist */}
                {settings.backendMode === 'audiobookshelf' && !settings.oidc.enabled && !settings.registration.enabled && !settings.hasLocalUsers && (
                  <div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4">
                    <div className="flex gap-3">
                      <svg className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                      </svg>
                      <div>
                        <h3 className="text-sm font-semibold text-red-800 dark:text-red-200">
                          No Authentication Methods Available
                        </h3>
                        <p className="text-sm text-red-700 dark:text-red-300 mt-1">
                          You must enable at least one authentication method (OIDC or Manual Registration) since no local users exist.
                          Saving with both disabled will lock you out of the system.
                        </p>
                      </div>
                    </div>
                  </div>
                )}

                {/* Info: Registration disabled but local users can still log in */}
                {settings.backendMode === 'audiobookshelf' && !settings.oidc.enabled && !settings.registration.enabled && settings.hasLocalUsers && (
                  <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
                    <div className="flex gap-3">
                      <svg className="w-5 h-5 text-blue-500 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                      </svg>
                      <div>
                        <h3 className="text-sm font-semibold text-blue-800 dark:text-blue-200">
                          Manual Registration Disabled
                        </h3>
                        <p className="text-sm text-blue-700 dark:text-blue-300 mt-1">
                          New user registration is disabled. Existing local users can still log in with their credentials.
                        </p>
                      </div>
                    </div>
                  </div>
                )}

                {/* Pending Users Section */}
                {settings.registration.enabled && settings.registration.requireAdminApproval && (
                  <div className="border-t border-gray-200 dark:border-gray-700 pt-8">
                    <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                      Pending User Approvals
                    </h2>
                    <p className="text-gray-600 dark:text-gray-400 mb-6">
                      Review and approve or reject user registration requests.
                    </p>

                    {loadingPendingUsers ? (
                      <div className="flex items-center gap-2 py-4">
                        <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div>
                        <span className="text-sm text-gray-500">Loading pending users...</span>
                      </div>
                    ) : pendingUsers.length > 0 ? (
                      <div className="space-y-4">
                        {pendingUsers.map((user) => (
                          <div
                            key={user.id}
                            className="border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-white dark:bg-gray-800"
                          >
                            <div className="flex items-start justify-between">
                              <div className="flex-1">
                                <h3 className="font-medium text-gray-900 dark:text-gray-100">
                                  {user.plexUsername}
                                </h3>
                                {user.plexEmail && (
                                  <p className="text-sm text-gray-600 dark:text-gray-400">
                                    {user.plexEmail}
                                  </p>
                                )}
                                <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">
                                  Registered: {new Date(user.createdAt).toLocaleDateString()}
                                </p>
                              </div>
                              <div className="flex gap-2">
                                <Button
                                  onClick={() => approveUser(user.id, true)}
                                  variant="outline"
                                  className="border-green-300 text-green-600 hover:bg-green-50 dark:border-green-700 dark:text-green-400 dark:hover:bg-green-900/20"
                                >
                                  Approve
                                </Button>
                                <Button
                                  onClick={() => approveUser(user.id, false)}
                                  variant="outline"
                                  className="border-red-300 text-red-600 hover:bg-red-50 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900/20"
                                >
                                  Reject
                                </Button>
                              </div>
                            </div>
                          </div>
                        ))}
                      </div>
                    ) : (
                      <div className="text-center py-8 border border-dashed border-gray-300 dark:border-gray-600 rounded-lg">
                        <p className="text-gray-500 dark:text-gray-400">
                          No pending user approvals
                        </p>
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}

            {/* Account Tab - Only visible to local admin */}
            {activeTab === 'account' && isLocalAdmin && (
              <div className="space-y-6 max-w-2xl">
                <div>
                  <h2 className="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">
                    Account Security
                  </h2>
                  <p className="text-gray-600 dark:text-gray-400 mb-6">
                    Change your local admin account password.
                  </p>
                </div>

                {/* Info Box */}
                <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
                  <div className="flex items-start gap-3">
                    <div className="flex-shrink-0 mt-0.5">
                      <svg className="w-5 h-5 text-blue-600 dark:text-blue-400" fill="currentColor" viewBox="0 0 20 20">
                        <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
                      </svg>
                    </div>
                    <div className="text-sm text-blue-800 dark:text-blue-200">
                      <p className="font-medium mb-1">Local Admin Account</p>
                      <p>
                        This password is for your local admin account created during setup.
                        This is separate from media server authentication and is used to log in to the admin portal.
                      </p>
                    </div>
                  </div>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Current Password
                  </label>
                  <Input
                    type="password"
                    value={passwordForm.currentPassword}
                    onChange={(e) =>
                      setPasswordForm({ ...passwordForm, currentPassword: e.target.value })
                    }
                    placeholder="Enter current password"
                    autoComplete="current-password"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    New Password
                  </label>
                  <Input
                    type="password"
                    value={passwordForm.newPassword}
                    onChange={(e) =>
                      setPasswordForm({ ...passwordForm, newPassword: e.target.value })
                    }
                    placeholder="Enter new password"
                    autoComplete="new-password"
                  />
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    Must be at least 8 characters
                  </p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                    Confirm New Password
                  </label>
                  <Input
                    type="password"
                    value={passwordForm.confirmPassword}
                    onChange={(e) =>
                      setPasswordForm({ ...passwordForm, confirmPassword: e.target.value })
                    }
                    placeholder="Confirm new password"
                    autoComplete="new-password"
                  />
                </div>

                <div className="border-t border-gray-200 dark:border-gray-700 pt-6">
                  <Button
                    onClick={changePassword}
                    loading={changingPassword}
                    disabled={
                      !passwordForm.currentPassword ||
                      !passwordForm.newPassword ||
                      !passwordForm.confirmPassword ||
                      passwordForm.newPassword.length < 8 ||
                      passwordForm.newPassword !== passwordForm.confirmPassword
                    }
                    className="w-full bg-blue-600 hover:bg-blue-700"
                  >
                    Change Password
                  </Button>
                </div>
              </div>
            )}
          </div>

          {/* Footer - Hide for Account tab */}
          {activeTab !== 'account' && activeTab !== 'bookdate' && (
            <div className="bg-gray-50 dark:bg-gray-900 px-8 py-4 border-t border-gray-200 dark:border-gray-700">
              <div className="flex justify-end gap-4">
                <Button variant="outline" onClick={() => window.location.reload()}>
                  Cancel
                </Button>
                <Button
                  onClick={saveSettings}
                  loading={saving}
                  disabled={(() => {
                    // For Library tab: check validation based on backend mode
                    if (activeTab === 'library' && settings) {
                      if (settings.backendMode === 'plex') {
                        return !validated.plex;
                      } else {
                        return !validated.audiobookshelf;
                      }
                    }
                    // For Auth tab: disable if no auth methods are enabled AND no local users exist in Audiobookshelf mode
                    if (activeTab === 'auth' && settings) {
                      if (settings.backendMode === 'audiobookshelf') {
                        // Allow disabling both if local users exist (they can still log in)
                        // Prevent disabling both if no local users exist (would lock out system)
                        return !settings.oidc.enabled && !settings.registration.enabled && !settings.hasLocalUsers;
                      }
                      return false;
                    }
                    // For Prowlarr tab: allow save if validated OR if URL/API key unchanged
                    if (activeTab === 'prowlarr' && originalSettings && settings) {
                      const connectionUnchanged =
                        settings.prowlarr.url === originalSettings.prowlarr.url &&
                        settings.prowlarr.apiKey === originalSettings.prowlarr.apiKey;
                      return !validated.prowlarr && !connectionUnchanged;
                    }
                    // For other tabs: require validation
                    if (activeTab === 'download') return !validated.download;
                    if (activeTab === 'paths') return !validated.paths;

                    // Default: allow save
                    return false;
                  })()}
                >
                  Save Changes
                </Button>
              </div>
              {(() => {
                // For Library tab: check based on backend mode
                if (activeTab === 'library' && settings) {
                  if (settings.backendMode === 'plex' && !validated.plex) {
                    return (
                      <p className="text-sm text-amber-600 dark:text-amber-400 mt-2 text-right">
                        Please test your connection before saving
                      </p>
                    );
                  }
                  if (settings.backendMode === 'audiobookshelf' && !validated.audiobookshelf) {
                    return (
                      <p className="text-sm text-amber-600 dark:text-amber-400 mt-2 text-right">
                        Please test your connection before saving
                      </p>
                    );
                  }
                }
                // For Auth tab: no validation message (toggles don't need testing)
                if (activeTab === 'auth') {
                  return null;
                }
                // For Prowlarr: show message only if URL/API key changed and not validated
                if (activeTab === 'prowlarr' && originalSettings && settings) {
                  const connectionChanged =
                    settings.prowlarr.url !== originalSettings.prowlarr.url ||
                    settings.prowlarr.apiKey !== originalSettings.prowlarr.apiKey;
                  if (connectionChanged && !validated.prowlarr) {
                    return (
                      <p className="text-sm text-amber-600 dark:text-amber-400 mt-2 text-right">
                        Please test your connection before saving
                      </p>
                    );
                  }
                }
                // For other tabs: show message if not validated
                if (activeTab === 'download' && !validated.download) {
                  return (
                    <p className="text-sm text-amber-600 dark:text-amber-400 mt-2 text-right">
                      Please test your connection before saving
                    </p>
                  );
                }
                if (activeTab === 'paths' && !validated.paths) {
                  return (
                    <p className="text-sm text-amber-600 dark:text-amber-400 mt-2 text-right">
                      Please test paths before saving
                    </p>
                  );
                }
                return null;
              })()}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
