import React, {ReactNode, useCallback, useMemo} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  IconCircleArrowRight,
  IconFileCheck,
  IconFileX,
  IconFlag,
  IconRefresh,
  IconSquareRotated,
  IconUser,
  IconUserEdit,
  IconWallpaper,
  IconX,
} from '@tabler/icons-react-native';
import {Divider, List, ListSkeleton, Typography} from '@components';
import i18next from '@config/i18n';
import {useCursorInfinityQuery} from '@hooks/queries-v5/useCursorInfinityQuery';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {ServiceManagementErrorMessage} from '@modules/serviceManagement/components/ServiceManagementErrorMessage';
import {getTaskActivity} from '@modules/serviceManagement/services';
import {
  SUBTASK_PREFIX,
  TASK_PREFIX,
  serviceManagementQueryKeys,
} from '@modules/serviceManagement/constants';
import {
  ApprovalGroupStatus,
  ServiceManagementActivity,
  ServiceManagementActivityType,
  ServiceManagementTask,
  ServiceManagementTaskType,
  TaskEventView,
} from '@modules/serviceManagement/interfaces';
import {
  getServiceManagementDisplayName,
  getTaskId,
  getTranslatedStateName,
} from '@modules/serviceManagement/utils';
import {useUserId} from '@redux/selectors';
import {REDUCED_LIMIT} from '@services/constants';
import {getCompactDateTime} from '@shared/utils';
import {NewThemeColors, useTheme} from '@shared/theme';

import ServiceManagementTaskTabFooter from '../ServiceManagementTaskTabFooter';
import {styles} from './styles';
import AvatarWithStatus from '../AvatarWithStatus';

type ActivityContent = {
  title: ReactNode;
  subtitle?: ReactNode;
} & (
  | {
      icon?: ReactNode;
      iconBackgroundColor?: string;
      avatar?: never;
    }
  | {
      icon?: never;
      iconBackgroundColor?: never;
      avatar?: ReactNode;
    }
);

const getActivityContent = (
  activity: ServiceManagementActivity,
  theme: NewThemeColors,
  userId: number,
): ActivityContent | undefined => {
  const taskType = activity.taskType || activity.task.type;
  const isIncident = taskType === ServiceManagementTaskType.Incident;
  const isSubtask = taskType === ServiceManagementTaskType.Subtask;
  const taskPrefix = isSubtask ? SUBTASK_PREFIX : TASK_PREFIX;
  const taskLabel =
    activity.task.label || `${taskPrefix}${activity.task.taskNumber}`;
  const taskName = activity.task.name || '';

  const getEventType = (): ServiceManagementActivityType | null => {
    if (
      activity.type === ServiceManagementActivityType.TaskUpdated &&
      activity.metadata?.eventType === 'TASK_STATE_CHANGED'
    ) {
      return ServiceManagementActivityType.TaskStateChanged;
    }
    if (Object.values(ServiceManagementActivityType).includes(activity.type)) {
      return activity.type;
    }
    return null;
  };

  const eventType = getEventType();
  if (!eventType) {
    return undefined;
  }

  const getSubtaskIcon = (
    IconComponent: React.ComponentType<{color: string}>,
  ) => <IconComponent color={theme.text.neutral.brand} />;

  const activityMap: Record<
    ServiceManagementActivityType,
    ActivityContent | undefined
  > = {
    [ServiceManagementActivityType.TaskStarted]: isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.subtasks.activity.started_title', {
                taskName,
              })}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: getSubtaskIcon(IconWallpaper),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.request_started')}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: <IconFlag color={theme.text.feedback.success} />,
          iconBackgroundColor: theme.background.feedback.success,
        },
    [ServiceManagementActivityType.TaskUpdated]: isIncident
      ? {
          title: (
            <Typography>
              {i18next.t('service_management.request_state_updated_to')}{' '}
              <Typography weight="semiBold">
                {getTranslatedStateName(activity.taskState?.name)}
              </Typography>
            </Typography>
          ),
          subtitle: taskLabel,
          icon: <IconCircleArrowRight color={theme.text.feedback.info} />,
          iconBackgroundColor: theme.background.feedback.info,
        }
      : isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.subtasks.activity.updated_title', {
                taskName,
                stateName: getTranslatedStateName(activity.taskState?.name),
              })}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: getSubtaskIcon(IconCircleArrowRight),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : undefined,
    [ServiceManagementActivityType.TaskStateChanged]: isIncident
      ? {
          title: (
            <Typography>
              {i18next.t('service_management.request_state_updated_to')}{' '}
              <Typography weight="semiBold">
                {getTranslatedStateName(activity.taskState?.name)}
              </Typography>
            </Typography>
          ),
          subtitle: taskLabel,
          icon: <IconCircleArrowRight color={theme.text.feedback.info} />,
          iconBackgroundColor: theme.background.feedback.info,
        }
      : isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.subtasks.activity.updated_title', {
                taskName,
                stateName: getTranslatedStateName(activity.taskState?.name),
              })}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: getSubtaskIcon(IconCircleArrowRight),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : undefined,
    [ServiceManagementActivityType.TaskAssigned]: isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.subtasks.activity.assigned_title')}
            </Typography>
          ),
          subtitle: i18next.t(
            'service_management.subtasks.activity.assigned_description',
            {
              taskId: taskLabel,
              assignee: getServiceManagementDisplayName({
                user: activity.assignee,
                userId,
                t: i18next.t,
              }),
            },
          ),
          icon: getSubtaskIcon(IconUser),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.agent_assigned_event_title')}
            </Typography>
          ),
          subtitle: `${taskLabel} ${i18next.t(
            'service_management.assigned_to_agent',
            {
              agentName: getServiceManagementDisplayName({
                user: activity.assignee,
                userId,
                t: i18next.t,
              }),
            },
          )}`,
          icon: <IconUser color={theme.text.feedback.highlight} />,
          iconBackgroundColor: theme.background.feedback.highlight,
        },
    [ServiceManagementActivityType.TaskReassigned]: isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t(
                'service_management.subtasks.activity.reassigned_title',
              )}
            </Typography>
          ),
          subtitle: i18next.t(
            'service_management.subtasks.activity.reassigned_description',
            {
              user: getServiceManagementDisplayName({
                user: activity.user,
                userId,
                t: i18next.t,
              }),
              assignee: getServiceManagementDisplayName({
                user: activity.assignee,
                userId,
                t: i18next.t,
              }),
            },
          ),
          icon: getSubtaskIcon(IconUserEdit),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : {
          title: (
            <Typography weight="semiBold">
              {i18next.t('service_management.agent_reassigned_event_title')}
            </Typography>
          ),
          subtitle: i18next.t('service_management.user_reassigned_request', {
            userName: getServiceManagementDisplayName({
              user: activity.user,
              userId,
              t: i18next.t,
            }),
            agentName: getServiceManagementDisplayName({
              user: activity.assignee,
              userId,
              t: i18next.t,
            }),
          }),
          icon: <IconRefresh color={theme.text.feedback.highlight} />,
          iconBackgroundColor: theme.background.feedback.highlight,
        },
    [ServiceManagementActivityType.TaskClosedManually]: isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t(
                'service_management.subtasks.activity.closed_manually',
                {
                  taskName,
                },
              )}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: getSubtaskIcon(IconWallpaper),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : undefined,
    [ServiceManagementActivityType.TaskClosedAutomatically]: isSubtask
      ? {
          title: (
            <Typography weight="semiBold">
              {i18next.t(
                'service_management.subtasks.activity.closed_automatically',
                {
                  taskName,
                },
              )}
            </Typography>
          ),
          subtitle: taskLabel,
          icon: getSubtaskIcon(IconWallpaper),
          iconBackgroundColor: theme.background.layout.brand,
        }
      : undefined,
    [ServiceManagementActivityType.ApprovalGroupCreated]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_group_created',
            {name: activity.metadata?.approvalName},
          )}
        </Typography>
      ),
      subtitle: i18next.t(
        'service_management.approvals.activity.approvals_needed',
        {
          count: activity.metadata?.approvalsNeeded,
          total: activity.metadata?.taskCount,
        },
      ),
      icon: <IconFileCheck color={theme.text.feedback.highlight} />,
      iconBackgroundColor: theme.background.feedback.highlight,
    },
    [ServiceManagementActivityType.ApprovalGroupApproved]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_group_approved',
            {name: activity.metadata?.approvalName},
          )}
        </Typography>
      ),
      icon: <IconFileCheck color={theme.text.feedback.success} />,
      iconBackgroundColor: theme.background.feedback.success,
    },
    [ServiceManagementActivityType.ApprovalGroupRejected]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_group_rejected',
            {name: activity.metadata?.approvalName},
          )}
        </Typography>
      ),
      icon: <IconFileX color={theme.text.feedback.error} />,
      iconBackgroundColor: theme.background.feedback.error,
    },
    [ServiceManagementActivityType.ApprovalGroupCancelled]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_group_cancelled',
            {name: activity.metadata?.approvalName},
          )}
        </Typography>
      ),
      icon: <IconX color={theme.text.neutral.lighter} />,
      iconBackgroundColor: theme.background.layout.default,
    },
    [ServiceManagementActivityType.ApprovalTaskApproved]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_task_approved',
            {
              name: getServiceManagementDisplayName({
                user: activity.user,
                userId,
                t: i18next.t,
              }),
            },
          )}
        </Typography>
      ),
      subtitle: activity.metadata?.message,
      avatar: (
        <AvatarWithStatus
          status={ApprovalGroupStatus.Approved}
          name={getServiceManagementDisplayName({
            user: activity.user,
            userId,
            t: i18next.t,
          })}
          url={activity.user?.profilePicture}
        />
      ),
    },
    [ServiceManagementActivityType.ApprovalTaskRejected]: {
      title: (
        <Typography weight="semiBold">
          {i18next.t(
            'service_management.approvals.activity.approval_task_rejected',
            {
              name: getServiceManagementDisplayName({
                user: activity.user,
                userId,
                t: i18next.t,
              }),
            },
          )}
        </Typography>
      ),
      subtitle: activity.metadata?.message,
      avatar: (
        <AvatarWithStatus
          status={ApprovalGroupStatus.Rejected}
          name={getServiceManagementDisplayName({
            user: activity.user,
            userId,
            t: i18next.t,
          })}
          url={activity.user?.profilePicture}
        />
      ),
    },
    [ServiceManagementActivityType.ApprovalTaskCancelled]: undefined,
  };

  const content = activityMap[eventType];
  if (!content) {
    return undefined;
  }
  return content;
};

export default function ServiceManagementTaskActivityList({
  task,
  footer,
  backgroundColor,
  isAgent = false,
}: {
  task: ServiceManagementTask;
  footer?: ReactNode;
  backgroundColor?: string;
  isAgent?: boolean;
}) {
  const {t} = useTranslation();
  const {theme, spacing} = useTheme();
  const paddingBottom = useSafeAreaBottomPadding();
  const taskId = getTaskId(task);
  const userId = useUserId();
  const {
    data,
    isLoading,
    isError,
    isRefreshing,
    isFetchingNextPage,
    hasNextPage,
    getNextPage,
    refresh,
  } = useCursorInfinityQuery({
    queryKey: serviceManagementQueryKeys.taskActivity(taskId, isAgent),
    queryFn: params =>
      getTaskActivity({
        taskId,
        views: isAgent
          ? TaskEventView.AllDetailedEvents
          : TaskEventView.AllSimplifiedEvents,
        limit: REDUCED_LIMIT,
        ...params,
      }),
  });

  const activities = useMemo(
    () =>
      data.filter(activity => !!getActivityContent(activity, theme, userId)),
    [data, theme, userId],
  );

  const renderItem = useCallback(
    ({item, index}: {item: ServiceManagementActivity; index: number}) => {
      const content = getActivityContent(item, theme, userId);
      if (!content) return null;

      return (
        <View style={styles.itemContainer}>
          <View>
            {index === 0 ? (
              <View style={styles.activityLine} />
            ) : (
              <Divider style={styles.activityLine} direction="vertical" />
            )}
            {content.icon ? (
              <View
                style={[
                  styles.iconContainer,
                  {backgroundColor: content.iconBackgroundColor},
                ]}>
                {content.icon}
              </View>
            ) : (
              content.avatar
            )}
            <Divider style={styles.activityLine} direction="vertical" />
          </View>
          <View style={styles.info}>
            <Typography variant="xxs" color={theme.text.neutral.lighter}>
              {getCompactDateTime(item.timestamp)}
            </Typography>
            {content.title}
            <Typography
              variant="xs"
              color={theme.text.neutral.lighter}
              numberOfLines={1}>
              {content.subtitle}
            </Typography>
          </View>
        </View>
      );
    },
    [theme, userId],
  );

  return (
    <>
      <List
        data={activities}
        renderItem={renderItem}
        isLoading={isLoading}
        isError={isError}
        isRefreshing={isRefreshing}
        isFetchingNextPage={isFetchingNextPage}
        hasNextPage={hasNextPage}
        onNextPage={getNextPage}
        onRefresh={refresh}
        backgroundColor={backgroundColor}
        style={[styles.contentContainer, {paddingBottom}]}
        ListFooterComponent={
          activities.length > 0 ? (
            <View style={styles.initialIcon}>
              <IconSquareRotated
                strokeWidth={1}
                size={spacing['x2.5']}
                color={theme.border.neutral.default}
              />
            </View>
          ) : undefined
        }
        ListEmptyComponent={
          isLoading ? (
            <ListSkeleton
              withDivider={false}
              itemLength={4}
              presentation="flat"
            />
          ) : (
            <ServiceManagementErrorMessage
              title={t('service_management.empty_activity_title')}
              body={t('service_management.empty_activity_body')}
            />
          )
        }
        errorText={t('service_management.tasks_error_title')}
        emptyText={t('service_management.tasks_error_body')}
        paginationType="infiniteScroll"
      />
      {footer && (
        <ServiceManagementTaskTabFooter>
          {footer}
        </ServiceManagementTaskTabFooter>
      )}
    </>
  );
}
