"use client";

import { useEffect, useRef } from "react";
import { Inbox, Loader2, Lock, Search, UserRound, Users, CheckCircle2, MessagesSquare } from "lucide-react";
import { useT, useLocale } from "@/shared/i18n/client";
import { cn } from "@/shared/lib/utils";
import { displayName } from "@/shared/lib/user-display";
import { PersonAvatar } from "./person-avatar";
import { formatListTime, formatWaiting, lastMessagePreview } from "./support-utils";
import type { SupportInboxCounts, SupportInboxView, Ticket } from "@/domain/entities/ticket";

const VIEWS: { key: SupportInboxView; icon: React.ComponentType<{ className?: string }> }[] = [
  { key: "mine", icon: UserRound },
  { key: "unassigned", icon: Inbox },
  { key: "open", icon: Users },
  { key: "resolved", icon: CheckCircle2 },
];

interface ConversationListProps {
  view: SupportInboxView;
  onViewChange: (view: SupportInboxView) => void;
  counts: SupportInboxCounts | null;
  search: string;
  onSearchChange: (value: string) => void;
  conversations: Ticket[];
  loading: boolean;
  hasMore: boolean;
  onLoadMore: () => void;
  selectedId: number | null;
  onSelect: (conversation: Ticket) => void;
  currentUserId?: number;
  live: boolean;
}

export function ConversationList({
  view,
  onViewChange,
  counts,
  search,
  onSearchChange,
  conversations,
  loading,
  hasMore,
  onLoadMore,
  selectedId,
  onSelect,
  currentUserId,
  live,
}: ConversationListProps) {
  const t = useT();
  const sentinel = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = sentinel.current;
    if (!el || !hasMore || loading) return;
    const observer = new IntersectionObserver((entries) => {
      if (entries.some((entry) => entry.isIntersecting)) onLoadMore();
    });
    observer.observe(el);
    return () => observer.disconnect();
  }, [hasMore, loading, onLoadMore]);

  return (
    <div className="flex h-full min-h-0 flex-col border-r border-border bg-card">
      <div className="space-y-3 px-4 pb-3 pt-4">
        <div className="flex items-center justify-between">
          <h2 className="flex items-center gap-2 text-base font-semibold text-foreground">
            <MessagesSquare className="h-4.5 w-4.5 text-primary" />
            {t.support.title}
          </h2>
          <span
            className={cn(
              "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[11px] font-medium",
              live ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400" : "bg-muted text-muted-foreground",
            )}
          >
            <span className="relative flex h-2 w-2">
              {live && <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75" />}
              <span className={cn("relative inline-flex h-2 w-2 rounded-full", live ? "bg-emerald-500" : "bg-muted-foreground/50")} />
            </span>
            {live ? t.support.live : t.support.autoRefresh}
          </span>
        </div>

        <div className="relative">
          <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <input
            value={search}
            onChange={(e) => onSearchChange(e.target.value)}
            placeholder={t.support.searchPlaceholder}
            className="h-9 w-full rounded-lg border border-transparent bg-muted/60 pl-9 pr-3 text-sm outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/30 focus:bg-card focus:ring-2 focus:ring-primary/15"
          />
        </div>

        <div className="grid grid-cols-2 gap-1 rounded-lg bg-muted/60 p-1">
          {VIEWS.map(({ key, icon: Icon }) => {
            const active = key === view;
            const count = counts?.[key];
            return (
              <button
                key={key}
                type="button"
                onClick={() => onViewChange(key)}
                className={cn(
                  "flex items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium transition-all",
                  active ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground",
                )}
              >
                <Icon className="h-3.5 w-3.5 shrink-0" />
                <span className="truncate">{t.support.views[key]}</span>
                {count !== undefined && key !== "resolved" && (
                  <span className={cn("ml-auto rounded-full px-1.5 text-[10px] tabular-nums", active ? "bg-primary/10 text-primary" : "bg-background/80")}>
                    {count}
                  </span>
                )}
              </button>
            );
          })}
        </div>
      </div>

      <div className="min-h-0 flex-1 overflow-y-auto">
        {loading && conversations.length === 0 ? (
          <div className="space-y-1 px-2">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="flex animate-pulse gap-3 rounded-xl px-3 py-3">
                <div className="h-10 w-10 rounded-full bg-muted" />
                <div className="flex-1 space-y-2 py-1">
                  <div className="h-3 w-2/3 rounded bg-muted" />
                  <div className="h-3 w-full rounded bg-muted/70" />
                </div>
              </div>
            ))}
          </div>
        ) : conversations.length === 0 ? (
          <div className="flex h-full flex-col items-center justify-center gap-2 px-8 text-center">
            <div className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary">
              <Inbox className="h-5 w-5" />
            </div>
            <p className="text-sm font-medium text-foreground">{search ? t.support.noResults : t.support.emptyTitle}</p>
            {!search && <p className="text-xs text-muted-foreground">{t.support.emptyDescription}</p>}
          </div>
        ) : (
          <ul className="space-y-0.5 px-2 pb-3">
            {conversations.map((conversation) => (
              <ConversationRow
                key={conversation.id}
                conversation={conversation}
                selected={conversation.id === selectedId}
                onSelect={() => onSelect(conversation)}
                currentUserId={currentUserId}
              />
            ))}
            {hasMore && (
              <div ref={sentinel} className="flex justify-center py-3">
                <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              </div>
            )}
          </ul>
        )}
      </div>
    </div>
  );
}

function ConversationRow({
  conversation,
  selected,
  onSelect,
  currentUserId,
}: {
  conversation: Ticket;
  selected: boolean;
  onSelect: () => void;
  currentUserId?: number;
}) {
  const t = useT();
  const locale = useLocale();
  const unread = (conversation.unread_count ?? 0) > 0;
  const activity = conversation.last_message?.created_at ?? conversation.last_message_at ?? conversation.created_at;
  const client = conversation.created_by;
  const resolved = conversation.status.key === "Resolved" || conversation.status.key === "Closed";

  return (
    <li>
      <button
        type="button"
        onClick={onSelect}
        className={cn(
          "group relative flex w-full gap-3 rounded-xl px-3 py-2.5 text-left transition-colors",
          selected ? "bg-primary/[0.08]" : "hover:bg-muted/70",
        )}
      >
        {selected && <span className="absolute inset-y-2 left-0 w-0.5 rounded-full bg-primary" />}
        <PersonAvatar
          name={client?.name}
          email={client?.email}
          initials={client?.initials}
          avatarUrl={client?.avatar_url}
          size={40}
        />
        <div className="min-w-0 flex-1">
          <div className="flex items-baseline gap-2">
            <span className={cn("truncate text-sm text-foreground", unread ? "font-semibold" : "font-medium")}>
              {client ? displayName(client) : conversation.company?.name}
            </span>
            <span className={cn("ml-auto shrink-0 text-[11px] tabular-nums", unread ? "font-semibold text-primary" : "text-muted-foreground")}>
              {formatListTime(activity, t, locale)}
            </span>
          </div>
          <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
            <span className="truncate">{conversation.company?.name}</span>
            <span className="shrink-0">·</span>
            <span className={cn("truncate", unread && "text-foreground/80")}>{conversation.title}</span>
          </div>
          <div className="mt-1 flex items-center gap-2">
            {conversation.last_message?.kind === "internal" && <Lock className="h-3 w-3 shrink-0 text-amber-500" />}
            <p className={cn("line-clamp-1 flex-1 text-[13px]", unread ? "font-medium text-foreground" : "text-muted-foreground")}>
              {lastMessagePreview(conversation.last_message, currentUserId, t)}
            </p>
            {unread ? (
              <span className="flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full bg-primary px-1.5 text-[10px] font-bold text-primary-foreground">
                {conversation.unread_count! > 9 ? "9+" : conversation.unread_count}
              </span>
            ) : conversation.assignee ? (
              <PersonAvatar name={conversation.assignee.name} email={conversation.assignee.email} initials={conversation.assignee.initials} size={18} />
            ) : null}
          </div>
          {conversation.status.key === "Resolved" && (
            <span className="mt-1.5 inline-flex items-center gap-1 rounded-md bg-emerald-50 px-1.5 py-0.5 text-[10px] font-medium text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400">
              {t.support.statuses.Resolved}
            </span>
          )}
          {!resolved && conversation.awaiting_reply && conversation.last_client_message_at && (
            <span className="mt-1.5 inline-flex items-center gap-1 rounded-md bg-amber-50 px-1.5 py-0.5 text-[10px] font-medium text-amber-700 dark:bg-amber-950/40 dark:text-amber-400">
              {t.support.awaitingReply} · {formatWaiting(conversation.last_client_message_at, locale)}
            </span>
          )}
        </div>
      </button>
    </li>
  );
}
