import {Badge, Button, Collapsible, CollapsibleContent, CollapsibleTrigger} from '@plunk/ui';
import type {Activity} from '@plunk/types';
import {memo, useState} from 'react';
import {EmailPreviewModal} from './EmailPreviewModal';
import {
  AlertCircle,
  Calendar,
  CheckCheck,
  CheckCircle,
  ChevronRight,
  Eye,
  Inbox,
  MousePointerClick,
  Send,
  ShieldAlert,
  Workflow,
  XCircle,
  Zap,
} from 'lucide-react';
import Link from 'next/link';

/**
 * Simple relative time formatter for past events
 */
function getRelativeTime(date: Date): string {
  const now = new Date();
  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);

  if (diffInSeconds < 60) {
    return 'just now';
  }

  const diffInMinutes = Math.floor(diffInSeconds / 60);
  if (diffInMinutes < 60) {
    return `${diffInMinutes} ${diffInMinutes === 1 ? 'minute' : 'minutes'} ago`;
  }

  const diffInHours = Math.floor(diffInMinutes / 60);
  if (diffInHours < 24) {
    return `${diffInHours} ${diffInHours === 1 ? 'hour' : 'hours'} ago`;
  }

  const diffInDays = Math.floor(diffInHours / 24);
  if (diffInDays < 30) {
    return `${diffInDays} ${diffInDays === 1 ? 'day' : 'days'} ago`;
  }

  const diffInMonths = Math.floor(diffInDays / 30);
  if (diffInMonths < 12) {
    return `${diffInMonths} ${diffInMonths === 1 ? 'month' : 'months'} ago`;
  }

  const diffInYears = Math.floor(diffInMonths / 12);
  return `${diffInYears} ${diffInYears === 1 ? 'year' : 'years'} ago`;
}

/**
 * Format upcoming time (for future events)
 */
function getUpcomingTime(date: Date): string {
  const now = new Date();
  const diffInSeconds = Math.floor((date.getTime() - now.getTime()) / 1000);

  if (diffInSeconds < 60) {
    return 'in a moment';
  }

  const diffInMinutes = Math.floor(diffInSeconds / 60);
  if (diffInMinutes < 60) {
    return `in ${diffInMinutes} ${diffInMinutes === 1 ? 'minute' : 'minutes'}`;
  }

  const diffInHours = Math.floor(diffInMinutes / 60);
  if (diffInHours < 24) {
    return `in ${diffInHours} ${diffInHours === 1 ? 'hour' : 'hours'}`;
  }

  const diffInDays = Math.floor(diffInHours / 24);
  if (diffInDays === 1) {
    return `tomorrow at ${date.toLocaleTimeString('en-US', {hour: 'numeric', minute: '2-digit', hour12: true})}`;
  }

  if (diffInDays < 7) {
    return `in ${diffInDays} days`;
  }

  if (diffInDays < 30) {
    const weeks = Math.floor(diffInDays / 7);
    return `in ${weeks} ${weeks === 1 ? 'week' : 'weeks'}`;
  }

  const diffInMonths = Math.floor(diffInDays / 30);
  return `in ${diffInMonths} ${diffInMonths === 1 ? 'month' : 'months'}`;
}

/**
 * Check if an activity is an email activity
 */
function isEmailActivity(type: string): boolean {
  return [
    'email.sent',
    'email.delivered',
    'email.received',
    'email.opened',
    'email.clicked',
    'email.bounced',
    'email.complaint',
  ].includes(type);
}

interface ActivityItemProps {
  activity: Activity;
  status?: 'upcoming' | 'completed';
}

interface ActivityConfig {
  icon: React.ComponentType<{className?: string}>;
  color: string;
  bgColor: string;
  title: string;
  description?: string;
  badge?: {
    label: string;
    variant: 'default' | 'secondary' | 'destructive' | 'outline';
  };
  jsonData?: Record<string, unknown>;
}

function getActivityConfig(activity: Activity): ActivityConfig {
  const {type, metadata} = activity;

  switch (type) {
    case 'event.triggered':
      return {
        icon: Zap,
        color: 'text-amber-700',
        bgColor: 'bg-amber-50',
        title: (typeof metadata.eventName === 'string' ? metadata.eventName : undefined) || 'Event triggered',
        description: undefined,
        badge: {
          label: 'Event',
          variant: 'default',
        },
        jsonData:
          metadata.eventData && typeof metadata.eventData === 'object' && !Array.isArray(metadata.eventData)
            ? (metadata.eventData as Record<string, unknown>)
            : undefined,
      };

    case 'email.sent':
      return {
        icon: Send,
        color: 'text-neutral-700',
        bgColor: 'bg-neutral-100',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email sent',
        description: metadata.campaignName
          ? `Campaign: ${String(metadata.campaignName)}`
          : metadata.workflowName
            ? `Workflow: ${String(metadata.workflowName)}`
            : typeof metadata.sourceType === 'string'
              ? metadata.sourceType
              : undefined,
        badge: {
          label: 'Sent',
          variant: 'default',
        },
      };

    case 'email.delivered':
      return {
        icon: CheckCircle,
        color: 'text-emerald-700',
        bgColor: 'bg-emerald-50',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email delivered',
        description: metadata.campaignName
          ? `Campaign: ${String(metadata.campaignName)}`
          : metadata.workflowName
            ? `Workflow: ${String(metadata.workflowName)}`
            : undefined,
        badge: {
          label: 'Delivered',
          variant: 'default',
        },
      };

    case 'email.received':
      return {
        icon: Inbox,
        color: 'text-neutral-600',
        bgColor: 'bg-neutral-100',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email received',
        description: typeof metadata.from === 'string' ? `From: ${metadata.from}` : 'Inbound email',
        badge: {
          label: 'Received',
          variant: 'default',
        },
      };

    case 'email.opened':
      return {
        icon: Eye,
        color: 'text-emerald-700',
        bgColor: 'bg-emerald-50',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email opened',
        description:
          typeof metadata.totalOpens === 'number' && metadata.totalOpens > 1
            ? `Opened ${metadata.totalOpens} times`
            : metadata.campaignName
              ? `Campaign: ${String(metadata.campaignName)}`
              : metadata.workflowName
                ? `Workflow: ${String(metadata.workflowName)}`
                : undefined,
        badge: {
          label: 'Opened',
          variant: 'secondary',
        },
      };

    case 'email.clicked':
      return {
        icon: MousePointerClick,
        color: 'text-sky-700',
        bgColor: 'bg-sky-50',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email clicked',
        description:
          typeof metadata.totalClicks === 'number' && metadata.totalClicks > 1
            ? `Clicked ${metadata.totalClicks} times`
            : metadata.campaignName
              ? `Campaign: ${String(metadata.campaignName)}`
              : metadata.workflowName
                ? `Workflow: ${String(metadata.workflowName)}`
                : undefined,
        badge: {
          label: 'Clicked',
          variant: 'default',
        },
      };

    case 'email.bounced':
      return {
        icon: XCircle,
        color: 'text-red-700',
        bgColor: 'bg-red-50',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email bounced',
        description: (typeof metadata.error === 'string' ? metadata.error : undefined) || 'Email failed to deliver',
        badge: {
          label: 'Bounced',
          variant: 'destructive',
        },
      };

    case 'email.complaint':
      return {
        icon: ShieldAlert,
        color: 'text-red-700',
        bgColor: 'bg-red-50',
        title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Spam complaint',
        description: metadata.campaignName
          ? `Campaign: ${String(metadata.campaignName)}`
          : metadata.workflowName
            ? `Workflow: ${String(metadata.workflowName)}`
            : 'Recipient marked as spam',
        badge: {
          label: 'Complaint',
          variant: 'destructive',
        },
      };

    case 'workflow.started':
      return {
        icon: Workflow,
        color: 'text-amber-700',
        bgColor: 'bg-amber-50',
        title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow started',
        description: `Status: ${String(metadata.status || 'unknown')}`,
        badge: {
          label: 'Workflow',
          variant: 'default',
        },
      };

    case 'workflow.completed':
      return {
        icon: CheckCheck,
        color: 'text-amber-700',
        bgColor: 'bg-amber-50',
        title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow completed',
        description: metadata.exitReason
          ? `Exit: ${String(metadata.exitReason)}`
          : `Status: ${String(metadata.status || 'unknown')}`,
        badge: {
          label: 'Completed',
          variant: 'default',
        },
      };

    case 'campaign.scheduled':
      return {
        icon: Calendar,
        color: 'text-sky-700',
        bgColor: 'bg-sky-50',
        title: (typeof metadata.campaignName === 'string' ? metadata.campaignName : undefined) || 'Campaign scheduled',
        description: metadata.subject
          ? `${String(metadata.subject)}${metadata.totalRecipients ? ` • ${metadata.totalRecipients} recipients` : ''}`
          : metadata.totalRecipients
            ? `${metadata.totalRecipients} recipients`
            : undefined,
        badge: {
          label: 'Scheduled',
          variant: 'outline',
        },
      };

    case 'workflow.email.scheduled':
      return {
        icon: Calendar,
        color: 'text-amber-700',
        bgColor: 'bg-amber-50',
        title: (typeof metadata.stepName === 'string' ? metadata.stepName : undefined) || 'Workflow email scheduled',
        description: metadata.workflowName
          ? `Workflow: ${String(metadata.workflowName)}${metadata.subject ? ` • ${String(metadata.subject)}` : ''}`
          : typeof metadata.subject === 'string'
            ? metadata.subject
            : undefined,
        badge: {
          label: 'Scheduled',
          variant: 'outline',
        },
      };

    default:
      return {
        icon: AlertCircle,
        color: 'text-neutral-600',
        bgColor: 'bg-neutral-100',
        title: 'Unknown activity',
        badge: {
          label: 'Unknown',
          variant: 'outline',
        },
      };
  }
}

export const ActivityItem = memo(function ActivityItem({activity, status = 'completed'}: ActivityItemProps) {
  const [showPreviewModal, setShowPreviewModal] = useState(false);
  const config = getActivityConfig(activity);
  const Icon = config.icon;
  const timestamp = new Date(activity.timestamp);
  const isUpcoming = status === 'upcoming';
  const relativeTime = isUpcoming ? getUpcomingTime(timestamp) : getRelativeTime(timestamp);

  return (
    <div className={`flex items-start gap-4 ${isUpcoming ? 'opacity-80' : ''}`}>
      {/* Icon */}
      <div
        className={`h-10 w-10 rounded-lg ${config.bgColor} flex items-center justify-center flex-shrink-0 ${isUpcoming ? 'border-2 border-dashed border-neutral-300' : ''}`}
      >
        <Icon className={`h-5 w-5 ${config.color}`} />
      </div>

      {/* Content */}
      <div className="flex-1 min-w-0">
        <div className="flex items-start justify-between gap-2 flex-wrap">
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2 mb-1">
              <p className={`text-sm font-medium truncate ${isUpcoming ? 'text-neutral-700' : 'text-neutral-900'}`}>
                {config.title}
              </p>
              {config.badge && <Badge variant={config.badge.variant}>{config.badge.label}</Badge>}
              {isEmailActivity(activity.type) && activity.metadata.subject && activity.metadata.body ? (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => setShowPreviewModal(true)}
                  className="h-6 px-2 text-xs"
                >
                  <Eye className="h-3 w-3 mr-1" />
                  Preview
                </Button>
              ) : null}
            </div>
            {config.description && <p className="text-sm text-neutral-500 line-clamp-2">{config.description}</p>}
            {activity.contactEmail && (
              <div className="flex items-center gap-2 mt-2">
                {activity.contactId ? (
                  <Link
                    href={`/contacts/${activity.contactId}`}
                    className="text-xs text-neutral-600 hover:text-neutral-900 hover:underline"
                  >
                    {activity.contactEmail}
                  </Link>
                ) : (
                  <span className="text-xs text-neutral-600">{activity.contactEmail}</span>
                )}
              </div>
            )}
            {/* Collapsible JSON Data */}
            {config.jsonData && (
              <Collapsible className="mt-2">
                <CollapsibleTrigger className="flex items-center gap-1 text-xs text-neutral-600 hover:text-neutral-900 transition-colors group">
                  <ChevronRight className="h-3 w-3 transition-transform group-data-[state=open]:rotate-90" />
                  <span className="font-medium">Event Data</span>
                </CollapsibleTrigger>
                <CollapsibleContent>
                  <pre className="mt-2 p-3 bg-neutral-50 rounded-md border border-neutral-200 text-xs overflow-x-auto">
                    <code className="text-neutral-700">{JSON.stringify(config.jsonData, null, 2)}</code>
                  </pre>
                </CollapsibleContent>
              </Collapsible>
            )}
          </div>
          <span
            className={`text-xs flex-shrink-0 whitespace-nowrap ${isUpcoming ? 'text-neutral-700 font-medium' : 'text-neutral-400'}`}
            title={timestamp.toLocaleString()}
          >
            {relativeTime}
          </span>
        </div>
      </div>

      {/* Email Preview Modal */}
      {showPreviewModal && activity.metadata.subject && activity.metadata.body ? (
        <EmailPreviewModal
          open={showPreviewModal}
          onOpenChange={setShowPreviewModal}
          subject={String(activity.metadata.subject)}
          body={String(activity.metadata.body)}
          from={activity.metadata.from ? String(activity.metadata.from) : undefined}
          fromName={activity.metadata.fromName ? String(activity.metadata.fromName) : undefined}
          replyTo={activity.metadata.replyTo ? String(activity.metadata.replyTo) : undefined}
          toName={activity.metadata.toName ? String(activity.metadata.toName) : undefined}
          toEmail={activity.contactEmail}
        />
      ) : null}
    </div>
  );
});
