import { useState, useEffect } from 'react';
import { Webhook, CreateWebhookRequest, UpdateWebhookRequest, WebhookEvent } from '@/services/api';
import { X, Plus, Trash2, Eye, EyeOff, Copy, Check } from 'lucide-react';
import clsx from 'clsx';

/**
 * Props for the WebhookForm component.
 */
interface WebhookFormProps {
  /** Existing webhook data for editing, or null/undefined for creating a new webhook */
  webhook?: Webhook | null;
  /** List of available webhook events that can be subscribed to */
  events: WebhookEvent[];
  /** Callback invoked when the form is submitted with valid data */
  onSubmit: (data: CreateWebhookRequest | UpdateWebhookRequest) => void;
  /** Callback invoked when the user cancels the form */
  onCancel: () => void;
  /** Whether the form submission is in progress */
  isLoading?: boolean;
}

/**
 * Form component for creating or editing webhook configurations.
 *
 * @description Provides a comprehensive form for webhook management including:
 * - Name and description fields
 * - HTTPS endpoint URL with validation
 * - Event selection checkboxes
 * - Custom HTTP headers management
 * - Signing secret display (edit mode only)
 *
 * @param props - The component props
 * @param props.webhook - Existing webhook data for editing, or null for creating
 * @param props.events - List of available webhook events to subscribe to
 * @param props.onSubmit - Callback when form is submitted with valid data
 * @param props.onCancel - Callback when user cancels the form
 * @param props.isLoading - Whether submission is in progress (disables form)
 *
 * @example
 * ```tsx
 * // Creating a new webhook
 * <WebhookForm
 *   events={availableEvents}
 *   onSubmit={(data) => createWebhook(data)}
 *   onCancel={() => closeModal()}
 * />
 *
 * // Editing an existing webhook
 * <WebhookForm
 *   webhook={existingWebhook}
 *   events={availableEvents}
 *   onSubmit={(data) => updateWebhook(existingWebhook.id, data)}
 *   onCancel={() => closeModal()}
 *   isLoading={isSaving}
 * />
 * ```
 */
export function WebhookForm({
  webhook,
  events,
  onSubmit,
  onCancel,
  isLoading,
}: WebhookFormProps) {
  const [name, setName] = useState(webhook?.name || '');
  const [description, setDescription] = useState(webhook?.description || '');
  const [url, setUrl] = useState(webhook?.url || '');
  const [selectedEvents, setSelectedEvents] = useState<string[]>(webhook?.events || []);
  const [headers, setHeaders] = useState<{ key: string; value: string }[]>(
    webhook?.headers
      ? Object.entries(webhook.headers).map(([key, value]) => ({ key, value }))
      : []
  );
  const [showSecret, setShowSecret] = useState(false);
  const [secretCopied, setSecretCopied] = useState(false);

  const isEditing = !!webhook;

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    const headersObj = headers.reduce((acc, { key, value }) => {
      if (key.trim()) {
        acc[key.trim()] = value;
      }
      return acc;
    }, {} as Record<string, string>);

    const data = {
      name,
      description: description || undefined,
      url,
      events: selectedEvents,
      headers: Object.keys(headersObj).length > 0 ? headersObj : undefined,
    };

    onSubmit(data);
  };

  const toggleEvent = (eventName: string) => {
    setSelectedEvents((prev) =>
      prev.includes(eventName)
        ? prev.filter((e) => e !== eventName)
        : [...prev, eventName]
    );
  };

  const addHeader = () => {
    setHeaders((prev) => [...prev, { key: '', value: '' }]);
  };

  const removeHeader = (index: number) => {
    setHeaders((prev) => prev.filter((_, i) => i !== index));
  };

  const updateHeader = (index: number, field: 'key' | 'value', value: string) => {
    setHeaders((prev) =>
      prev.map((h, i) => (i === index ? { ...h, [field]: value } : h))
    );
  };

  const copySecret = async () => {
    if (webhook?.secret) {
      await navigator.clipboard.writeText(webhook.secret);
      setSecretCopied(true);
      setTimeout(() => setSecretCopied(false), 2000);
    }
  };

  const isValid = name.trim() && url.trim() && url.startsWith('https://') && selectedEvents.length > 0;

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      {/* Name */}
      <div>
        <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">
          Name *
        </label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="My Webhook"
          className="w-full px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-white dark:bg-secondary-800 text-secondary-900 dark:text-secondary-100 focus:ring-2 focus:ring-primary-500"
          required
        />
      </div>

      {/* Description */}
      <div>
        <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">
          Description
        </label>
        <input
          type="text"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          placeholder="Optional description"
          className="w-full px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-white dark:bg-secondary-800 text-secondary-900 dark:text-secondary-100 focus:ring-2 focus:ring-primary-500"
        />
      </div>

      {/* URL */}
      <div>
        <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">
          Endpoint URL *
        </label>
        <input
          type="url"
          value={url}
          onChange={(e) => setUrl(e.target.value)}
          placeholder="https://example.com/webhook"
          className="w-full px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-white dark:bg-secondary-800 text-secondary-900 dark:text-secondary-100 focus:ring-2 focus:ring-primary-500"
          required
        />
        {url && !url.startsWith('https://') && (
          <p className="mt-1 text-sm text-red-600">URL must use HTTPS</p>
        )}
      </div>

      {/* Secret (only for editing) */}
      {isEditing && webhook?.secret && (
        <div>
          <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">
            Signing Secret
          </label>
          <div className="flex items-center gap-2">
            <div className="flex-1 relative">
              <input
                type={showSecret ? 'text' : 'password'}
                value={webhook.secret}
                readOnly
                className="w-full px-3 py-2 pr-20 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-secondary-50 dark:bg-secondary-900 text-secondary-900 dark:text-secondary-100 font-mono text-sm"
              />
              <div className="absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1">
                <button
                  type="button"
                  onClick={() => setShowSecret(!showSecret)}
                  className="p-1 text-secondary-400 hover:text-secondary-600"
                >
                  {showSecret ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                </button>
                <button
                  type="button"
                  onClick={copySecret}
                  className="p-1 text-secondary-400 hover:text-secondary-600"
                >
                  {secretCopied ? (
                    <Check className="w-4 h-4 text-green-500" />
                  ) : (
                    <Copy className="w-4 h-4" />
                  )}
                </button>
              </div>
            </div>
          </div>
          <p className="mt-1 text-xs text-secondary-500">
            Use this secret to verify webhook signatures
          </p>
        </div>
      )}

      {/* Events */}
      <div>
        <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-2">
          Events * ({selectedEvents.length} selected)
        </label>
        <div className="border border-secondary-300 dark:border-secondary-600 rounded-lg p-3 max-h-48 overflow-y-auto">
          <div className="space-y-2">
            {events.map((event) => (
              <label
                key={event.name}
                className="flex items-start gap-3 p-2 rounded hover:bg-secondary-50 dark:hover:bg-secondary-700/50 cursor-pointer"
              >
                <input
                  type="checkbox"
                  checked={selectedEvents.includes(event.name)}
                  onChange={() => toggleEvent(event.name)}
                  className="mt-0.5 rounded border-secondary-300 text-primary-600 focus:ring-primary-500"
                />
                <div>
                  <div className="text-sm font-medium text-secondary-900 dark:text-secondary-100">
                    {event.name}
                  </div>
                  <div className="text-xs text-secondary-500">{event.description}</div>
                </div>
              </label>
            ))}
          </div>
        </div>
        {selectedEvents.length === 0 && (
          <p className="mt-1 text-sm text-red-600">Select at least one event</p>
        )}
      </div>

      {/* Custom Headers */}
      <div>
        <div className="flex items-center justify-between mb-2">
          <label className="block text-sm font-medium text-secondary-700 dark:text-secondary-300">
            Custom Headers
          </label>
          <button
            type="button"
            onClick={addHeader}
            className="text-sm text-primary-600 hover:text-primary-700 flex items-center gap-1"
          >
            <Plus className="w-4 h-4" />
            Add Header
          </button>
        </div>
        {headers.length > 0 && (
          <div className="space-y-2">
            {headers.map((header, index) => (
              <div key={index} className="flex items-center gap-2">
                <input
                  type="text"
                  value={header.key}
                  onChange={(e) => updateHeader(index, 'key', e.target.value)}
                  placeholder="Header name"
                  className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-white dark:bg-secondary-800 text-secondary-900 dark:text-secondary-100 text-sm"
                />
                <input
                  type="text"
                  value={header.value}
                  onChange={(e) => updateHeader(index, 'value', e.target.value)}
                  placeholder="Value"
                  className="flex-1 px-3 py-2 border border-secondary-300 dark:border-secondary-600 rounded-lg bg-white dark:bg-secondary-800 text-secondary-900 dark:text-secondary-100 text-sm"
                />
                <button
                  type="button"
                  onClick={() => removeHeader(index)}
                  className="p-2 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded"
                >
                  <Trash2 className="w-4 h-4" />
                </button>
              </div>
            ))}
          </div>
        )}
        {headers.length === 0 && (
          <p className="text-sm text-secondary-500">No custom headers</p>
        )}
      </div>

      {/* Actions */}
      <div className="flex items-center justify-end gap-3 pt-4 border-t border-secondary-200 dark:border-secondary-700">
        <button
          type="button"
          onClick={onCancel}
          className="px-4 py-2 text-secondary-700 dark:text-secondary-300 hover:bg-secondary-100 dark:hover:bg-secondary-700 rounded-lg"
        >
          Cancel
        </button>
        <button
          type="submit"
          disabled={!isValid || isLoading}
          className={clsx(
            'px-4 py-2 rounded-lg font-medium',
            isValid && !isLoading
              ? 'bg-primary-600 text-white hover:bg-primary-700'
              : 'bg-secondary-200 text-secondary-400 cursor-not-allowed'
          )}
        >
          {isLoading ? 'Saving...' : isEditing ? 'Update Webhook' : 'Create Webhook'}
        </button>
      </div>
    </form>
  );
}
