"use client";

import { useCallback, useEffect, useState } from "react";
import {
  Activity,
  ArrowRight,
  CheckCircle2,
  Flag,
  Loader2,
  Mail,
  MessageSquare,
  Paperclip,
  Pencil,
  Tag,
  Trash2,
  User as UserIcon,
  UserMinus,
} from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/presentation/components/ui/card";
import { Button } from "@/presentation/components/ui/button";
import { useRepositories } from "@/di/repository-provider";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDateTime, formatRelative } from "@/shared/lib/format-date";
import { MemberAvatar } from "./member-avatar";
import type {
  TicketHistoryEntry,
  TicketHistoryEventType,
} from "@/domain/entities/ticket";

interface HistoryTimelineProps {
  ticketId: number;
  /** Bumped by parent after a mutation to force a refetch from scratch. */
  refreshToken?: number;
  pageSize?: number;
}

const ICONS: Record<TicketHistoryEventType, React.ComponentType<{ className?: string }>> = {
  create: Activity,
  deleted: Trash2,
  status_change: CheckCircle2,
  priority_change: Flag,
  category_change: Tag,
  title_change: Pencil,
  description_change: Pencil,
  assign: UserIcon,
  unassign: UserMinus,
  message_client: Mail,
  message_internal: MessageSquare,
  message_edited: Pencil,
  message_deleted: Trash2,
  attachment_added: Paperclip,
  attachment_removed: Paperclip,
};

export function HistoryTimeline({ ticketId, refreshToken = 0, pageSize = 20 }: HistoryTimelineProps) {
  const t = useT();
  const locale = useLocale();
  const container = useRepositories();
  const [entries, setEntries] = useState<TicketHistoryEntry[]>([]);
  const [cursor, setCursor] = useState<number | null>(null);
  const [hasMore, setHasMore] = useState(false);
  const [loading, setLoading] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const loadFirst = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const page = await container.ticketRepository.getHistory(ticketId, { limit: pageSize });
      setEntries(page.items);
      setCursor(page.next_cursor);
      setHasMore(page.has_more);
    } catch (err) {
      const message =
        (err as { response?: { data?: { message?: string } }; message?: string })?.response?.data?.message ??
        (err as { message?: string })?.message ??
        "Unknown error";
      setError(message);
    } finally {
      setLoading(false);
    }
  }, [container, ticketId, pageSize]);

  useEffect(() => {
    void loadFirst();
  }, [loadFirst, refreshToken]);

  async function loadMore() {
    if (!cursor) return;
    setLoadingMore(true);
    try {
      const page = await container.ticketRepository.getHistory(ticketId, {
        limit: pageSize,
        cursor,
      });
      setEntries((prev) => [...prev, ...page.items]);
      setCursor(page.next_cursor);
      setHasMore(page.has_more);
    } catch {
      // Pagination failure: stop offering "load more" rather than crashing the page.
      setHasMore(false);
    } finally {
      setLoadingMore(false);
    }
  }

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between space-y-0">
        <CardTitle className="text-base flex items-center gap-2">
          <Activity className="w-4 h-4" /> {t.ticketDetail.sections.history}
        </CardTitle>
        <span className="text-[11px] text-muted-foreground">
          {t.ticketDetail.history.readOnly}
        </span>
      </CardHeader>
      <CardContent>
        {loading && entries.length === 0 ? (
          <div className="flex items-center justify-center py-6">
            <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
          </div>
        ) : error ? (
          <p className="text-sm text-destructive text-center py-6">{error}</p>
        ) : entries.length === 0 ? (
          <p className="text-sm text-muted-foreground text-center py-6">
            {t.ticketDetail.history.empty}
          </p>
        ) : (
          <ol className="relative space-y-3 border-l border-border pl-6">
            {entries.map((e) => {
              const Icon = ICONS[e.event_type] ?? Activity;
              // Client-kind messages are written by either side; older rows carry no flag.
              const labelKey =
                e.event_type === "message_client" && e.metadata?.from_dadycar === false
                  ? "message_from_client"
                  : e.event_type;
              const localized =
                t.ticketDetail.history.labels[labelKey] ?? e.description_fr;
              return (
                <li key={e.id} className="relative">
                  <span className="absolute -left-[34px] flex h-7 w-7 items-center justify-center rounded-full bg-primary/10 text-primary ring-4 ring-card">
                    <Icon className="h-3.5 w-3.5" />
                  </span>
                  <div className="rounded-lg border border-border bg-background px-3 py-2">
                    <div className="flex items-center justify-between gap-2">
                      <div className="text-sm flex items-center gap-2 min-w-0">
                        <MemberAvatar initials={e.actor.initials} name={e.actor.name} size={20} />
                        <span className="truncate">
                          <span className="font-medium">{e.actor.name}</span>{" "}
                          <span className="text-foreground/80">{localized}</span>
                        </span>
                      </div>
                      <span
                        title={formatDateTime(e.created_at, locale)}
                        className="shrink-0 text-xs text-muted-foreground"
                      >
                        {formatRelative(e.created_at, locale)}
                      </span>
                    </div>
                    {(e.before !== null || e.after !== null) && (
                      <div className="mt-1.5 flex items-center gap-2 text-xs flex-wrap">
                        {e.before !== null && (
                          <span className="rounded bg-muted px-1.5 py-0.5 text-muted-foreground line-through">
                            {e.before}
                          </span>
                        )}
                        <ArrowRight className="h-3 w-3 text-muted-foreground" />
                        {e.after !== null && (
                          <span className="rounded bg-primary/10 px-1.5 py-0.5 text-primary font-medium">
                            {e.after}
                          </span>
                        )}
                      </div>
                    )}
                  </div>
                </li>
              );
            })}
          </ol>
        )}
        {hasMore && (
          <Button
            variant="outline"
            size="sm"
            className="w-full mt-4"
            onClick={loadMore}
            disabled={loadingMore}
          >
            {loadingMore && <Loader2 className="w-3.5 h-3.5 mr-2 animate-spin" />}
            {t.ticketDetail.history.loadMore}
          </Button>
        )}
      </CardContent>
    </Card>
  );
}
