/**
 * AI Conversations — WealthX Backoffice
 *
 * 3-panel inbox for managing AI + advisor conversations from website chatbot leads.
 *
 * Component hierarchy:
 *   Atom     → ConversationStatusChip
 *   Molecule → ConversationListItem, ChatBubble
 *   Organism → ConversationList, ChatThread, ChatComposer, AICollectedDataSection, LeadInfoPanel
 *   Template → ConversationsPage
 */

import React, { useState } from "react";
import { ChevronLeft, MessageSquare, Search } from "lucide-react";
import { cn } from "@/lib/utils";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import type {
  AiConvAdvisor,
  AiConvAppointmentData,
  AiConvChannel,
  AiConvChannelFilter,
  AiConvContact,
  AiConvDataField,
  AiConvFilterTab,
  AiConvListItemData,
  AiConvMessage,
  AiConvMode,
  AiConvStatus,
} from "./types";
import type { AiConvEmailPayload } from "./thread";
import { ConversationList } from "./list";
import { ChatThread } from "./thread";
import { LeadInfoPanel } from "./lead-panel";

// Re-export everything so consumers import from the one public path.
export * from "./types";
export * from "./list";
export * from "./bubble";
export * from "./thread";
export * from "./lead-panel";

// ---------------------------------------------------------------------------
// ConversationsPage
// ---------------------------------------------------------------------------

export interface ConversationsPageProps {
  conversations: AiConvListItemData[];
  activeConversationId?: string;
  /** Contact for the currently-selected conversation. */
  contact?: AiConvContact;
  status?: AiConvStatus;
  mode?: AiConvMode;
  messages?: AiConvMessage[];
  aiFields?: AiConvDataField[];
  appointment?: AiConvAppointmentData;
  /** When the lead first contacted via the chatbot. */
  leadFirstSeen?: string;
  /** Traffic source label (e.g. "Website Chatbot"). */
  leadSource?: string;
  /** Conversation topic tag — e.g. "Buy a Home", "Refinance", "Investment". */
  leadTopic?: string;
  searchQuery?: string;
  activeFilter?: AiConvFilterTab;
  /** Filter conversation list by channel type. */
  channelFilter?: AiConvChannelFilter;
  /** Active reply channel — "chat" (default) or "email". */
  channel?: AiConvChannel;
  onChannelChange?: (channel: AiConvChannel) => void;
  /** When true, the Email tab is shown in the composer. Defaults to false. */
  isEmailIntegrated?: boolean;
  inputValue?: string;
  internalNotes?: string;
  showLeadPanel?: boolean;
  hasMore?: boolean;
  isLoadingMore?: boolean;
  /** True when older messages can be loaded for the active conversation. */
  hasMoreMessages?: boolean;
  /** True while a `onLoadMoreMessages` request is in-flight. */
  isLoadingMoreMessages?: boolean;
  /** Fired when the consumer should fetch older messages for the active conversation. */
  onLoadMoreMessages?: () => void;
  onSelectConversation?: (id: string) => void;
  onRead?: (id: string) => void;
  onSearchChange?: (v: string) => void;
  onFilterChange?: (f: AiConvFilterTab) => void;
  onChannelFilterChange?: (f: AiConvChannelFilter) => void;
  onInputChange?: (v: string) => void;
  /** Fired when the user sends a chat message. */
  onSend?: (content: string) => void;
  /** Fired when the user sends an email. */
  onSendEmail?: (payload: AiConvEmailPayload) => void;
  onTakeOver?: () => void;
  onLetAiHandle?: () => void;
  /** Called when the user selects files via the attachment button in the composer. */
  onAttachFile?: (files: FileList) => void;
  /** Called when the user selects images via the image upload button in the composer. */
  onAttachImage?: (files: FileList) => void;
  /** Pre-fills the email Subject field with "Re: [emailReplySubject]" for reply threads. */
  emailReplySubject?: string;
  onReopen?: () => void;
  onMarkUrgent?: () => void;
  onUnmarkUrgent?: () => void;
  onArchive?: () => void;
  onAssignToAdvisor?: () => void;
  /** True when this lead is already a client in the system. Disables Add to Clients. */
  isKnownContact?: boolean;
  onAddToContacts?: () => void;
  onCreateOpportunity?: () => void;
  onBookAppointment?: () => void;
  onApproveAppointment?: () => void;
  onDeclineAppointment?: () => void;
  onRescheduleAppointment?: (contactId: string) => void;
  onNotesChange?: (v: string) => void;
  onToggleLeadPanel?: () => void;
  onLoadMore?: () => void;
  isAiTyping?: boolean;
  notesSaveStatus?: "idle" | "saving" | "saved";
  className?: string;
}

export function ConversationsPage({
  conversations,
  activeConversationId,
  contact,
  status = "ai-active",
  mode = "ai",
  messages = [],
  aiFields = [],
  appointment,
  leadFirstSeen,
  leadSource,
  leadTopic,
  searchQuery,
  activeFilter,
  channelFilter,
  onChannelFilterChange,
  channel,
  onChannelChange,
  isEmailIntegrated,
  inputValue,
  internalNotes,
  showLeadPanel = true,
  hasMore,
  isLoadingMore,
  hasMoreMessages,
  isLoadingMoreMessages,
  onLoadMoreMessages,
  isAiTyping,
  notesSaveStatus,
  onSelectConversation,
  onRead,
  onSearchChange,
  onFilterChange,
  onInputChange,
  onSend,
  onSendEmail,
  onTakeOver,
  onLetAiHandle,
  onAttachFile,
  onAttachImage,
  emailReplySubject,
  onReopen,
  onMarkUrgent,
  onUnmarkUrgent,
  onArchive,
  onAssignToAdvisor,
  isKnownContact,
  onAddToContacts,
  onCreateOpportunity,
  onBookAppointment,
  onApproveAppointment,
  onDeclineAppointment,
  onRescheduleAppointment,
  onNotesChange,
  onToggleLeadPanel,
  onLoadMore,
  className,
}: ConversationsPageProps) {
  const [mobilePanel, setMobilePanel] = useState<"list" | "chat" | "lead">(
    "list",
  );

  const handleSelectConversation = (id: string) => {
    onSelectConversation?.(id);
    setMobilePanel("chat");
  };

  const handleToggleLeadPanel = () => {
    onToggleLeadPanel?.();
    setMobilePanel(showLeadPanel ? "chat" : "lead");
  };

  return (
    <TooltipProvider>
      <div
        className={cn("flex h-full overflow-hidden bg-background", className)}
      >
        {/* Left — Conversation List */}
        <ConversationList
          conversations={conversations}
          activeId={activeConversationId}
          searchQuery={searchQuery}
          activeFilter={activeFilter}
          channelFilter={channelFilter}
          hasMore={hasMore}
          isLoadingMore={isLoadingMore}
          onSearchChange={onSearchChange}
          onFilterChange={onFilterChange}
          onChannelFilterChange={onChannelFilterChange}
          onSelect={handleSelectConversation}
          onRead={onRead}
          onLoadMore={onLoadMore}
          className={cn(
            "shrink-0 md:w-[320px]",
            mobilePanel === "list" ? "flex w-full md:flex" : "hidden md:flex",
          )}
        />

        {/* Center — Chat Thread */}
        {contact ? (
          <ChatThread
            key={contact.id}
            contact={contact}
            status={status}
            mode={mode}
            messages={messages}
            isAiTyping={isAiTyping}
            channel={channel}
            onChannelChange={onChannelChange}
            isEmailIntegrated={isEmailIntegrated}
            inputValue={inputValue}
            onInputChange={onInputChange}
            onSend={onSend}
            onSendEmail={onSendEmail}
            onTakeOver={onTakeOver}
            onLetAiHandle={onLetAiHandle}
            onAttachFile={onAttachFile}
            onAttachImage={onAttachImage}
            emailReplySubject={emailReplySubject}
            onReopen={onReopen}
            onMarkUrgent={onMarkUrgent}
            onUnmarkUrgent={onUnmarkUrgent}
            onArchive={onArchive}
            onAssignToAdvisor={onAssignToAdvisor}
            hasMoreMessages={hasMoreMessages}
            isLoadingMoreMessages={isLoadingMoreMessages}
            onLoadMoreMessages={onLoadMoreMessages}
            onBack={() => setMobilePanel("list")}
            onShowLeadInfo={() => setMobilePanel("lead")}
            className={cn(
              "min-w-0 flex-1 border-r border-border",
              mobilePanel === "chat"
                ? "flex flex-col md:flex"
                : "hidden md:flex",
            )}
          />
        ) : (
          <div
            className={cn(
              "min-w-0 flex-1 items-center justify-center border-r border-border bg-muted/10",
              mobilePanel === "chat" ? "flex md:flex" : "hidden md:flex",
            )}
          >
            <div className="flex flex-col items-center gap-2 text-muted-foreground">
              <MessageSquare className="size-10 opacity-30" />
              <p className="text-sm">Select a conversation</p>
            </div>
          </div>
        )}

        {/* Right — Lead Info Panel */}
        {contact && (
          <>
            <div
              className={cn(
                mobilePanel === "lead"
                  ? "flex w-full shrink-0 flex-col"
                  : "hidden",
                "md:block md:shrink-0 md:overflow-hidden md:transition-[width] md:duration-200 md:ease-in-out",
                showLeadPanel ? "md:w-[320px]" : "md:w-0",
              )}
            >
              <LeadInfoPanel
                contact={contact}
                firstSeen={leadFirstSeen}
                source={leadSource}
                topic={leadTopic}
                aiFields={aiFields}
                appointment={appointment}
                internalNotes={internalNotes}
                notesSaveStatus={notesSaveStatus}
                isKnownContact={isKnownContact}
                onAddToContacts={onAddToContacts}
                onCreateOpportunity={onCreateOpportunity}
                onBookAppointment={onBookAppointment}
                onApproveAppointment={onApproveAppointment}
                onDeclineAppointment={onDeclineAppointment}
                onRescheduleAppointment={onRescheduleAppointment}
                onNotesChange={onNotesChange}
                onToggleCollapse={handleToggleLeadPanel}
                onBack={() => setMobilePanel("chat")}
                className="flex h-full w-full flex-col border-l border-border md:w-[320px]"
              />
            </div>

            {!showLeadPanel && onToggleLeadPanel && (
              <div className="hidden shrink-0 items-start border-l border-border pt-[29px] md:flex">
                <Tooltip>
                  <TooltipTrigger
                    render={
                      <Button
                        variant="ghost"
                        size="icon"
                        className="size-8"
                        aria-label="Show lead info"
                        onClick={handleToggleLeadPanel}
                      >
                        <ChevronLeft className="size-4" />
                      </Button>
                    }
                  />
                  <TooltipContent>Show lead info</TooltipContent>
                </Tooltip>
              </div>
            )}
          </>
        )}
      </div>
    </TooltipProvider>
  );
}

// ---------------------------------------------------------------------------
// AiConvAssignAdvisorDialog
// ---------------------------------------------------------------------------

export interface AiConvAssignAdvisorDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  advisors: AiConvAdvisor[];
  /** Currently selected advisor id */
  value: string;
  onValueChange: (id: string) => void;
  onConfirm: () => void;
}

export function AiConvAssignAdvisorDialog({
  open,
  onOpenChange,
  advisors,
  value,
  onValueChange,
  onConfirm,
}: AiConvAssignAdvisorDialogProps) {
  const [search, setSearch] = useState("");
  const [roleFilter, setRoleFilter] = useState("");

  const roles = Array.from(
    new Set(advisors.map((a) => a.role).filter(Boolean)),
  ) as string[];

  const filtered = advisors.filter(
    (a) =>
      a.name.toLowerCase().includes(search.toLowerCase()) &&
      (!roleFilter || a.role === roleFilter),
  );

  const handleOpenChange = (v: boolean) => {
    onOpenChange(v);
    if (!v) {
      setSearch("");
      setRoleFilter("");
    }
  };

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Assign to advisor</DialogTitle>
          <DialogDescription>
            Choose an advisor to handle this conversation.
          </DialogDescription>
        </DialogHeader>
        <div className="flex flex-col gap-0">
          {roles.length > 0 && (
            <div className="pb-3">
              <ToggleGroup
                type="single"
                variant="outline"
                spacing={1.5}
                size="sm"
                value={roleFilter ? [roleFilter] : ["__all__"]}
                onValueChange={(values) => {
                  const v = values[0];
                  setRoleFilter(!v || v === "__all__" ? "" : v);
                }}
              >
                <ToggleGroupItem value="__all__">All</ToggleGroupItem>
                {roles.map((role) => (
                  <ToggleGroupItem key={role} value={role}>
                    {role}
                  </ToggleGroupItem>
                ))}
              </ToggleGroup>
            </div>
          )}
          <div className="flex items-center gap-2 border border-input px-3">
            <Search className="size-4 shrink-0 text-muted-foreground" />
            <input
              type="text"
              placeholder="Search advisors..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="h-9 w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground"
            />
          </div>
          <div className="max-h-52 overflow-y-auto border border-t-0 border-input">
            {filtered.length === 0 ? (
              <p className="py-6 text-center text-sm text-muted-foreground">
                No advisors found.
              </p>
            ) : (
              filtered.map((advisor) => (
                <button
                  key={advisor.id}
                  type="button"
                  onClick={() => onValueChange(advisor.id)}
                  className={cn(
                    "flex w-full items-center gap-3 px-3 py-2.5 text-left text-sm transition-colors hover:bg-muted",
                    value === advisor.id && "bg-muted font-medium",
                  )}
                >
                  <Avatar size="sm">
                    <AvatarFallback className="font-semibold">
                      {advisor.initials}
                    </AvatarFallback>
                  </Avatar>
                  <div className="min-w-0 flex-1">
                    <p className="truncate text-sm">{advisor.name}</p>
                    {advisor.role && (
                      <p className="truncate text-xs text-muted-foreground">
                        {advisor.role}
                      </p>
                    )}
                  </div>
                </button>
              ))
            )}
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button onClick={onConfirm}>Assign</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
