'use client';


import React, { useState, useMemo, useCallback } from 'react';
import {
  Activity,
  ActivityType,
  ScheduleActivity,
  NotificationActivity
} from '@alga-psa/types';
import { useActivityDrawer } from './ActivityDrawerProvider';
import { DataTable } from '@alga-psa/ui/components/DataTable';
import { ColumnDefinition } from '@alga-psa/types';
import { formatDistanceToNow } from 'date-fns';
import { ActivityActionMenu } from './ActivityActionMenu';
import { InlinePriorityPicker } from './InlinePriorityPicker';
import { InlineStatusPicker } from './InlineStatusPicker';
import { Tooltip } from '@alga-psa/ui/components/Tooltip';
import { useTranslation } from '@alga-psa/ui/lib/i18n/client';
import { Calendar, Layers, MessageSquare, Clock, ListChecks, Repeat, Bell } from 'lucide-react';
import { getActivityTypeColor } from './constants';

interface ActivitiesDataTableProps {
  activities: Activity[];
  onViewDetails: (activity: Activity) => void;
  onActionComplete?: () => void;
  isLoading?: boolean;
  currentPage?: number;
  pageSize?: number;
  totalItems?: number;
  onPageChange?: (page: number) => void;
  onItemsPerPageChange?: (pageSize: number) => void;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
  onSortChange?: (sortBy: string, sortDirection: 'asc' | 'desc') => void;
}

// Format date to a readable format
const formatDate = (dateString?: string) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleDateString('en-US', { 
    month: 'short', 
    day: 'numeric', 
    year: 'numeric' 
  });
};

// Get relative time (e.g., "2 days ago")
const getRelativeTime = (dateString?: string) => {
  if (!dateString) return '';
  return formatDistanceToNow(new Date(dateString), { addSuffix: true });
};

// Get activity type icon
const getActivityTypeIcon = (type: ActivityType) => {
  switch (type) {
    case ActivityType.SCHEDULE:
      return <Calendar className="h-4 w-4 text-success" />;
    case ActivityType.PROJECT_TASK:
      return <Layers className="h-4 w-4" style={{ color: 'rgb(var(--color-secondary-500))' }} />;
    case ActivityType.TICKET:
      return <MessageSquare className="h-4 w-4 text-primary-500" />;
    case ActivityType.TIME_ENTRY:
      return <Clock className="h-4 w-4 text-orange-500" />;
    case ActivityType.WORKFLOW_TASK:
      return <ListChecks className="h-4 w-4 text-destructive" />;
    case ActivityType.NOTIFICATION:
      return <Bell className="h-4 w-4 text-indigo-500" />;
    default:
      return null;
  }
};

// Get priority icon - only renders when a real priority color from DB is available
const getPriorityIcon = (priorityColor?: string, priorityName?: string) => {
  if (!priorityColor) return null;

  const dot = <div className="w-3 h-3 rounded-full flex-shrink-0" style={{ backgroundColor: priorityColor }} />;

  if (priorityName) {
    return <Tooltip content={priorityName}>{dot}</Tooltip>;
  }
  return dot;
};

type TFn = (key: string, options?: Record<string, unknown>) => string;

// Get activity type label
const getActivityTypeLabel = (type: ActivityType, t: TFn) => {
  switch (type) {
    case ActivityType.SCHEDULE:
      return t('table.activityTypes.schedule', { defaultValue: 'Schedule' });
    case ActivityType.PROJECT_TASK:
      return t('table.activityTypes.projectTask', { defaultValue: 'Project Task' });
    case ActivityType.TICKET:
      return t('table.activityTypes.ticket', { defaultValue: 'Ticket' });
    case ActivityType.TIME_ENTRY:
      return t('table.activityTypes.timeEntry', { defaultValue: 'Time Entry' });
    case ActivityType.WORKFLOW_TASK:
      return t('table.activityTypes.workflowTask', { defaultValue: 'Workflow Task' });
    case ActivityType.NOTIFICATION:
      return t('table.activityTypes.notification', { defaultValue: 'Notification' });
    default:
      return t('table.activityTypes.unknown', { defaultValue: 'Unknown' });
  }
};

// Wrap the entire component in React.memo for top-level memoization
export const ActivitiesDataTable = React.memo(function ActivitiesDataTable({
  activities,
  onViewDetails,
  onActionComplete,
  isLoading = false,
  currentPage = 1,
  pageSize = 10,
  totalItems,
  onPageChange,
  onItemsPerPageChange,
  sortBy,
  sortDirection,
  onSortChange
}: ActivitiesDataTableProps) {
  const { t } = useTranslation('msp/user-activities');
  const { openActivityDrawer } = useActivityDrawer();

  // Define columns for the DataTable - memoized to prevent unnecessary re-renders.
  // Widths are percentages, but DataTable sizes them against a ~1800px base, so the
  // total is kept modest to avoid columns being falsely hidden as "limited space".
  const columns = useMemo<ColumnDefinition<Activity>[]>(() => [
    {
      title: t('table.columns.type', { defaultValue: 'Type' }),
      dataIndex: 'type',
      width: '6%',
      cellClassName: 'relative',
      render: (value, record) => (
        <div className="flex items-center gap-2">
          {/* Left-edge color accent for the activity type — flush to the row's left
              border, full height. Positioned inline because this file's Tailwind classes
              aren't all in the scanned content globs. */}
          <div
            className="absolute"
            style={{ top: 0, bottom: 0, left: 0, width: 4, backgroundColor: getActivityTypeColor(value as ActivityType) }}
            aria-hidden="true"
          />
          {getActivityTypeIcon(value as ActivityType)}
          <span className="text-xs">{getActivityTypeLabel(value as ActivityType, t)}</span>
        </div>
      ),
    },
    {
      title: t('table.columns.title', { defaultValue: 'Title' }),
      dataIndex: 'title',
      width: '27%',
      render: (value, record) => (
        <div className="flex items-center gap-2">
          {record.type === ActivityType.SCHEDULE && (record as ScheduleActivity).workItemType === 'ad_hoc' && (
            <span className="px-1.5 py-0.5 text-xs font-medium bg-gray-500/15 text-gray-600 dark:text-gray-400 rounded flex-shrink-0">
              {t('table.values.adHocBadge', { defaultValue: 'Ad hoc' })}
            </span>
          )}
          <span className="font-medium text-gray-900 break-words">{value as string}</span>
          {record.type === ActivityType.SCHEDULE && (record as ScheduleActivity).isRecurring && (
             <span title={t('table.values.recurringEvent', { defaultValue: 'Recurring Event' })}>
               <Repeat className="h-4 w-4 text-gray-500 flex-shrink-0" />
             </span>
          )}
          {record.type === ActivityType.NOTIFICATION && !(record as NotificationActivity).isRead && (
            <div className="w-2 h-2 rounded-full bg-primary-500 flex-shrink-0" title={t('table.values.unread', { defaultValue: 'Unread' })} />
          )}
        </div>
      ),
    },
    {
      title: t('table.columns.status', { defaultValue: 'Status' }),
      dataIndex: 'status',
      width: '8%',
      render: (_value, record) => (
        <InlineStatusPicker
          activity={record}
          onStatusChange={onActionComplete}
        />
      ),
    },
    {
      title: t('table.columns.priority', { defaultValue: 'Priority' }),
      dataIndex: 'priority',
      width: '7%',
      render: (value, record) => {
        // Inline priority picker for tickets and project tasks
        if (record.type === ActivityType.TICKET || record.type === ActivityType.PROJECT_TASK) {
          return (
            <InlinePriorityPicker
              activity={record}
              onPriorityChange={onActionComplete}
            />
          );
        }
        // Read-only display for other types
        if (!record.priorityColor) {
          return <span className="text-muted-foreground">—</span>;
        }
        return (
          <div className="flex items-center gap-2">
            {getPriorityIcon(record.priorityColor, record.priorityName)}
            <span>{record.priorityName || (value as string)}</span>
          </div>
        );
      },
    },
    {
      title: t('table.columns.dueDate', { defaultValue: 'Due Date' }),
      dataIndex: 'dueDate',
      width: '6%',
      render: (value, record) => (
        <div>
          {value ? (
            <div className="flex flex-col">
              <span>{formatDate(value as string)}</span>
              <span className="text-xs text-gray-500">{getRelativeTime(value as string)}</span>
            </div>
          ) : (
            <span className="text-gray-400">{t('table.values.noDueDate', { defaultValue: 'No due date' })}</span>
          )}
        </div>
      ),
    },
    {
      title: t('table.columns.actions', { defaultValue: 'Actions' }),
      dataIndex: 'actions',
      width: '3%',
      sortable: false,
      render: (_, record) => (
        <ActivityActionMenu
          activity={record}
          onActionComplete={onActionComplete}
          onViewDetails={onViewDetails}
        />
      ),
    },
  ], [onActionComplete, onViewDetails, t]);  // Add dependencies that are used in the columns

  // Handle row click to view details - memoized to prevent unnecessary re-renders
  const handleRowClick = useCallback((record: Activity) => {
    openActivityDrawer(record);
  }, [openActivityDrawer]);

  // Memoize the entire DataTable component to prevent unnecessary re-renders
  const MemoizedDataTable = useMemo(() => (
    <DataTable
      key={`${currentPage}-${pageSize}`}
      id="user-activities-table"
      data={activities}
      columns={columns}
      pagination={true}
      onRowClick={handleRowClick}
      currentPage={currentPage}
      onPageChange={onPageChange}
      pageSize={pageSize}
      totalItems={totalItems}
      onItemsPerPageChange={onItemsPerPageChange}
      manualSorting
      sortBy={sortBy}
      sortDirection={sortDirection}
      onSortChange={onSortChange}
    />
  ), [
    activities,
    columns,
    handleRowClick,
    currentPage,
    onPageChange,
    pageSize,
    totalItems,
    onItemsPerPageChange,
    sortBy,
    sortDirection,
    onSortChange
  ]);
  
  return MemoizedDataTable;
}, (prevProps, nextProps) => {
  // Custom comparison function for React.memo
  // Return true if the component should NOT re-render
  
  // Check if activities array has changed (length or content)
  if (prevProps.activities.length !== nextProps.activities.length) {
    return false; // Re-render if length changed
  }
  
  // Check if pagination props changed
  if (
    prevProps.currentPage !== nextProps.currentPage ||
    prevProps.pageSize !== nextProps.pageSize ||
    prevProps.totalItems !== nextProps.totalItems
  ) {
    return false; // Re-render if pagination changed
  }
  
  // Check if loading state changed
  if (prevProps.isLoading !== nextProps.isLoading) {
    return false; // Re-render if loading state changed
  }

  // Check if sort props changed
  if (
    prevProps.sortBy !== nextProps.sortBy ||
    prevProps.sortDirection !== nextProps.sortDirection
  ) {
    return false;
  }


  // For activities, we need a deeper comparison
  // This is a simplified approach - for large datasets, consider using a more efficient comparison
  const prevIds = prevProps.activities.map(a => a.id).join(',');
  const nextIds = nextProps.activities.map(a => a.id).join(',');
  if (prevIds !== nextIds) {
    return false; // Re-render if activities changed
  }
  
  // If we got here, don't re-render
  return true;
});
