/**
 * CreateTriggerModal - Modal for creating event triggers
 *
 * Supports trigger types:
 * - webhook: External HTTP request trigger
 * - event: ZCLAW internal event trigger
 * - message: Chat message pattern trigger
 */

import { useState, useEffect, useCallback } from 'react';
import { useHandStore } from '../store/handStore';
import { useWorkflowStore } from '../store/workflowStore';
import {
  Zap,
  X,
  AlertCircle,
  CheckCircle,
  Loader2,
  Globe,
  MessageSquare,
  Bell,
} from 'lucide-react';

// === ReDoS Protection ===

const MAX_PATTERN_LENGTH = 200;
const REGEX_TIMEOUT_MS = 100;

// Dangerous regex patterns that can cause catastrophic backtracking
const DANGEROUS_PATTERNS = [
  /\([^)]*\+[^)]*\)\+/,      // Nested quantifiers like (a+)+
  /\([^)]*\*[^)]*\)\*/,      // Nested quantifiers like (a*)*
  /\([^)]*\+[^)]*\)\*/,      // Mixed nested quantifiers
  /\([^)]*\*[^)]*\)\+/,      // Mixed nested quantifiers
  /\.\*\.\*/,                // Multiple greedy wildcards
  /\.+\.\+/,                 // Multiple greedy wildcards
  /(.*)\1{3,}/,              // Backreference loops
];

function validateRegexPattern(pattern: string): { valid: boolean; error?: string } {
  // Length check
  if (pattern.length > MAX_PATTERN_LENGTH) {
    return { valid: false, error: `Pattern too long (max ${MAX_PATTERN_LENGTH} chars)` };
  }

  // Check for dangerous constructs
  for (const dangerous of DANGEROUS_PATTERNS) {
    if (dangerous.test(pattern)) {
      return { valid: false, error: 'Pattern contains potentially dangerous constructs' };
    }
  }

  // Validate syntax and check execution time
  try {
    const regex = new RegExp(pattern);
    const testString = 'a'.repeat(20) + 'b'.repeat(20);
    const start = Date.now();
    regex.test(testString);
    const elapsed = Date.now() - start;

    if (elapsed > REGEX_TIMEOUT_MS) {
      return { valid: false, error: 'Pattern is too complex (execution timeout)' };
    }

    return { valid: true };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : 'Invalid pattern';
    return { valid: false, error: `Invalid regular expression: ${message}` };
  }
}

// === Types ===

type TriggerType = 'webhook' | 'event' | 'message';
type TargetType = 'hand' | 'workflow';

interface TriggerFormData {
  name: string;
  type: TriggerType;
  pattern: string;
  targetType: TargetType;
  targetId: string;
  webhookPath: string;
  eventType: string;
  enabled: boolean;
}

interface CreateTriggerModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
}

const initialFormData: TriggerFormData = {
  name: '',
  type: 'webhook',
  pattern: '',
  targetType: 'hand',
  targetId: '',
  webhookPath: '',
  eventType: '',
  enabled: true,
};

// === Trigger Type Options ===

const triggerTypeOptions: Array<{
  value: TriggerType;
  label: string;
  description: string;
  icon: React.ComponentType<{ className?: string }>;
}> = [
  {
    value: 'webhook',
    label: 'Webhook',
    description: 'External HTTP request trigger',
    icon: Globe,
  },
  {
    value: 'event',
    label: 'Event',
    description: 'ZCLAW internal event trigger',
    icon: Bell,
  },
  {
    value: 'message',
    label: 'Message',
    description: 'Chat message pattern trigger',
    icon: MessageSquare,
  },
];

// === Event Type Options ===

const eventTypeOptions = [
  { value: 'file_changed', label: 'File Changed' },
  { value: 'agent_started', label: 'Agent Started' },
  { value: 'agent_stopped', label: 'Agent Stopped' },
  { value: 'hand_completed', label: 'Hand Completed' },
  { value: 'workflow_completed', label: 'Workflow Completed' },
  { value: 'session_created', label: 'Session Created' },
  { value: 'custom', label: 'Custom Event' },
];

// === Component ===

export function CreateTriggerModal({ isOpen, onClose, onSuccess }: CreateTriggerModalProps) {
  // Store state - use domain stores
  const hands = useHandStore((s) => s.hands);
  const workflows = useWorkflowStore((s) => s.workflows);
  const createTrigger = useHandStore((s) => s.createTrigger);
  const loadHands = useHandStore((s) => s.loadHands);
  const loadWorkflows = useWorkflowStore((s) => s.loadWorkflows);
  const [formData, setFormData] = useState<TriggerFormData>(initialFormData);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle');
  const [errorMessage, setErrorMessage] = useState('');

  // Load available targets on mount
  useEffect(() => {
    if (isOpen) {
      loadHands();
      loadWorkflows();
    }
  }, [isOpen, loadHands, loadWorkflows]);

  // Reset form when modal opens
  useEffect(() => {
    if (isOpen) {
      setFormData(initialFormData);
      setErrors({});
      setSubmitStatus('idle');
      setErrorMessage('');
    }
  }, [isOpen]);

  // Validate form
  const validateForm = useCallback((): boolean => {
    const newErrors: Record<string, string> = {};

    if (!formData.name.trim()) {
      newErrors.name = 'Trigger name is required';
    }

    switch (formData.type) {
      case 'webhook':
        if (!formData.webhookPath.trim()) {
          newErrors.webhookPath = 'Webhook path is required';
        } else if (!formData.webhookPath.startsWith('/')) {
          newErrors.webhookPath = 'Webhook path must start with /';
        }
        break;
      case 'event':
        if (!formData.eventType) {
          newErrors.eventType = 'Event type is required';
        }
        break;
      case 'message':
        if (!formData.pattern.trim()) {
          newErrors.pattern = 'Pattern is required';
        } else {
          // Validate regex pattern with ReDoS protection
          const validation = validateRegexPattern(formData.pattern);
          if (!validation.valid) {
            newErrors.pattern = validation.error || 'Invalid pattern';
          }
        }
        break;
    }

    if (!formData.targetId) {
      newErrors.targetId = 'Please select a target';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [formData]);

  // Handle form submission
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!validateForm()) {
      return;
    }

    setIsSubmitting(true);
    setSubmitStatus('idle');
    setErrorMessage('');

    try {
      // Build config based on trigger type
      const config: Record<string, unknown> = {};

      switch (formData.type) {
        case 'webhook':
          config.path = formData.webhookPath;
          break;
        case 'event':
          config.eventType = formData.eventType;
          break;
        case 'message':
          config.pattern = formData.pattern;
          break;
      }

      await createTrigger({
        type: formData.type,
        name: formData.name.trim(),
        enabled: formData.enabled,
        config,
        handName: formData.targetType === 'hand' ? formData.targetId : undefined,
        workflowId: formData.targetType === 'workflow' ? formData.targetId : undefined,
      });

      setSubmitStatus('success');
      setTimeout(() => {
        onSuccess();
        onClose();
      }, 1500);
    } catch (err) {
      setSubmitStatus('error');
      setErrorMessage(err instanceof Error ? err.message : 'Failed to create trigger');
    } finally {
      setIsSubmitting(false);
    }
  };

  // Update form field
  const updateField = <K extends keyof TriggerFormData>(field: K, value: TriggerFormData[K]) => {
    setFormData(prev => ({ ...prev, [field]: value }));
    // Clear error when field is updated
    if (errors[field]) {
      setErrors(prev => {
        const newErrors = { ...prev };
        delete newErrors[field];
        return newErrors;
      });
    }
  };

  // Get available targets based on type
  const getAvailableTargets = (): Array<{ id: string; name?: string }> => {
    switch (formData.targetType) {
      case 'hand':
        return hands.map(h => ({ id: h.id, name: h.name }));
      case 'workflow':
        return workflows.map(w => ({ id: w.id, name: w.name }));
      default:
        return [];
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/50 backdrop-blur-sm"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg mx-4 max-h-[90vh] overflow-hidden flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
          <div className="flex items-center gap-3">
            <div className="w-8 h-8 bg-amber-100 dark:bg-amber-900/30 rounded-lg flex items-center justify-center">
              <Zap className="w-4 h-4 text-amber-600 dark:text-amber-400" />
            </div>
            <div>
              <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
                Create Event Trigger
              </h2>
              <p className="text-xs text-gray-500 dark:text-gray-400">
                Create a trigger to respond to events
              </p>
            </div>
          </div>
          <button
            onClick={onClose}
            className="p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Form */}
        <form onSubmit={handleSubmit} className="flex-1 overflow-y-auto p-4 space-y-4">
          {/* Trigger Name */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
              Trigger Name <span className="text-red-500">*</span>
            </label>
            <input
              type="text"
              value={formData.name}
              onChange={(e) => updateField('name', e.target.value)}
              placeholder="e.g., Daily Report Webhook"
              className={`w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-amber-500 ${
                errors.name ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
              }`}
            />
            {errors.name && (
              <p className="mt-1 text-xs text-red-500 flex items-center gap-1">
                <AlertCircle className="w-3 h-3" />
                {errors.name}
              </p>
            )}
          </div>

          {/* Trigger Type */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
              Trigger Type <span className="text-red-500">*</span>
            </label>
            <div className="grid grid-cols-3 gap-2">
              {triggerTypeOptions.map((option) => {
                const Icon = option.icon;
                return (
                  <button
                    key={option.value}
                    type="button"
                    onClick={() => updateField('type', option.value as TriggerType)}
                    className={`flex flex-col items-center gap-1 p-3 text-sm rounded-lg border transition-colors ${
                      formData.type === option.value
                        ? 'bg-amber-600 text-white border-amber-600'
                        : 'bg-white dark:bg-gray-900 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:border-amber-500'
                    }`}
                  >
                    <Icon className="w-5 h-5" />
                    <span>{option.label}</span>
                  </button>
                );
              })}
            </div>
            <p className="mt-1 text-xs text-gray-400">
              {triggerTypeOptions.find(o => o.value === formData.type)?.description}
            </p>
          </div>

          {/* Webhook Path */}
          {formData.type === 'webhook' && (
            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                Webhook Path <span className="text-red-500">*</span>
              </label>
              <input
                type="text"
                value={formData.webhookPath}
                onChange={(e) => updateField('webhookPath', e.target.value)}
                placeholder="/api/webhooks/daily-report"
                className={`w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-amber-500 font-mono ${
                  errors.webhookPath ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
                }`}
              />
              {errors.webhookPath && (
                <p className="mt-1 text-xs text-red-500 flex items-center gap-1">
                  <AlertCircle className="w-3 h-3" />
                  {errors.webhookPath}
                </p>
              )}
              <p className="mt-1 text-xs text-gray-400">
                The URL path that will trigger this action when called
              </p>
            </div>
          )}

          {/* Event Type */}
          {formData.type === 'event' && (
            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                Event Type <span className="text-red-500">*</span>
              </label>
              <select
                value={formData.eventType}
                onChange={(e) => updateField('eventType', e.target.value)}
                className={`w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-amber-500 ${
                  errors.eventType ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
                }`}
              >
                <option value="">-- Select Event Type --</option>
                {eventTypeOptions.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
              {errors.eventType && (
                <p className="mt-1 text-xs text-red-500 flex items-center gap-1">
                  <AlertCircle className="w-3 h-3" />
                  {errors.eventType}
                </p>
              )}
            </div>
          )}

          {/* Message Pattern */}
          {formData.type === 'message' && (
            <div>
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                Message Pattern <span className="text-red-500">*</span>
              </label>
              <input
                type="text"
                value={formData.pattern}
                onChange={(e) => updateField('pattern', e.target.value)}
                placeholder="^/report"
                className={`w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-amber-500 font-mono ${
                  errors.pattern ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
                }`}
              />
              {errors.pattern && (
                <p className="mt-1 text-xs text-red-500 flex items-center gap-1">
                  <AlertCircle className="w-3 h-3" />
                  {errors.pattern}
                </p>
              )}
              <p className="mt-1 text-xs text-gray-400">
                Regular expression pattern to match chat messages
              </p>
            </div>
          )}

          {/* Target Selection */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
              Target Type
            </label>
            <div className="flex gap-2">
              {[
                { value: 'hand', label: 'Hand' },
                { value: 'workflow', label: 'Workflow' },
              ].map((option) => (
                <button
                  key={option.value}
                  type="button"
                  onClick={() => {
                    updateField('targetType', option.value as TargetType);
                    updateField('targetId', ''); // Reset target when type changes
                  }}
                  className={`flex-1 px-3 py-2 text-sm rounded-lg border transition-colors ${
                    formData.targetType === option.value
                      ? 'bg-amber-600 text-white border-amber-600'
                      : 'bg-white dark:bg-gray-900 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:border-amber-500'
                  }`}
                >
                  {option.label}
                </button>
              ))}
            </div>
          </div>

          {/* Target Selection Dropdown */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
              Select Target <span className="text-red-500">*</span>
            </label>
            <select
              value={formData.targetId}
              onChange={(e) => updateField('targetId', e.target.value)}
              className={`w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-amber-500 ${
                errors.targetId ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
              }`}
            >
              <option value="">-- Please Select --</option>
              {getAvailableTargets().map((target) => (
                <option key={target.id} value={target.id}>
                  {target.name || target.id}
                </option>
              ))}
            </select>
            {errors.targetId && (
              <p className="mt-1 text-xs text-red-500 flex items-center gap-1">
                <AlertCircle className="w-3 h-3" />
                {errors.targetId}
              </p>
            )}
            {getAvailableTargets().length === 0 && (
              <p className="mt-1 text-xs text-gray-400">
                No {formData.targetType === 'hand' ? 'Hands' : 'Workflows'} available
              </p>
            )}
          </div>

          {/* Enabled Toggle */}
          <div className="flex items-center gap-2">
            <input
              type="checkbox"
              id="trigger-enabled"
              checked={formData.enabled}
              onChange={(e) => updateField('enabled', e.target.checked)}
              className="w-4 h-4 text-amber-600 border-gray-300 rounded focus:ring-amber-500"
            />
            <label htmlFor="trigger-enabled" className="text-sm text-gray-700 dark:text-gray-300">
              Enable immediately after creation
            </label>
          </div>

          {/* Status Messages */}
          {submitStatus === 'success' && (
            <div className="flex items-center gap-2 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg text-green-700 dark:text-green-400">
              <CheckCircle className="w-5 h-5 flex-shrink-0" />
              <span className="text-sm">Trigger created successfully!</span>
            </div>
          )}
          {submitStatus === 'error' && (
            <div className="flex items-center gap-2 p-3 bg-red-50 dark:bg-red-900/20 rounded-lg text-red-700 dark:text-red-400">
              <AlertCircle className="w-5 h-5 flex-shrink-0" />
              <span className="text-sm">{errorMessage}</span>
            </div>
          )}
        </form>

        {/* Footer */}
        <div className="flex items-center justify-end gap-2 p-4 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
          <button
            type="button"
            onClick={onClose}
            disabled={isSubmitting}
            className="px-4 py-2 text-sm text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            type="submit"
            onClick={handleSubmit}
            disabled={isSubmitting || submitStatus === 'success'}
            className="px-4 py-2 text-sm text-white bg-amber-600 rounded-lg hover:bg-amber-700 transition-colors disabled:opacity-50 flex items-center gap-2"
          >
            {isSubmitting ? (
              <>
                <Loader2 className="w-4 h-4 animate-spin" />
                Creating...
              </>
            ) : (
              <>
                <Zap className="w-4 h-4" />
                Create Trigger
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  );
}

export default CreateTriggerModal;
