'use client';

import { History, MessageSquareText, RefreshCw } from 'lucide-react';

import { PersonInfo } from '@/components/person-avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Timeline, TimelineItem } from '@/components/ui/timeline';
import { cn } from '@/lib/utils';
import type {
  TicketTimelineEventType,
  TicketTimelineItem,
  TicketTimelineNoteKind,
  TicketTimelineSource,
  TicketTimelineUser,
} from '@/types';
import { formatTimelineDateTime } from '@/utils/date';
import { getPersonLabel } from '@/utils/person';

import { useTicketTimelineQuery } from '../../hooks/useTicketQueries';
import { TicketTimelineSkeleton } from './TicketTimelineSkeleton';

function TimelineDate({ value }: { value: string }) {
  const { date, time } = formatTimelineDateTime(value);

  return (
    <time dateTime={value} className="block tabular-nums">
      <span className="block text-sm font-semibold text-foreground">
        {date}
      </span>
      <span className="block text-xs text-muted-foreground">{time}</span>
    </time>
  );
}

function getNoteKindLabel(kind: TicketTimelineNoteKind) {
  switch (kind) {
    case 'system_note':
      return 'System note';
    case 'repair_note':
      return 'Repair note';
    case 'review_comment':
      return 'Review comment';
    default:
      return 'Note';
  }
}

function HistoryNote({ item }: { item: TicketTimelineItem }) {
  const note = item.note;
  if (!note) return null;

  const noteText = note.text.trim();
  if (!noteText) return null;

  return (
    <div className="mt-3 rounded-lg  border border-amber-300/80 bg-amber-50/90 px-3 py-2.5 dark:border-amber-500/30 dark:bg-amber-500/10">
      <div className="flex items-center gap-1.5 text-xs font-medium text-amber-900 dark:text-amber-200">
        <MessageSquareText className="size-3.5 shrink-0 text-amber-700 dark:text-amber-300" />
        <span>
          {getNoteKindLabel(note.kind)} by {getPersonLabel(note.author)}
        </span>
      </div>
      <p className="mt-1.5 text-sm leading-relaxed text-amber-950/80 dark:text-amber-100/90">
        {noteText}
      </p>
    </div>
  );
}

function getSourceLabel(source: TicketTimelineSource) {
  return source === 'system' ? 'System Generated' : 'User Action';
}

function SystemHistoryEntry({ item }: { item: TicketTimelineItem }) {
  const noteText = item.note?.text?.trim();

  return (
    <div className="rounded-lg border border-dashed border-primary/25 bg-primary/5 px-4 py-3.5">
      <Badge className="rounded-lg px-2.5 py-0.5 text-[10px] font-semibold tracking-wider uppercase">
        {getSourceLabel(item.source)}
      </Badge>
      <h3 className="mt-2 text-sm font-semibold text-foreground">
        {item.title}
      </h3>
      {noteText ? (
        <p className="mt-1 text-sm leading-relaxed text-muted-foreground">
          {noteText}
        </p>
      ) : null}
    </div>
  );
}

function isSameUser(actor: TicketTimelineUser, target: TicketTimelineUser) {
  if (actor.user_id !== null && target.user_id !== null) {
    return actor.user_id === target.user_id;
  }

  const actorEmail = actor.email?.trim().toLowerCase();
  const targetEmail = target.email?.trim().toLowerCase();
  if (actorEmail && targetEmail) return actorEmail === targetEmail;

  return (
    Boolean(actor.name?.trim()) &&
    actor.name?.trim().toLowerCase() === target.name?.trim().toLowerCase()
  );
}

function getTargetLabel(eventType: TicketTimelineEventType | null) {
  switch (eventType) {
    case 'assignment_added':
      return 'Assigned to';
    case 'assignment_replaced':
      return 'Replacement worker';
    case 'assignment_updated':
      return 'Assigned worker';
    case 'assignment_deleted':
      return 'Removed worker';
    default:
      return 'Affected worker';
  }
}

function UserHistoryEntry({ item }: { item: TicketTimelineItem }) {
  const noteText = item.note?.text?.trim();
  const showTargetUser =
    item.target_user && !isSameUser(item.actor, item.target_user);

  return (
    <div className="rounded-lg border bg-card p-4">
      <h3 className="mb-3 text-sm font-semibold text-foreground">
        {item.title}
      </h3>
      <PersonInfo person={item.actor} />
      {showTargetUser && item.target_user ? (
        <div className="mt-3 space-y-1">
          <p className="text-xs text-muted-foreground">
            {getTargetLabel(item.event_type)}
          </p>
          <PersonInfo person={item.target_user} />
        </div>
      ) : null}
      {noteText ? <HistoryNote item={item} /> : null}
    </div>
  );
}

function TimelineHeader() {
  return (
    <div className="flex items-center gap-2">
      <History className="size-5 text-primary" />
      <h2 className="text-base font-semibold">Audit & Lifecycle Timeline</h2>
    </div>
  );
}

export function TicketHistoryCard({ ticketId }: { ticketId: string }) {
  const timelineQuery = useTicketTimelineQuery(ticketId);

  if (timelineQuery.isLoading) {
    return <TicketTimelineSkeleton />;
  }

  const history = timelineQuery.data?.history ?? [];

  return (
    <div className="space-y-4">
      <TimelineHeader />

      {timelineQuery.isError ? (
        <div
          role="alert"
          className="rounded-lg border border-dashed border-destructive/40 bg-destructive/5 px-4 py-6 text-center"
        >
          <p className="text-sm text-destructive">
            Failed to load the ticket timeline.
          </p>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="mt-3"
            disabled={timelineQuery.isFetching}
            onClick={() => timelineQuery.refetch()}
          >
            <RefreshCw
              className={cn(
                'size-4',
                timelineQuery.isFetching && 'animate-spin',
              )}
            />
            Retry
          </Button>
        </div>
      ) : history.length ? (
        <Timeline>
          {history.map((item, index) => (
            <TimelineItem
              key={item.id}
              layout="left"
              isLast={index === history.length - 1}
              opposite={<TimelineDate value={item.created_at} />}
              marker={
                <span className="flex size-4 items-center justify-center rounded-full border bg-background shadow-xs">
                  <span
                    className={cn(
                      'size-1.5 rounded-full',
                      item.source === 'system'
                        ? 'bg-muted-foreground'
                        : 'bg-primary',
                    )}
                  />
                </span>
              }
            >
              {item.source === 'system' ? (
                <SystemHistoryEntry item={item} />
              ) : (
                <UserHistoryEntry item={item} />
              )}
            </TimelineItem>
          ))}
        </Timeline>
      ) : (
        <div className="rounded-lg border border-dashed border-border/80 bg-muted/10 px-4 py-8 text-center">
          <p className="text-sm font-medium text-muted-foreground">
            No timeline entries yet
          </p>
        </div>
      )}
    </div>
  );
}
