import React from "react";
import { Flag, Mail, MessageSquare, Plus, Search } from "lucide-react";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import type {
  AiConvChannelFilter,
  AiConvFilterTab,
  AiConvListItemData,
  AiConvStatus,
} from "./types";
import {
  ContactAvatar,
  displayContactName,
  PANEL_HEADER_HEIGHT,
} from "./helpers";

// ---------------------------------------------------------------------------
// ConversationStatusChip
// ---------------------------------------------------------------------------

type BadgeVariant = "success" | "default" | "warning" | "secondary";

const STATUS_CONFIG: Record<
  AiConvStatus,
  { label: string; variant: BadgeVariant; dotClass: string }
> = {
  "ai-active": {
    label: "AI Active",
    variant: "success",
    dotClass: "bg-success",
  },
  manual: {
    label: "Manual",
    variant: "default",
    dotClass: "bg-primary",
  },
  "needs-attention": {
    label: "Needs Attention",
    variant: "warning",
    dotClass: "bg-warning",
  },
  closed: {
    label: "Closed",
    variant: "secondary",
    dotClass: "bg-muted-foreground/50",
  },
};

export interface ConversationStatusChipProps {
  status: AiConvStatus;
  showDot?: boolean;
  className?: string;
}

export function ConversationStatusChip({
  status,
  showDot = false,
  className,
}: ConversationStatusChipProps) {
  const { label, variant, dotClass } = STATUS_CONFIG[status];
  return (
    <Badge variant={variant} className={className}>
      {showDot && (
        <span className={cn("size-1.5 shrink-0 rounded-full", dotClass)} />
      )}
      {label}
    </Badge>
  );
}

// ---------------------------------------------------------------------------
// ConversationListItem
// ---------------------------------------------------------------------------

export interface ConversationListItemProps {
  data: AiConvListItemData;
  isActive?: boolean;
  /**
   * Visual variant: "panel" (default) is the 3-row sidebar card used by the
   * Conversations inbox; "row" is a single-line, Gmail-style row (name ·
   * subject · snippet · timestamp) for full-width embedded lists where the
   * user drills into a thread instead of using a side panel.
   */
  variant?: "panel" | "row";
  onClick?: (id: string) => void;
  onRead?: (id: string) => void;
}

export function ConversationListItem({
  data,
  isActive,
  variant = "panel",
  onClick,
  onRead,
}: ConversationListItemProps) {
  if (variant === "row") {
    const unread = Boolean(data.unreadCount);
    return (
      <button
        type="button"
        onClick={() => {
          onClick?.(data.id);
          onRead?.(data.id);
        }}
        className={cn(
          "flex w-full items-center gap-3 px-4 py-3 text-left transition-colors",
          "border-b border-border last:border-b-0",
          isActive ? "bg-muted" : "hover:bg-muted/40",
        )}
      >
        <ContactAvatar name={data.contact.name} size="sm" />
        <span
          className={cn(
            "w-[160px] shrink-0 truncate text-label-small text-foreground",
            !unread && "font-normal",
          )}
        >
          {displayContactName(data.contact.name)}
        </span>
        <span className="min-w-0 flex-1 truncate text-body-small">
          <span className={cn("text-foreground", unread && "font-semibold")}>
            {data.subject ?? data.topic ?? data.lastMessage}
          </span>
          {(data.subject ?? data.topic) && (
            <span className="text-muted-foreground"> · {data.lastMessage}</span>
          )}
        </span>
        <span className="flex shrink-0 items-center gap-2">
          {data.status === "needs-attention" && (
            <Flag className="size-3 text-warning-text" />
          )}
          {data.status === "closed" && (
            <ConversationStatusChip status="closed" />
          )}
          {data.unreadCount ? (
            <Badge
              variant="default"
              className="size-4 justify-center px-0 text-[10px]"
            >
              {data.unreadCount}
            </Badge>
          ) : null}
          <span
            className={cn(
              "whitespace-nowrap text-caption",
              unread
                ? "font-semibold text-foreground"
                : "text-muted-foreground",
            )}
          >
            {data.timestamp}
          </span>
        </span>
      </button>
    );
  }

  return (
    <button
      type="button"
      onClick={() => {
        onClick?.(data.id);
        onRead?.(data.id);
      }}
      className={cn(
        "w-full flex items-start gap-3 px-3 py-3 text-left transition-colors",
        "border-b border-border last:border-b-0",
        isActive ? "bg-muted" : "hover:bg-muted/40",
      )}
    >
      <ContactAvatar name={data.contact.name} />
      <div className="min-w-0 flex-1">
        {/* Row 1 — name + icons + timestamp */}
        <div className="mb-1 flex items-center justify-between gap-2">
          <span className="truncate text-label-small text-foreground">
            {displayContactName(data.contact.name)}
          </span>
          <div className="flex shrink-0 items-center gap-1">
            {data.status === "needs-attention" && (
              <Flag className="size-3 text-warning-text" />
            )}
            {data.channel === "email" ? (
              <Mail className="size-3 text-muted-foreground" />
            ) : (
              <MessageSquare className="size-3 text-muted-foreground" />
            )}
            <span className="whitespace-nowrap text-caption text-muted-foreground">
              {data.timestamp}
            </span>
          </div>
        </div>
        {/* Row 2 — status chip + assigned advisor + unread badge */}
        <div className="mb-1.5 flex items-center justify-between gap-2">
          <div className="flex min-w-0 items-center gap-1.5">
            <ConversationStatusChip status={data.status} showDot />
            {data.assignedTo && (
              <span className="truncate text-caption text-muted-foreground">
                → {data.assignedTo}
              </span>
            )}
          </div>
          {data.unreadCount ? (
            <Badge
              variant="default"
              className="size-4 shrink-0 justify-center px-0 text-[10px]"
            >
              {data.unreadCount}
            </Badge>
          ) : null}
        </div>
        {/* Row 3 — last message preview */}
        <p className="line-clamp-2 text-body-small leading-relaxed text-muted-foreground">
          {data.lastMessageRole === "bot" ? (
            <span className="font-medium text-foreground/60">AI: </span>
          ) : data.lastMessageRole === "advisor" ? (
            <span className="font-medium text-foreground/60">You: </span>
          ) : data.lastMessageRole === "visitor" ? (
            <span className="font-medium text-foreground/60">
              {displayContactName(data.contact.name).split(" ")[0]}:{" "}
            </span>
          ) : null}
          {data.lastMessage}
        </p>
      </div>
    </button>
  );
}

// ---------------------------------------------------------------------------
// ConversationList
// ---------------------------------------------------------------------------

function filterConversations(
  conversations: AiConvListItemData[],
  query: string,
  filter: AiConvFilterTab,
  channelFilter: AiConvChannelFilter,
): AiConvListItemData[] {
  const q = query.toLowerCase();
  return conversations.filter((c) => {
    const matchesFilter =
      filter === "all" ||
      (filter === "emails"
        ? (c.channel ?? "chat") === "email"
        : c.status === filter);
    const matchesChannel =
      channelFilter === "all" || (c.channel ?? "chat") === channelFilter;
    const matchesSearch =
      !q ||
      c.contact.name.toLowerCase().includes(q) ||
      c.lastMessage.toLowerCase().includes(q);
    return matchesFilter && matchesChannel && matchesSearch;
  });
}

const FILTER_TABS: { id: AiConvFilterTab; label: string }[] = [
  { id: "all", label: "All" },
  { id: "emails", label: "Emails" },
  { id: "needs-attention", label: "Urgent" },
  { id: "closed", label: "Archived" },
  { id: "ai-active", label: "AI Active" },
];

export interface ConversationListProps {
  conversations: AiConvListItemData[];
  activeId?: string;
  /**
   * Embedded mode for contexts scoped to a handful of conversations (e.g.
   * one opportunity's applicants): swaps the search + filter-tab chrome for
   * a slim labelled header (overline label + count badge) and lists every
   * conversation unfiltered. Defaults to false.
   */
  compact?: boolean;
  /** Header label shown in compact mode. Defaults to "Conversations". */
  compactLabel?: string;
  /**
   * Shows a "New Email" button in the compact header when set. For scoped
   * contexts (e.g. one opportunity's applicants) where the broker may need
   * to start a new thread instead of only replying to existing ones.
   */
  onCompose?: () => void;
  /**
   * Visual variant applied to every list item — "panel" (default, sidebar
   * card) or "row" (single-line, Gmail-style; pair with `compact` for
   * full-width embedded lists).
   */
  itemVariant?: "panel" | "row";
  searchQuery?: string;
  activeFilter?: AiConvFilterTab;
  channelFilter?: AiConvChannelFilter;
  hasMore?: boolean;
  isLoadingMore?: boolean;
  onSearchChange?: (v: string) => void;
  onFilterChange?: (f: AiConvFilterTab) => void;
  onChannelFilterChange?: (f: AiConvChannelFilter) => void;
  onSelect?: (id: string) => void;
  onRead?: (id: string) => void;
  onLoadMore?: () => void;
  className?: string;
}

export function ConversationList({
  conversations,
  activeId,
  compact = false,
  compactLabel = "Conversations",
  onCompose,
  itemVariant = "panel",
  searchQuery = "",
  activeFilter = "all",
  channelFilter = "all",
  hasMore,
  isLoadingMore,
  onSearchChange,
  onFilterChange,
  onSelect,
  onRead,
  onLoadMore,
  className,
}: ConversationListProps) {
  return (
    <div
      className={cn(
        "flex flex-col border-r border-border bg-background",
        className,
      )}
    >
      {compact ? (
        <div className="flex shrink-0 items-center gap-2 border-b border-border px-4 py-3">
          <span className="text-overline text-muted-foreground">
            {compactLabel}
          </span>
          <Badge variant="secondary">{conversations.length}</Badge>
          {onCompose && (
            <Button
              variant="ghost"
              size="sm"
              className="ml-auto h-7 gap-1 px-2"
              onClick={onCompose}
            >
              <Plus className="size-3.5" />
              New Email
            </Button>
          )}
        </div>
      ) : (
        <div className={cn(PANEL_HEADER_HEIGHT, "flex shrink-0 flex-col")}>
          <div className="flex shrink-0 items-center border-b border-border px-3 py-2.5">
            <div className="relative flex-1">
              <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={searchQuery}
                onChange={(e) => onSearchChange?.(e.target.value)}
                placeholder="Search conversations..."
                className="h-8 pl-8 text-body-small"
              />
            </div>
          </div>

          <div className="flex flex-1 items-center border-b border-border">
            <Tabs
              value={activeFilter}
              onValueChange={(v) => v && onFilterChange?.(v as AiConvFilterTab)}
              className="w-full"
            >
              <TabsList
                variant="line"
                className="w-full justify-start gap-0 h-auto"
              >
                {FILTER_TABS.map((tab) => (
                  <TabsTrigger
                    key={tab.id}
                    value={tab.id}
                    className="flex-none px-3 py-2 text-button-xs"
                  >
                    {tab.label}
                  </TabsTrigger>
                ))}
              </TabsList>
            </Tabs>
          </div>
        </div>
      )}

      {/* List */}
      <div className="flex-1 overflow-y-auto" tabIndex={0}>
        {(() => {
          const filtered = compact
            ? conversations
            : filterConversations(
                conversations,
                searchQuery,
                activeFilter,
                channelFilter,
              );
          return filtered.length === 0 ? (
            <div className="flex flex-col items-center justify-center gap-2 p-8 text-muted-foreground">
              <MessageSquare className="size-8 opacity-30" />
              <p className="text-body-small">No conversations</p>
              {searchQuery && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => onSearchChange?.("")}
                >
                  Clear search
                </Button>
              )}
              {!searchQuery && activeFilter !== "all" && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => onFilterChange?.("all")}
                >
                  Clear filter
                </Button>
              )}
            </div>
          ) : (
            <>
              {filtered.map((item) => (
                <ConversationListItem
                  key={item.id}
                  data={item}
                  isActive={activeId === item.id}
                  variant={itemVariant}
                  onClick={onSelect}
                  onRead={onRead}
                />
              ))}
              {hasMore && (
                <div className="border-t border-border p-3">
                  <Button
                    variant="outline"
                    size="sm"
                    className="w-full"
                    disabled={isLoadingMore}
                    onClick={onLoadMore}
                  >
                    {isLoadingMore ? "Loading..." : "Load more"}
                  </Button>
                </div>
              )}
            </>
          );
        })()}
      </div>
    </div>
  );
}
