import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import {
  listUpstreamSources,
  createUpstreamSource,
  updateUpstreamSource,
  deleteUpstreamSource,
  testUpstreamSource,
  getCacheSettings,
  updateCacheSettings,
} from '../api';
import { UpstreamSource, CacheSettings, SourceType, AuthType } from '../types';
import './AdminCachePage.css';

const SOURCE_TYPES: SourceType[] = ['npm', 'pypi', 'maven', 'docker', 'helm', 'nuget', 'deb', 'rpm', 'generic'];
const AUTH_TYPES: AuthType[] = ['none', 'basic', 'bearer', 'api_key'];

function AdminCachePage() {
  const { user, loading: authLoading } = useAuth();
  const navigate = useNavigate();

  // Upstream sources state
  const [sources, setSources] = useState<UpstreamSource[]>([]);
  const [loadingSources, setLoadingSources] = useState(true);
  const [sourcesError, setSourcesError] = useState<string | null>(null);

  // Cache settings state
  const [settings, setSettings] = useState<CacheSettings | null>(null);
  const [loadingSettings, setLoadingSettings] = useState(true);
  const [settingsError, setSettingsError] = useState<string | null>(null);

  // Create/Edit form state
  const [showForm, setShowForm] = useState(false);
  const [editingSource, setEditingSource] = useState<UpstreamSource | null>(null);
  const [formData, setFormData] = useState({
    name: '',
    source_type: 'generic' as SourceType,
    url: '',
    enabled: true,
    is_public: true,
    auth_type: 'none' as AuthType,
    username: '',
    password: '',
    priority: 100,
  });
  const [formError, setFormError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);

  // Test result state
  const [testingId, setTestingId] = useState<string | null>(null);
  const [testResults, setTestResults] = useState<Record<string, { success: boolean; message: string }>>({});

  // Delete confirmation state
  const [deletingId, setDeletingId] = useState<string | null>(null);

  // Settings update state
  const [updatingSettings, setUpdatingSettings] = useState(false);

  // Success message
  const [successMessage, setSuccessMessage] = useState<string | null>(null);

  useEffect(() => {
    if (!authLoading && !user) {
      navigate('/login', { state: { from: '/admin/cache' } });
    }
  }, [user, authLoading, navigate]);

  useEffect(() => {
    if (user && user.is_admin) {
      loadSources();
      loadSettings();
    }
  }, [user]);

  useEffect(() => {
    if (successMessage) {
      const timer = setTimeout(() => setSuccessMessage(null), 3000);
      return () => clearTimeout(timer);
    }
  }, [successMessage]);

  async function loadSources() {
    setLoadingSources(true);
    setSourcesError(null);
    try {
      const data = await listUpstreamSources();
      setSources(data);
    } catch (err) {
      setSourcesError(err instanceof Error ? err.message : 'Failed to load sources');
    } finally {
      setLoadingSources(false);
    }
  }

  async function loadSettings() {
    setLoadingSettings(true);
    setSettingsError(null);
    try {
      const data = await getCacheSettings();
      setSettings(data);
    } catch (err) {
      setSettingsError(err instanceof Error ? err.message : 'Failed to load settings');
    } finally {
      setLoadingSettings(false);
    }
  }

  function openCreateForm() {
    setEditingSource(null);
    setFormData({
      name: '',
      source_type: 'generic',
      url: '',
      enabled: true,
      is_public: true,
      auth_type: 'none',
      username: '',
      password: '',
      priority: 100,
    });
    setFormError(null);
    setShowForm(true);
  }

  function openEditForm(source: UpstreamSource) {
    setEditingSource(source);
    setFormData({
      name: source.name,
      source_type: source.source_type,
      url: source.url,
      enabled: source.enabled,
      is_public: source.is_public,
      auth_type: source.auth_type,
      username: source.username || '',
      password: '',
      priority: source.priority,
    });
    setFormError(null);
    setShowForm(true);
  }

  async function handleFormSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!formData.name.trim()) {
      setFormError('Name is required');
      return;
    }
    if (!formData.url.trim()) {
      setFormError('URL is required');
      return;
    }

    setIsSaving(true);
    setFormError(null);

    try {
      if (editingSource) {
        // Update existing source
        await updateUpstreamSource(editingSource.id, {
          name: formData.name.trim(),
          source_type: formData.source_type,
          url: formData.url.trim(),
          enabled: formData.enabled,
          is_public: formData.is_public,
          auth_type: formData.auth_type,
          username: formData.username.trim() || undefined,
          password: formData.password || undefined,
          priority: formData.priority,
        });
        setSuccessMessage('Source updated successfully');
      } else {
        // Create new source
        await createUpstreamSource({
          name: formData.name.trim(),
          source_type: formData.source_type,
          url: formData.url.trim(),
          enabled: formData.enabled,
          is_public: formData.is_public,
          auth_type: formData.auth_type,
          username: formData.username.trim() || undefined,
          password: formData.password || undefined,
          priority: formData.priority,
        });
        setSuccessMessage('Source created successfully');
      }
      setShowForm(false);
      await loadSources();
    } catch (err) {
      setFormError(err instanceof Error ? err.message : 'Failed to save source');
    } finally {
      setIsSaving(false);
    }
  }

  async function handleDelete(source: UpstreamSource) {
    if (!window.confirm(`Delete upstream source "${source.name}"? This cannot be undone.`)) {
      return;
    }

    setDeletingId(source.id);
    try {
      await deleteUpstreamSource(source.id);
      setSuccessMessage(`Source "${source.name}" deleted`);
      await loadSources();
    } catch (err) {
      setSourcesError(err instanceof Error ? err.message : 'Failed to delete source');
    } finally {
      setDeletingId(null);
    }
  }

  async function handleTest(source: UpstreamSource) {
    setTestingId(source.id);
    setTestResults((prev) => ({ ...prev, [source.id]: { success: true, message: 'Testing...' } }));

    try {
      const result = await testUpstreamSource(source.id);
      setTestResults((prev) => ({
        ...prev,
        [source.id]: {
          success: result.success,
          message: result.success
            ? `Connected (${result.elapsed_ms}ms)`
            : result.error || `HTTP ${result.status_code}`,
        },
      }));
    } catch (err) {
      setTestResults((prev) => ({
        ...prev,
        [source.id]: {
          success: false,
          message: err instanceof Error ? err.message : 'Test failed',
        },
      }));
    } finally {
      setTestingId(null);
    }
  }

  async function handleSettingsToggle(field: 'allow_public_internet' | 'auto_create_system_projects') {
    if (!settings) return;

    // Check if env override is active
    const isOverridden =
      (field === 'allow_public_internet' && settings.allow_public_internet_env_override !== null) ||
      (field === 'auto_create_system_projects' && settings.auto_create_system_projects_env_override !== null);

    if (isOverridden) {
      alert('This setting is overridden by an environment variable and cannot be changed via UI.');
      return;
    }

    setUpdatingSettings(true);
    try {
      const update = { [field]: !settings[field] };
      const newSettings = await updateCacheSettings(update);
      setSettings(newSettings);
      setSuccessMessage(`Setting "${field}" updated`);
    } catch (err) {
      setSettingsError(err instanceof Error ? err.message : 'Failed to update settings');
    } finally {
      setUpdatingSettings(false);
    }
  }

  if (authLoading) {
    return <div className="admin-cache-page">Loading...</div>;
  }

  if (!user?.is_admin) {
    return (
      <div className="admin-cache-page">
        <div className="error-message">Access denied. Admin privileges required.</div>
      </div>
    );
  }

  return (
    <div className="admin-cache-page">
      <h1>Cache Management</h1>

      {successMessage && <div className="success-message">{successMessage}</div>}

      {/* Cache Settings Section */}
      <section className="settings-section">
        <h2>Global Settings</h2>
        {loadingSettings ? (
          <p>Loading settings...</p>
        ) : settingsError ? (
          <div className="error-message">{settingsError}</div>
        ) : settings ? (
          <div className="settings-grid">
            <div className="setting-item">
              <label className="toggle-label">
                <span className="setting-name">
                  Allow Public Internet
                  {settings.allow_public_internet_env_override !== null && (
                    <span className="env-badge" title="Overridden by environment variable">
                      ENV
                    </span>
                  )}
                </span>
                <span className="setting-description">
                  When disabled (air-gap mode), requests to public sources are blocked.
                </span>
              </label>
              <button
                className={`toggle-button ${settings.allow_public_internet ? 'on' : 'off'}`}
                onClick={() => handleSettingsToggle('allow_public_internet')}
                disabled={updatingSettings || settings.allow_public_internet_env_override !== null}
              >
                {settings.allow_public_internet ? 'Enabled' : 'Disabled'}
              </button>
            </div>
            <div className="setting-item">
              <label className="toggle-label">
                <span className="setting-name">
                  Auto-create System Projects
                  {settings.auto_create_system_projects_env_override !== null && (
                    <span className="env-badge" title="Overridden by environment variable">
                      ENV
                    </span>
                  )}
                </span>
                <span className="setting-description">
                  Automatically create system projects (_npm, _pypi, etc.) on first cache request.
                </span>
              </label>
              <button
                className={`toggle-button ${settings.auto_create_system_projects ? 'on' : 'off'}`}
                onClick={() => handleSettingsToggle('auto_create_system_projects')}
                disabled={updatingSettings || settings.auto_create_system_projects_env_override !== null}
              >
                {settings.auto_create_system_projects ? 'Enabled' : 'Disabled'}
              </button>
            </div>
          </div>
        ) : null}
      </section>

      {/* Upstream Sources Section */}
      <section className="sources-section">
        <div className="section-header">
          <h2>Upstream Sources</h2>
          <button className="btn btn-primary" onClick={openCreateForm}>
            Add Source
          </button>
        </div>

        {loadingSources ? (
          <p>Loading sources...</p>
        ) : sourcesError ? (
          <div className="error-message">{sourcesError}</div>
        ) : sources.length === 0 ? (
          <p className="empty-message">No upstream sources configured.</p>
        ) : (
          <table className="sources-table">
            <thead>
              <tr>
                <th>Name</th>
                <th>Type</th>
                <th>URL</th>
                <th>Priority</th>
                <th>Status</th>
                <th>Source</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {sources.map((source) => (
                <tr key={source.id} className={source.enabled ? '' : 'disabled-row'}>
                  <td>
                    <span className="source-name">{source.name}</span>
                    {source.is_public && <span className="public-badge">Public</span>}
                  </td>
                  <td>{source.source_type}</td>
                  <td className="url-cell">{source.url}</td>
                  <td>{source.priority}</td>
                  <td>
                    <span className={`status-badge ${source.enabled ? 'enabled' : 'disabled'}`}>
                      {source.enabled ? 'Enabled' : 'Disabled'}
                    </span>
                  </td>
                  <td>
                    {source.source === 'env' ? (
                      <span className="env-badge" title="Defined via environment variable">
                        ENV
                      </span>
                    ) : (
                      'Database'
                    )}
                  </td>
                  <td className="actions-cell">
                    <button
                      className="btn btn-sm"
                      onClick={() => handleTest(source)}
                      disabled={testingId === source.id}
                    >
                      {testingId === source.id ? 'Testing...' : 'Test'}
                    </button>
                    {source.source !== 'env' && (
                      <>
                        <button className="btn btn-sm" onClick={() => openEditForm(source)}>
                          Edit
                        </button>
                        <button
                          className="btn btn-sm btn-danger"
                          onClick={() => handleDelete(source)}
                          disabled={deletingId === source.id}
                        >
                          {deletingId === source.id ? 'Deleting...' : 'Delete'}
                        </button>
                      </>
                    )}
                    {testResults[source.id] && (
                      <span className={`test-result ${testResults[source.id].success ? 'success' : 'failure'}`}>
                        {testResults[source.id].message}
                      </span>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </section>

      {/* Create/Edit Modal */}
      {showForm && (
        <div className="modal-overlay" onClick={() => setShowForm(false)}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <h2>{editingSource ? 'Edit Upstream Source' : 'Add Upstream Source'}</h2>
            <form onSubmit={handleFormSubmit}>
              {formError && <div className="error-message">{formError}</div>}

              <div className="form-group">
                <label htmlFor="name">Name</label>
                <input
                  type="text"
                  id="name"
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  placeholder="e.g., npm-private"
                  required
                />
              </div>

              <div className="form-row">
                <div className="form-group">
                  <label htmlFor="source_type">Type</label>
                  <select
                    id="source_type"
                    value={formData.source_type}
                    onChange={(e) => setFormData({ ...formData, source_type: e.target.value as SourceType })}
                  >
                    {SOURCE_TYPES.map((type) => (
                      <option key={type} value={type}>
                        {type}
                      </option>
                    ))}
                  </select>
                </div>

                <div className="form-group">
                  <label htmlFor="priority">Priority</label>
                  <input
                    type="number"
                    id="priority"
                    value={formData.priority}
                    onChange={(e) => setFormData({ ...formData, priority: parseInt(e.target.value) || 100 })}
                    min="1"
                  />
                  <span className="help-text">Lower = higher priority</span>
                </div>
              </div>

              <div className="form-group">
                <label htmlFor="url">URL</label>
                <input
                  type="url"
                  id="url"
                  value={formData.url}
                  onChange={(e) => setFormData({ ...formData, url: e.target.value })}
                  placeholder="https://registry.example.com"
                  required
                />
              </div>

              <div className="form-row">
                <div className="form-group checkbox-group">
                  <label>
                    <input
                      type="checkbox"
                      checked={formData.enabled}
                      onChange={(e) => setFormData({ ...formData, enabled: e.target.checked })}
                    />
                    Enabled
                  </label>
                </div>
                <div className="form-group checkbox-group">
                  <label>
                    <input
                      type="checkbox"
                      checked={formData.is_public}
                      onChange={(e) => setFormData({ ...formData, is_public: e.target.checked })}
                    />
                    Public Internet Source
                  </label>
                </div>
              </div>

              <div className="form-group">
                <label htmlFor="auth_type">Authentication</label>
                <select
                  id="auth_type"
                  value={formData.auth_type}
                  onChange={(e) => setFormData({ ...formData, auth_type: e.target.value as AuthType })}
                >
                  {AUTH_TYPES.map((type) => (
                    <option key={type} value={type}>
                      {type === 'none' ? 'None' : type === 'api_key' ? 'API Key' : type.charAt(0).toUpperCase() + type.slice(1)}
                    </option>
                  ))}
                </select>
              </div>

              {formData.auth_type !== 'none' && (
                <div className="form-row">
                  {(formData.auth_type === 'basic' || formData.auth_type === 'api_key') && (
                    <div className="form-group">
                      <label htmlFor="username">{formData.auth_type === 'api_key' ? 'Header Name' : 'Username'}</label>
                      <input
                        type="text"
                        id="username"
                        value={formData.username}
                        onChange={(e) => setFormData({ ...formData, username: e.target.value })}
                        placeholder={formData.auth_type === 'api_key' ? 'X-API-Key' : 'username'}
                      />
                    </div>
                  )}
                  <div className="form-group">
                    <label htmlFor="password">
                      {formData.auth_type === 'bearer'
                        ? 'Token'
                        : formData.auth_type === 'api_key'
                        ? 'API Key Value'
                        : 'Password'}
                    </label>
                    <input
                      type="password"
                      id="password"
                      value={formData.password}
                      onChange={(e) => setFormData({ ...formData, password: e.target.value })}
                      placeholder={editingSource ? '(unchanged)' : ''}
                    />
                    {editingSource && (
                      <span className="help-text">Leave empty to keep existing {formData.auth_type === 'bearer' ? 'token' : 'credentials'}</span>
                    )}
                  </div>
                </div>
              )}

              <div className="form-actions">
                <button type="button" className="btn" onClick={() => setShowForm(false)}>
                  Cancel
                </button>
                <button type="submit" className="btn btn-primary" disabled={isSaving}>
                  {isSaving ? 'Saving...' : editingSource ? 'Update' : 'Create'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

export default AdminCachePage;
