import React, { useMemo } from 'react';
import styled from 'styled-components';
import { HiSwitchHorizontal, HiUserAdd, HiUserCircle, HiUserRemove } from 'react-icons/hi';
import { useLocale } from '@/app/providers/LocaleProvider';
import { Card } from '@/shared/components/ui';
import type { TicketCollaboratorActivityEntry } from '@/features/tickets/types/collaborator.types';
import type { TicketAssignmentEntry, TicketStatusHistoryEntry } from '@/features/tickets/types/ticket.types';
import { formatDateTime, localizedName } from '@/features/tickets/utils/ticketDisplay';

const Timeline = styled.ul`
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;

  &::before {
    content: '';
    position: absolute;
    inset-inline-start: 15px;
    top: 8px;
    bottom: 8px;
    width: 2px;
    background-color: ${({ theme }) => theme.colors.divider};
  }
`;

const Item = styled.li`
  position: relative;
  padding-inline-start: ${({ theme }) => theme.spacing[10]};
  padding-bottom: ${({ theme }) => theme.spacing[4]};

  &:last-child {
    padding-bottom: 0;
  }
`;

const Dot = styled.span<{ $accent?: boolean }>`
  position: absolute;
  inset-inline-start: 8px;
  top: 4px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background-color: ${({ theme, $accent }) =>
    $accent ? theme.colors.primary : theme.colors.borderStrong};
  border: 2px solid
    ${({ theme, $accent }) => ($accent ? theme.colors.primary : theme.colors.borderStrong)};
  z-index: 1;
`;

const EventTitle = styled.div`
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
  color: ${({ theme }) => theme.colors.text.primary};
  text-align: start;
  line-height: ${({ theme }) => theme.typography.lineHeight.normal};
`;

const EventMeta = styled.div`
  margin-top: ${({ theme }) => theme.spacing[1]};
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
  color: ${({ theme }) => theme.colors.text.tertiary};
  text-align: start;
`;

const DateGroup = styled.div`
  margin-bottom: ${({ theme }) => theme.spacing[4]};

  &:last-child {
    margin-bottom: 0;
  }
`;

const DateLabel = styled.div`
  font-size: 0.6875rem;
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  letter-spacing: ${({ theme }) => theme.typography.letterSpacing.widest};
  text-transform: uppercase;
  color: ${({ theme }) => theme.colors.text.tertiary};
  margin-bottom: ${({ theme }) => theme.spacing[3]};
  text-align: start;
`;

const EmptyMessage = styled.p`
  margin: 0;
  color: ${({ theme }) => theme.colors.text.secondary};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  text-align: start;
`;

type TimelineEntry =
  | { kind: 'status'; entry: TicketStatusHistoryEntry }
  | { kind: 'collaborator'; entry: TicketCollaboratorActivityEntry }
  | { kind: 'assignment'; entry: TicketAssignmentEntry };

function dateGroupKey(iso: string | null | undefined, locale: string): string {
  if (!iso) {
    return 'unknown';
  }

  try {
    return new Intl.DateTimeFormat(locale === 'ar' ? 'ar' : 'en', {
      dateStyle: 'medium',
    }).format(new Date(iso));
  } catch {
    return iso.slice(0, 10);
  }
}

interface TicketActivityTimelineProps {
  statusHistory: TicketStatusHistoryEntry[];
  collaboratorActivity?: TicketCollaboratorActivityEntry[];
  assignments?: TicketAssignmentEntry[];
}

export const TicketActivityTimeline: React.FC<TicketActivityTimelineProps> = ({
  statusHistory,
  collaboratorActivity = [],
  assignments = [],
}) => {
  const { t, locale } = useLocale();

  const entries = useMemo((): TimelineEntry[] => {
    const statusEntries = statusHistory.map(
      (entry): TimelineEntry => ({ kind: 'status', entry }),
    );
    const collaboratorEntries = collaboratorActivity.map(
      (entry): TimelineEntry => ({ kind: 'collaborator', entry }),
    );
    const assignmentEntries = assignments.map(
      (entry): TimelineEntry => ({ kind: 'assignment', entry }),
    );

    return [...statusEntries, ...collaboratorEntries, ...assignmentEntries].sort((a, b) => {
      const aTime =
        a.kind === 'status'
          ? a.entry.created_at
          : a.kind === 'collaborator'
            ? a.entry.created_at ?? ''
            : a.entry.created_at;
      const bTime =
        b.kind === 'status'
          ? b.entry.created_at
          : b.kind === 'collaborator'
            ? b.entry.created_at ?? ''
            : b.entry.created_at;
      return bTime.localeCompare(aTime);
    });
  }, [assignments, collaboratorActivity, statusHistory]);

  const grouped = useMemo(() => {
    const map = new Map<string, TimelineEntry[]>();
    for (const entry of entries) {
      const createdAt =
        entry.kind === 'status'
          ? entry.entry.created_at
          : entry.kind === 'collaborator'
            ? entry.entry.created_at
            : entry.entry.created_at;
      const key = dateGroupKey(createdAt, locale);
      const list = map.get(key) ?? [];
      list.push(entry);
      map.set(key, list);
    }
    return Array.from(map.entries());
  }, [entries, locale]);

  return (
    <Card
      variant="muted"
      padding="md"
      header={
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          <HiSwitchHorizontal aria-hidden style={{ width: 18, height: 18 }} />
          {t('tickets:activity.title')}
        </span>
      }
    >
      {entries.length === 0 ? (
        <EmptyMessage>{t('tickets:states.noHistory')}</EmptyMessage>
      ) : (
        grouped.map(([dateLabel, groupEntries]) => (
          <DateGroup key={dateLabel}>
            <DateLabel>{dateLabel}</DateLabel>
            <Timeline>
              {groupEntries.map((item) => {
                if (item.kind === 'status') {
                  const entry = item.entry;
                  return (
                    <Item key={entry.id}>
                      <Dot aria-hidden />
                      <EventTitle>
                        <strong>{entry.changed_by.name}</strong>
                        {' — '}
                        {entry.from_status
                          ? `${localizedName(entry.from_status, locale)} → ${localizedName(entry.to_status, locale)}`
                          : localizedName(entry.to_status, locale)}
                      </EventTitle>
                      <EventMeta>{formatDateTime(entry.created_at, locale)}</EventMeta>
                    </Item>
                  );
                }

                if (item.kind === 'collaborator') {
                  const entry = item.entry;
                  const Icon = entry.action === 'added' ? HiUserAdd : HiUserRemove;
                  return (
                    <Item key={entry.id}>
                      <Dot $accent aria-hidden />
                      <EventTitle>
                        <Icon aria-hidden style={{ display: 'inline', marginInlineEnd: 6 }} />
                        {entry.action === 'added'
                          ? t('tickets:activity.collaboratorAdded', {
                              actor: entry.actor.name,
                              name: entry.collaborator.name,
                            })
                          : t('tickets:activity.collaboratorRemoved', {
                              actor: entry.actor.name,
                              name: entry.collaborator.name,
                            })}
                      </EventTitle>
                      <EventMeta>
                        {entry.created_at ? formatDateTime(entry.created_at, locale) : ''}
                      </EventMeta>
                    </Item>
                  );
                }

                const entry = item.entry;
                return (
                  <Item key={entry.id}>
                    <Dot $accent aria-hidden />
                    <EventTitle>
                      <HiUserCircle aria-hidden style={{ display: 'inline', marginInlineEnd: 6 }} />
                      {t('tickets:activity.assigneeChanged', {
                        actor: entry.assigned_by.name,
                        name: entry.assigned_to.name,
                      })}
                    </EventTitle>
                    <EventMeta>{formatDateTime(entry.created_at, locale)}</EventMeta>
                  </Item>
                );
              })}
            </Timeline>
          </DateGroup>
        ))
      )}
    </Card>
  );
};
