import React, { useMemo } from 'react';
import styled, { useTheme as useStyledTheme } from 'styled-components';
import { useLocale } from '@/app/providers/LocaleProvider';
import { StatusBadge, UserAvatar } from '@/shared/components/ui';
import { MessageAttachments } from '@/features/tickets/components/MessageAttachments';
import type { TicketReply } from '@/features/tickets/types/ticket.types';
import { formatMessageTimestamp } from '@/features/tickets/utils/ticketDisplay';
import { mixParticipantAccent, type ParticipantColor } from '@/features/tickets/utils/participantColors';
import {
  resolveTicketParticipantColor,
  resolveTicketParticipantKind,
  ticketParticipantRoleLabelKey,
  type TicketParticipantContext,
} from '@/features/tickets/utils/ticketParticipantContext';
import type { Theme } from '@/styles/theme';

const CONVERSATION_BUBBLE_RADIUS = '22px';
const AVATAR_COLUMN_WIDTH = '28px';

const Thread = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  max-width: ${({ theme }) => theme.layout.conversationMaxWidth};
`;

const DateSeparator = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  margin: ${({ theme }) => `${theme.spacing[8]} 0 ${theme.spacing[5]}`};

  &:first-child {
    margin-top: 0;
  }

  span {
    padding: ${({ theme }) => `${theme.spacing[1]} ${theme.spacing[4]}`};
    border-radius: ${({ theme }) => theme.borderRadius.full};
    background: ${({ theme }) => theme.colors.surface};
    border: 1px solid ${({ theme }) => theme.colors.borderSoft};
    color: ${({ theme }) => theme.colors.text.tertiary};
    font-size: ${({ theme }) => theme.typography.fontSize.xs};
    font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
    letter-spacing: ${({ theme }) => theme.typography.letterSpacing.wide};
  }
`;

const MessageBlock = styled.div<{ $grouped: boolean }>`
  display: grid;
  grid-template-columns: ${AVATAR_COLUMN_WIDTH} minmax(0, 1fr);
  column-gap: ${({ theme }) => theme.spacing[3]};
  align-items: start;
  margin-top: ${({ $grouped, theme }) => ($grouped ? theme.spacing[2] : theme.spacing[6])};

  &:first-of-type {
    margin-top: 0;
  }
`;

const SenderHeader = styled.header`
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[3]};
  margin-bottom: ${({ theme }) => theme.spacing[2]};
  min-width: 0;
`;

const SenderMeta = styled.div`
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: ${({ theme }) => `${theme.spacing[2]} ${theme.spacing[3]}`};
  min-width: 0;
`;

const SenderName = styled.span`
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  color: ${({ theme }) => theme.colors.text.primary};
  line-height: ${({ theme }) => theme.typography.lineHeight.tight};
`;

const RoleBadge = styled.span<{ $color: string; $background: string; $border: string }>`
  font-size: 0.6875rem;
  font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
  color: ${({ $color }) => $color};
  padding: 2px ${({ theme }) => theme.spacing[2]};
  border-radius: ${({ theme }) => theme.borderRadius.full};
  background: ${({ $background }) => $background};
  border: 1px solid ${({ $border }) => $border};
  line-height: 1.2;
  white-space: nowrap;
`;

const AvatarColumn = styled.div<{ $visible: boolean }>`
  grid-column: 1;
  grid-row: 2;
  width: ${AVATAR_COLUMN_WIDTH};
  visibility: ${({ $visible }) => ($visible ? 'visible' : 'hidden')};
`;

const BubbleColumn = styled.div`
  grid-column: 2;
  grid-row: 2;
  min-width: 0;
`;

const Bubble = styled.article<{
  $compact?: boolean;
  $accent: ParticipantColor;
  $surface: string;
  $borderSoft: string;
}>`
  padding: ${({ theme, $compact }) =>
    $compact
      ? `${theme.spacing[3]} ${theme.spacing[4]}`
      : `${theme.spacing[4]} ${theme.spacing[5]}`};
  border-radius: ${CONVERSATION_BUBBLE_RADIUS};
  line-height: ${({ theme }) => theme.typography.lineHeight.relaxed};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  white-space: pre-wrap;
  text-align: start;
  word-break: break-word;
  max-width: 100%;
  width: fit-content;
  min-width: 8rem;
  color: ${({ theme }) => theme.colors.conversation.inboundText};
  background: ${({ $surface }) => $surface};
  border: 1px solid
    ${({ $accent, $borderSoft }) => mixParticipantAccent($accent.avatarBackground, 20, $borderSoft)};
  border-inline-start: 3px solid ${({ $accent }) => $accent.avatarBackground};
  box-shadow: ${({ theme }) => theme.shadows.xs};
`;

const BubbleMeta = styled.footer<{ $accent: ParticipantColor; $borderSoft: string }>`
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: ${({ theme }) => theme.spacing[2]};
  margin-top: ${({ theme }) => theme.spacing[3]};
  padding-top: ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
  line-height: 1;
  color: ${({ theme }) => theme.colors.text.tertiary};
  border-top: 1px solid
    ${({ $accent, $borderSoft }) => mixParticipantAccent($accent.avatarBackground, 16, $borderSoft)};
`;

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

const EmptyWrap = styled.div`
  padding: ${({ theme }) => theme.spacing[10]} ${({ theme }) => theme.spacing[4]};
  text-align: center;
`;

const EmptyText = styled.p`
  margin: 0;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.secondary};
  line-height: ${({ theme }) => theme.typography.lineHeight.relaxed};
`;

type GroupedReply = TicketReply & {
  showHeader: boolean;
  showDate: boolean;
  dateLabel: string;
  roleLabel: string;
  timestampLabel: string;
  participantColor: ParticipantColor;
};

function participantAvatarProps(color: ParticipantColor) {
  return {
    ringColor: color.avatarBackground,
    avatarBackground: color.avatarBackground,
    avatarText: color.avatarText,
  };
}

function dayKey(iso: string): string {
  return iso.slice(0, 10);
}

function formatDayLabel(iso: string, locale: string): string {
  try {
    return new Intl.DateTimeFormat(locale === 'ar' ? 'ar' : 'en', {
      weekday: 'short',
      month: 'short',
      day: 'numeric',
    }).format(new Date(iso));
  } catch {
    return iso.slice(0, 10);
  }
}

export interface RepliesThreadProps {
  replies: TicketReply[];
  participantContext: TicketParticipantContext;
}

export const RepliesThread: React.FC<RepliesThreadProps> = ({
  replies,
  participantContext,
}) => {
  const { t, locale } = useLocale();
  const theme = useStyledTheme() as Theme;
  const { mode, colors } = theme;

  const grouped = useMemo((): GroupedReply[] => {
    return replies.map((reply, index) => {
      const prev = replies[index - 1];
      const showHeader =
        !prev ||
        prev.user.id !== reply.user.id ||
        dayKey(prev.created_at) !== dayKey(reply.created_at);
      const showDate = !prev || dayKey(prev.created_at) !== dayKey(reply.created_at);
      const kind = resolveTicketParticipantKind(reply.user.id, participantContext);
      const participantColor = resolveTicketParticipantColor(
        reply.user.id,
        participantContext,
        mode,
      );

      return {
        ...reply,
        showHeader,
        showDate,
        dateLabel: formatDayLabel(reply.created_at, locale),
        roleLabel: t(ticketParticipantRoleLabelKey(kind)),
        timestampLabel: formatMessageTimestamp(reply.created_at, locale),
        participantColor,
      };
    });
  }, [replies, participantContext, locale, t, mode]);

  if (replies.length === 0) {
    return (
      <EmptyWrap>
        <EmptyText>{t('tickets:states.noReplies')}</EmptyText>
      </EmptyWrap>
    );
  }

  return (
    <Thread>
      {grouped.map((reply) => (
        <React.Fragment key={reply.id}>
          {reply.showDate && (
            <DateSeparator>
              <span>{reply.dateLabel}</span>
            </DateSeparator>
          )}
          <MessageBlock $grouped={!reply.showHeader}>
            {reply.showHeader && (
              <SenderHeader>
                <UserAvatar
                  name={reply.user.name}
                  size="sm"
                  {...participantAvatarProps(reply.participantColor)}
                />
                <SenderMeta>
                  <SenderName>{reply.user.name}</SenderName>
                  <RoleBadge
                    $color={reply.participantColor.text}
                    $background={reply.participantColor.background}
                    $border={reply.participantColor.border}
                  >
                    {reply.roleLabel}
                  </RoleBadge>
                </SenderMeta>
              </SenderHeader>
            )}
            <AvatarColumn $visible={!reply.showHeader} aria-hidden={reply.showHeader}>
              {!reply.showHeader ? (
                <UserAvatar
                  name={reply.user.name}
                  size="sm"
                  {...participantAvatarProps(reply.participantColor)}
                />
              ) : (
                <span />
              )}
            </AvatarColumn>
            <BubbleColumn>
              <Bubble
                $compact={!reply.showHeader}
                $accent={reply.participantColor}
                $surface={colors.surface}
                $borderSoft={colors.borderSoft}
              >
                {reply.is_solution && (
                  <SolutionWrap>
                    <StatusBadge tone="success" size="sm">
                      {t('tickets:labels.solution')}
                    </StatusBadge>
                  </SolutionWrap>
                )}
                {reply.content.trim() ? reply.content : null}
                {reply.attachments && reply.attachments.length > 0 && (
                  <MessageAttachments
                    attachments={reply.attachments}
                    accentColor={reply.participantColor.avatarBackground}
                  />
                )}
                <BubbleMeta
                  $accent={reply.participantColor}
                  $borderSoft={colors.borderSoft}
                >
                  <time dateTime={reply.created_at}>{reply.timestampLabel}</time>
                </BubbleMeta>
              </Bubble>
            </BubbleColumn>
          </MessageBlock>
        </React.Fragment>
      ))}
    </Thread>
  );
};
