/**
 * EventList Component
 *
 * Displays a list of project events with:
 * - Event type icons and styling
 * - Relative timestamps
 * - Actor information
 * - Expandable payload details
 */

'use client';

import { useState } from 'react';
import { formatDistanceToNow } from 'date-fns';
import {
  Bot,
  FileText,
  Users,
  CheckCircle2,
  XCircle,
  PlayCircle,
  AlertTriangle,
  Folder,
  Workflow,
  ChevronDown,
  ChevronRight,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  EventType,
  type ProjectEvent,
  isAgentEvent,
  isIssueEvent,
  isSprintEvent,
  isApprovalEvent,
  isWorkflowEvent,
  isProjectEvent,
} from '@/lib/types/events';

// ============================================================================
// Types
// ============================================================================

interface EventListProps {
  /** Events to display */
  events: ProjectEvent[];
  /** Maximum height for scrolling (default: 400px) */
  maxHeight?: number | string;
  /** Whether to show the header (default: true) */
  showHeader?: boolean;
  /** Title for the header (default: 'Activity Feed') */
  title?: string;
  /** Whether to show event payloads (default: false) */
  showPayloads?: boolean;
  /** Empty state message */
  emptyMessage?: string;
  /** Additional CSS classes */
  className?: string;
  /** Callback when event is clicked */
  onEventClick?: (event: ProjectEvent) => void;
}

interface EventItemProps {
  /** Event to display */
  event: ProjectEvent;
  /** Whether to show payload details */
  showPayload?: boolean;
  /** Callback when clicked */
  onClick?: (event: ProjectEvent) => void;
}

// ============================================================================
// Helper Functions
// ============================================================================

function getEventConfig(event: ProjectEvent) {
  if (isAgentEvent(event)) {
    switch (event.type) {
      case EventType.AGENT_SPAWNED:
        return {
          icon: Bot,
          label: 'Agent Spawned',
          color: 'text-blue-500',
          bgColor: 'bg-blue-100 dark:bg-blue-900',
        };
      case EventType.AGENT_MESSAGE:
        return {
          icon: Bot,
          label: 'Agent Message',
          color: 'text-blue-500',
          bgColor: 'bg-blue-100 dark:bg-blue-900',
        };
      case EventType.AGENT_STATUS_CHANGED:
        return {
          icon: Bot,
          label: 'Status Changed',
          color: 'text-yellow-500',
          bgColor: 'bg-yellow-100 dark:bg-yellow-900',
        };
      case EventType.AGENT_TERMINATED:
        return {
          icon: Bot,
          label: 'Agent Terminated',
          color: 'text-gray-500',
          bgColor: 'bg-gray-100 dark:bg-gray-800',
        };
    }
  }

  if (isIssueEvent(event)) {
    switch (event.type) {
      case EventType.ISSUE_CREATED:
        return {
          icon: FileText,
          label: 'Issue Created',
          color: 'text-green-500',
          bgColor: 'bg-green-100 dark:bg-green-900',
        };
      case EventType.ISSUE_UPDATED:
        return {
          icon: FileText,
          label: 'Issue Updated',
          color: 'text-blue-500',
          bgColor: 'bg-blue-100 dark:bg-blue-900',
        };
      case EventType.ISSUE_ASSIGNED:
        return {
          icon: Users,
          label: 'Issue Assigned',
          color: 'text-purple-500',
          bgColor: 'bg-purple-100 dark:bg-purple-900',
        };
      case EventType.ISSUE_CLOSED:
        return {
          icon: CheckCircle2,
          label: 'Issue Closed',
          color: 'text-green-600',
          bgColor: 'bg-green-100 dark:bg-green-900',
        };
    }
  }

  if (isSprintEvent(event)) {
    return {
      icon: PlayCircle,
      label: event.type === EventType.SPRINT_STARTED ? 'Sprint Started' : 'Sprint Completed',
      color: 'text-indigo-500',
      bgColor: 'bg-indigo-100 dark:bg-indigo-900',
    };
  }

  if (isApprovalEvent(event)) {
    switch (event.type) {
      case EventType.APPROVAL_REQUESTED:
        return {
          icon: AlertTriangle,
          label: 'Approval Requested',
          color: 'text-orange-500',
          bgColor: 'bg-orange-100 dark:bg-orange-900',
        };
      case EventType.APPROVAL_GRANTED:
        return {
          icon: CheckCircle2,
          label: 'Approval Granted',
          color: 'text-green-500',
          bgColor: 'bg-green-100 dark:bg-green-900',
        };
      case EventType.APPROVAL_DENIED:
        return {
          icon: XCircle,
          label: 'Approval Denied',
          color: 'text-red-500',
          bgColor: 'bg-red-100 dark:bg-red-900',
        };
    }
  }

  if (isProjectEvent(event)) {
    return {
      icon: Folder,
      label: event.type.replace('project.', '').replace('_', ' '),
      color: 'text-teal-500',
      bgColor: 'bg-teal-100 dark:bg-teal-900',
    };
  }

  if (isWorkflowEvent(event)) {
    switch (event.type) {
      case EventType.WORKFLOW_STARTED:
        return {
          icon: Workflow,
          label: 'Workflow Started',
          color: 'text-cyan-500',
          bgColor: 'bg-cyan-100 dark:bg-cyan-900',
        };
      case EventType.WORKFLOW_STEP_COMPLETED:
        return {
          icon: Workflow,
          label: 'Step Completed',
          color: 'text-cyan-500',
          bgColor: 'bg-cyan-100 dark:bg-cyan-900',
        };
      case EventType.WORKFLOW_COMPLETED:
        return {
          icon: CheckCircle2,
          label: 'Workflow Completed',
          color: 'text-green-500',
          bgColor: 'bg-green-100 dark:bg-green-900',
        };
      case EventType.WORKFLOW_FAILED:
        return {
          icon: XCircle,
          label: 'Workflow Failed',
          color: 'text-red-500',
          bgColor: 'bg-red-100 dark:bg-red-900',
        };
    }
  }

  // Default fallback
  return {
    icon: FileText,
    label: event.type,
    color: 'text-gray-500',
    bgColor: 'bg-gray-100 dark:bg-gray-800',
  };
}

function getEventSummary(event: ProjectEvent): string {
  const payload = event.payload as Record<string, unknown>;

  switch (event.type) {
    case EventType.AGENT_SPAWNED:
      return `${payload.agent_name || 'Agent'} spawned as ${payload.role || 'unknown role'}`;
    case EventType.AGENT_MESSAGE:
      return String(payload.message || 'No message');
    case EventType.AGENT_STATUS_CHANGED:
      return `Status: ${payload.previous_status} -> ${payload.new_status}`;
    case EventType.AGENT_TERMINATED:
      return payload.termination_reason ? String(payload.termination_reason) : 'Agent terminated';
    case EventType.ISSUE_CREATED:
      return String(payload.title || 'New issue created');
    case EventType.ISSUE_UPDATED:
      return `Issue ${payload.issue_id || ''} updated`;
    case EventType.ISSUE_ASSIGNED:
      return payload.assignee_name
        ? `Assigned to ${payload.assignee_name}`
        : 'Issue assignment changed';
    case EventType.ISSUE_CLOSED:
      return payload.resolution ? `Closed: ${payload.resolution}` : 'Issue closed';
    case EventType.SPRINT_STARTED:
      return payload.sprint_name ? `Sprint "${payload.sprint_name}" started` : 'Sprint started';
    case EventType.SPRINT_COMPLETED:
      return payload.sprint_name ? `Sprint "${payload.sprint_name}" completed` : 'Sprint completed';
    case EventType.APPROVAL_REQUESTED:
      return String(payload.description || 'Approval requested');
    case EventType.APPROVAL_GRANTED:
      return 'Approval granted';
    case EventType.APPROVAL_DENIED:
      return payload.reason ? `Denied: ${payload.reason}` : 'Approval denied';
    case EventType.WORKFLOW_STARTED:
      return payload.workflow_type
        ? `${payload.workflow_type} workflow started`
        : 'Workflow started';
    case EventType.WORKFLOW_STEP_COMPLETED:
      return `Step ${payload.step_number}/${payload.total_steps}: ${payload.step_name || 'completed'}`;
    case EventType.WORKFLOW_COMPLETED:
      return payload.duration_seconds
        ? `Completed in ${payload.duration_seconds}s`
        : 'Workflow completed';
    case EventType.WORKFLOW_FAILED:
      return payload.error_message ? String(payload.error_message) : 'Workflow failed';
    default:
      return event.type;
  }
}

function formatActorDisplay(event: ProjectEvent): string {
  if (event.actor_type === 'system') return 'System';
  if (event.actor_type === 'agent') return 'Agent';
  if (event.actor_type === 'user') return 'User';
  return event.actor_type;
}

// ============================================================================
// EventItem Component
// ============================================================================

function EventItem({ event, showPayload = false, onClick }: EventItemProps) {
  const [isExpanded, setIsExpanded] = useState(false);
  const config = getEventConfig(event);
  const Icon = config.icon;
  const summary = getEventSummary(event);
  const actor = formatActorDisplay(event);

  const timestamp = formatDistanceToNow(new Date(event.timestamp), { addSuffix: true });

  const handleClick = () => {
    if (showPayload) {
      setIsExpanded(!isExpanded);
    }
    onClick?.(event);
  };

  return (
    <div
      className={cn(
        'flex gap-3 border-b border-border/50 p-3 last:border-b-0',
        (showPayload || onClick) && 'cursor-pointer hover:bg-muted/50 transition-colors'
      )}
      onClick={handleClick}
      role={onClick ? 'button' : undefined}
      tabIndex={onClick ? 0 : undefined}
      onKeyDown={
        onClick
          ? (e) => {
              if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                handleClick();
              }
            }
          : undefined
      }
    >
      {/* Icon */}
      <div
        className={cn(
          'flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full',
          config.bgColor
        )}
      >
        <Icon className={cn('h-4 w-4', config.color)} aria-hidden="true" />
      </div>

      {/* Content */}
      <div className="flex-1 min-w-0">
        <div className="flex items-start justify-between gap-2">
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2">
              <Badge variant="outline" className="text-xs">
                {config.label}
              </Badge>
              <span className="text-xs text-muted-foreground">{actor}</span>
            </div>
            <p className="mt-1 text-sm truncate">{summary}</p>
          </div>

          <div className="flex items-center gap-1 flex-shrink-0">
            <span className="text-xs text-muted-foreground whitespace-nowrap">{timestamp}</span>
            {showPayload && (
              <Button variant="ghost" size="sm" className="h-6 w-6 p-0">
                {isExpanded ? (
                  <ChevronDown className="h-4 w-4" />
                ) : (
                  <ChevronRight className="h-4 w-4" />
                )}
              </Button>
            )}
          </div>
        </div>

        {/* Expanded payload */}
        {showPayload && isExpanded && (
          <div className="mt-2 rounded-md bg-muted/50 p-2">
            <pre className="text-xs overflow-x-auto whitespace-pre-wrap break-words">
              {JSON.stringify(event.payload, null, 2)}
            </pre>
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================================
// EventList Component
// ============================================================================

/**
 * EventList - Display project activity feed
 *
 * Features:
 * - Event type icons and colors
 * - Event summaries
 * - Relative timestamps
 * - Actor display
 * - Expandable payload details
 * - Scrollable container
 * - Empty state handling
 *
 * @example
 * ```tsx
 * <EventList
 *   events={events}
 *   maxHeight={500}
 *   showPayloads
 *   onEventClick={(e) => console.log('Clicked:', e)}
 * />
 * ```
 */
export function EventList({
  events,
  maxHeight = 400,
  showHeader = true,
  title = 'Activity Feed',
  showPayloads = false,
  emptyMessage = 'No events yet',
  className,
  onEventClick,
}: EventListProps) {
  // Sort events by timestamp, newest first
  const sortedEvents = [...events].sort(
    (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
  );

  return (
    <Card className={className}>
      {showHeader && (
        <CardHeader className="pb-3">
          <CardTitle className="flex items-center justify-between text-base">
            <span>{title}</span>
            {events.length > 0 && (
              <Badge variant="secondary" className="text-xs">
                {events.length} event{events.length !== 1 ? 's' : ''}
              </Badge>
            )}
          </CardTitle>
        </CardHeader>
      )}
      <CardContent className={showHeader ? 'pt-0' : ''}>
        {sortedEvents.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-8 text-muted-foreground">
            <FileText className="h-8 w-8 mb-2" />
            <p className="text-sm">{emptyMessage}</p>
          </div>
        ) : (
          <div
            className="overflow-y-auto"
            style={{ maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight }}
          >
            <div className="divide-y divide-border/50">
              {sortedEvents.map((event) => (
                <EventItem
                  key={event.id}
                  event={event}
                  showPayload={showPayloads}
                  onClick={onEventClick}
                />
              ))}
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}
