'use client';

import { useState, useEffect } from 'react';
import { RMABLogger } from '@/lib/utils/logger';
import { fetchWithAuth } from '@/lib/utils/api';
import { EVENT_LABELS } from '@/lib/constants/notification-events';

const logger = RMABLogger.create('NotificationsTab');

interface ProviderConfigField {
  name: string;
  label: string;
  type: 'text' | 'password' | 'select' | 'number';
  required: boolean;
  placeholder?: string;
  defaultValue?: string | number;
  options?: { label: string; value: string | number }[];
}

interface ProviderMetadata {
  type: string;
  displayName: string;
  description: string;
  iconLabel: string;
  iconColor: string;
  configFields: ProviderConfigField[];
}

interface NotificationBackend {
  id: string;
  type: string;
  name: string;
  config: Record<string, any>;
  events: string[];
  enabled: boolean;
  createdAt: string;
  updatedAt: string;
}

interface ModalState {
  isOpen: boolean;
  mode: 'add' | 'edit';
  selectedType?: string;
  backend?: NotificationBackend;
}

const eventLabels: Record<string, string> = EVENT_LABELS;

export function NotificationsTab() {
  const [backends, setBackends] = useState<NotificationBackend[]>([]);
  const [providerMetadata, setProviderMetadata] = useState<ProviderMetadata[]>([]);
  const [loading, setLoading] = useState(true);
  const [modalState, setModalState] = useState<ModalState>({
    isOpen: false,
    mode: 'add',
  });
  const [formData, setFormData] = useState<any>({
    name: '',
    config: {},
    events: ['request_available', 'request_error'],
    enabled: true,
  });
  const [testResult, setTestResult] = useState<{ success: boolean; message: string } | null>(null);
  const [isTesting, setIsTesting] = useState(false);
  const [isSaving, setIsSaving] = useState(false);

  useEffect(() => {
    fetchBackends();
    fetchProviderMetadata();
  }, []);

  const fetchProviderMetadata = async () => {
    try {
      const response = await fetchWithAuth('/api/admin/notifications/providers');
      if (response.ok) {
        const data = await response.json();
        if (data.success) {
          setProviderMetadata(data.providers);
        }
      }
    } catch (error) {
      logger.error('Failed to fetch provider metadata', { error: error instanceof Error ? error.message : String(error) });
    }
  };

  const fetchBackends = async () => {
    try {
      setLoading(true);
      const response = await fetchWithAuth('/api/admin/notifications');

      if (response.ok) {
        const data = await response.json();
        if (data.success) {
          setBackends(data.backends);
        } else {
          logger.error('Failed to fetch backends', { error: data.error });
        }
      } else {
        logger.error('Failed to fetch backends', { status: response.status });
      }
    } catch (error) {
      logger.error('Failed to fetch backends', { error: error instanceof Error ? error.message : String(error) });
    } finally {
      setLoading(false);
    }
  };

  const getMetadataForType = (type: string): ProviderMetadata | undefined => {
    return providerMetadata.find((p) => p.type === type);
  };

  const openAddModal = (type: string) => {
    const meta = getMetadataForType(type);
    const defaultConfig: Record<string, any> = {};
    if (meta) {
      for (const field of meta.configFields) {
        defaultConfig[field.name] = field.defaultValue ?? '';
      }
    }

    setModalState({ isOpen: true, mode: 'add', selectedType: type });
    setFormData({
      name: `${meta?.displayName ?? type} Notifications`,
      config: defaultConfig,
      events: ['request_available', 'request_error'],
      enabled: true,
    });
    setTestResult(null);
  };

  const openEditModal = (backend: NotificationBackend) => {
    setModalState({ isOpen: true, mode: 'edit', selectedType: backend.type, backend });
    setFormData({
      name: backend.name,
      config: backend.config,
      events: backend.events,
      enabled: backend.enabled,
    });
    setTestResult(null);
  };

  const closeModal = () => {
    setModalState({ isOpen: false, mode: 'add' });
    setTestResult(null);
  };

  const handleTest = async () => {
    if (!modalState.selectedType) return;

    try {
      setIsTesting(true);
      setTestResult(null);

      // In edit mode, use backend ID to test with real config (masked values won't work)
      // In add mode, use the form config directly
      const testPayload = modalState.mode === 'edit' && modalState.backend
        ? { backendId: modalState.backend.id }
        : { type: modalState.selectedType, config: formData.config };

      const response = await fetchWithAuth('/api/admin/notifications/test', {
        method: 'POST',
        body: JSON.stringify(testPayload),
      });

      const data = await response.json();

      if (response.ok && data.success) {
        setTestResult({ success: true, message: 'Test notification sent successfully!' });
      } else {
        setTestResult({ success: false, message: data.message || 'Failed to send test notification' });
      }
    } catch (error) {
      setTestResult({ success: false, message: error instanceof Error ? error.message : 'Unknown error' });
    } finally {
      setIsTesting(false);
    }
  };

  const handleSave = async () => {
    if (!modalState.selectedType) return;

    try {
      setIsSaving(true);

      const url = modalState.mode === 'add' ? '/api/admin/notifications' : `/api/admin/notifications/${modalState.backend?.id}`;
      const method = modalState.mode === 'add' ? 'POST' : 'PUT';

      const response = await fetchWithAuth(url, {
        method,
        body: JSON.stringify({
          type: modalState.selectedType,
          ...formData,
        }),
      });

      const data = await response.json();

      if (response.ok && data.success) {
        await fetchBackends();
        closeModal();
      } else {
        setTestResult({ success: false, message: data.message || 'Failed to save backend' });
      }
    } catch (error) {
      setTestResult({ success: false, message: error instanceof Error ? error.message : 'Unknown error' });
    } finally {
      setIsSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm('Are you sure you want to delete this notification backend?')) return;

    try {
      const response = await fetchWithAuth(`/api/admin/notifications/${id}`, {
        method: 'DELETE',
      });

      if (response.ok) {
        const data = await response.json();
        if (data.success) {
          await fetchBackends();
        }
      }
    } catch (error) {
      logger.error('Failed to delete backend', { error: error instanceof Error ? error.message : String(error) });
    }
  };

  const renderConfigField = (field: ProviderConfigField) => {
    if (field.type === 'select' && field.options) {
      return (
        <div key={field.name}>
          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
            {field.label}{field.required ? ' *' : ''}
          </label>
          <select
            value={formData.config[field.name] ?? field.defaultValue ?? ''}
            onChange={(e) => {
              const value = field.options?.some((o) => typeof o.value === 'number')
                ? Number(e.target.value)
                : e.target.value;
              setFormData({ ...formData, config: { ...formData.config, [field.name]: value } });
            }}
            className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
          >
            {field.options.map((opt) => (
              <option key={String(opt.value)} value={opt.value}>{opt.label}</option>
            ))}
          </select>
        </div>
      );
    }

    return (
      <div key={field.name}>
        <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
          {field.label}{field.required ? ' *' : field.label.includes('optional') ? '' : ' (optional)'}
        </label>
        <input
          type={field.type === 'password' ? 'password' : 'text'}
          value={formData.config[field.name] ?? ''}
          onChange={(e) => setFormData({ ...formData, config: { ...formData.config, [field.name]: e.target.value } })}
          className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
          placeholder={field.placeholder}
        />
      </div>
    );
  };

  const currentMeta = modalState.selectedType ? getMetadataForType(modalState.selectedType) : undefined;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h2 className="text-2xl font-bold text-gray-900 dark:text-white">Notifications</h2>
        <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
          Configure notification backends to receive alerts for audiobook request events.
        </p>
      </div>

      {/* Type Selector */}
      <div>
        <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">Add Notification Backend</h3>
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          {providerMetadata.map((meta) => (
            <button
              key={meta.type}
              onClick={() => openAddModal(meta.type)}
              className="flex items-center p-4 bg-white dark:bg-gray-800 rounded-lg border-2 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 transition-colors"
            >
              <div className={`flex-shrink-0 w-12 h-12 ${meta.iconColor} rounded-lg flex items-center justify-center text-white font-bold text-2xl`}>
                {meta.iconLabel}
              </div>
              <div className="ml-4 text-left">
                <div className="font-semibold text-gray-900 dark:text-white">{meta.displayName}</div>
                <div className="text-sm text-gray-600 dark:text-gray-400">{meta.description}</div>
              </div>
            </button>
          ))}
        </div>
      </div>

      {/* Configured Backends */}
      <div>
        <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">Configured Backends</h3>
        {loading ? (
          <p className="text-gray-600 dark:text-gray-400">Loading...</p>
        ) : backends.length === 0 ? (
          <p className="text-gray-600 dark:text-gray-400">No notification backends configured.</p>
        ) : (
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {backends.map((backend) => {
              const meta = getMetadataForType(backend.type);
              return (
                <div key={backend.id} className="bg-white dark:bg-gray-800 rounded-lg shadow-md border border-gray-200 dark:border-gray-700 p-4 hover:shadow-lg transition-shadow">
                  <div className="flex items-start justify-between mb-3">
                    <div className="flex items-center space-x-3">
                      <div className={`w-10 h-10 ${meta?.iconColor ?? 'bg-gray-500'} rounded-lg flex items-center justify-center text-white font-bold`}>
                        {meta?.iconLabel ?? backend.type.charAt(0).toUpperCase()}
                      </div>
                      <div>
                        <div className="font-semibold text-gray-900 dark:text-white truncate">{backend.name}</div>
                        <div className="text-xs text-gray-500 dark:text-gray-400">{meta?.displayName ?? backend.type}</div>
                      </div>
                    </div>
                  </div>
                  <div className="space-y-2 mb-3">
                    <div className={`inline-block px-2 py-1 rounded text-xs ${backend.enabled ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' : 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300'}`}>
                      {backend.enabled ? 'Enabled' : 'Disabled'}
                    </div>
                    <div className="text-sm text-gray-600 dark:text-gray-400">
                      {backend.events.length} {backend.events.length === 1 ? 'event' : 'events'} subscribed
                    </div>
                  </div>
                  <div className="flex space-x-2">
                    <button
                      onClick={() => openEditModal(backend)}
                      className="flex-1 px-3 py-1.5 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded transition-colors"
                    >
                      Edit
                    </button>
                    <button
                      onClick={() => handleDelete(backend.id)}
                      className="flex-1 px-3 py-1.5 text-sm bg-red-600 hover:bg-red-700 text-white rounded transition-colors"
                    >
                      Delete
                    </button>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Modal */}
      {modalState.isOpen && modalState.selectedType && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
            <div className="p-6">
              <div className="flex items-center justify-between mb-6">
                <h3 className="text-xl font-bold text-gray-900 dark:text-white">
                  {modalState.mode === 'add' ? 'Add' : 'Edit'} {currentMeta?.displayName ?? modalState.selectedType} Notification
                </h3>
                <button onClick={closeModal} className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                  <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </div>

              <div className="space-y-4">
                {/* Name */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label>
                  <input
                    type="text"
                    value={formData.name}
                    onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                    className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
                    placeholder="e.g., Discord - Admins"
                  />
                </div>

                {/* Dynamic Config Fields */}
                {currentMeta?.configFields.map((field) => renderConfigField(field))}

                {/* Events */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Subscribe to Events *</label>
                  <div className="space-y-2">
                    {Object.entries(eventLabels).map(([event, label]) => (
                      <label key={event} className="flex items-center space-x-2 p-3 border border-gray-300 dark:border-gray-600 rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700">
                        <input
                          type="checkbox"
                          checked={formData.events.includes(event)}
                          onChange={(e) => {
                            if (e.target.checked) {
                              setFormData({ ...formData, events: [...formData.events, event] });
                            } else {
                              setFormData({ ...formData, events: formData.events.filter((e: string) => e !== event) });
                            }
                          }}
                          className="rounded"
                        />
                        <span className="text-sm text-gray-900 dark:text-white">{label}</span>
                      </label>
                    ))}
                  </div>
                </div>

                {/* Enabled Toggle */}
                <div>
                  <label className="flex items-center space-x-2 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={formData.enabled}
                      onChange={(e) => setFormData({ ...formData, enabled: e.target.checked })}
                      className="rounded"
                    />
                    <span className="text-sm text-gray-900 dark:text-white">Enable this notification backend</span>
                  </label>
                </div>

                {/* Test Result */}
                {testResult && (
                  <div className={`p-3 rounded-lg ${testResult.success ? 'bg-green-100 dark:bg-green-900 border border-green-300 dark:border-green-700 text-green-800 dark:text-green-200' : 'bg-red-100 dark:bg-red-900 border border-red-300 dark:border-red-700 text-red-800 dark:text-red-200'}`}>
                    {testResult.message}
                  </div>
                )}

                {/* Actions */}
                <div className="flex justify-between pt-4 border-t border-gray-200 dark:border-gray-700">
                  <button
                    onClick={handleTest}
                    disabled={isTesting}
                    className="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-50"
                  >
                    {isTesting ? 'Testing...' : 'Send Test'}
                  </button>
                  <div className="flex space-x-2">
                    <button
                      onClick={closeModal}
                      className="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700"
                    >
                      Cancel
                    </button>
                    <button
                      onClick={handleSave}
                      disabled={isSaving}
                      className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg disabled:opacity-50"
                    >
                      {isSaving ? 'Saving...' : (modalState.mode === 'add' ? 'Add Backend' : 'Save Changes')}
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
