import * as React from "react";
import { useState } from "react";
import { ArrowLeft, Mail, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "./button";
import {
  Empty,
  EmptyContent,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
  EmptyDescription,
} from "./empty";
import { ConversationList, ChatThread } from "./ai-conversations";
import type {
  AiConvContact,
  AiConvListItemData,
  AiConvMessage,
  AiConvEmailPayload,
} from "./ai-conversations";

/**
 * OpportunityEmailNotesTab — WealthX DS (Level 5)
 *
 * Content for the "Email & Notes" tab of `OpportunityDetailsDrawer`
 * (financial-drawers.tsx). Scopes the existing Conversations building
 * blocks to a single opportunity's applicant(s) so staff can read and
 * reply to a client's email without leaving the Pipeline board.
 *
 * Gmail-style drill-in layout (chosen for the drawer's width constraints):
 * conversations render as full-width rows (name · subject · snippet ·
 * timestamp); clicking a row swaps the panel to the full-width thread with
 * a back control, `emailOnly` composer (no Chat/Email toggle, no AI
 * hand-off), and email reply fields.
 *
 * Covers Email only — "Notes" is deferred to a follow-up story per the
 * BUILD-2313 refinement (see docs/feature-prep/kanban-client-emails.md).
 *
 * Pass as the `emailAndNotes` slot of `OpportunityDetailsDrawer`.
 */

export interface OpportunityEmailNotesTabProps {
  /** Email conversations tied to this opportunity's applicant(s) (main + co, when joint). */
  conversations: AiConvListItemData[];
  /** Messages for every conversation above, keyed by conversation id. */
  messagesByConversationId: Record<string, AiConvMessage[]>;
  /** When set, opens directly on that thread; otherwise opens on the row list. */
  defaultConversationId?: string;
  /**
   * This opportunity's applicant(s) (main + co, when joint) — independent of
   * `conversations` so a broker can start a first email even when none
   * exist yet. Powers the "New Email" affordance; omit to hide it.
   */
  applicants?: AiConvContact[];
  /** Fired when the advisor sends a reply from an existing thread. */
  onSendEmail?: (conversationId: string, payload: AiConvEmailPayload) => void;
  /** Fired when the advisor sends a brand-new email (no prior conversation). */
  onComposeEmail?: (
    contact: AiConvContact,
    payload: AiConvEmailPayload,
  ) => void;
  className?: string;
}

const PANEL_CLASS =
  "flex h-[calc(100vh_-_5.5rem)] min-h-[440px] border border-border";

export function OpportunityEmailNotesTab({
  conversations,
  messagesByConversationId,
  defaultConversationId,
  applicants,
  onSendEmail,
  onComposeEmail,
  className,
}: OpportunityEmailNotesTabProps) {
  const [selectedId, setSelectedId] = useState<string | null>(
    defaultConversationId ?? null,
  );
  const [pickingRecipient, setPickingRecipient] = useState(false);
  const [composeContact, setComposeContact] = useState<AiConvContact | null>(
    null,
  );

  const canCompose = Boolean(applicants && applicants.length > 0);

  const handleComposeStart = () => {
    if (!applicants || applicants.length === 0) return;
    if (applicants.length === 1) {
      setComposeContact(applicants[0]);
      return;
    }
    setPickingRecipient(true);
  };

  if (composeContact) {
    return (
      <div className={cn(PANEL_CLASS, className)}>
        <ChatThread
          contact={composeContact}
          status="manual"
          hideStatusChip
          mode="manual"
          emailOnly
          messages={[]}
          onSendEmail={(payload) => {
            onComposeEmail?.(composeContact, payload);
            setComposeContact(null);
          }}
          onBack={() => setComposeContact(null)}
          showBackButton
          className="min-w-0 flex-1"
        />
      </div>
    );
  }

  if (pickingRecipient) {
    return (
      <div className={cn(PANEL_CLASS, "flex-col", className)}>
        <div className="flex shrink-0 items-center gap-3 border-b border-border px-4 py-3">
          <Button
            variant="ghost"
            size="icon"
            className="size-8 shrink-0"
            onClick={() => setPickingRecipient(false)}
            aria-label="Back"
          >
            <ArrowLeft className="size-4" />
          </Button>
          <span className="text-label-medium text-foreground">
            New Email — select recipient
          </span>
        </div>
        <div className="flex flex-col overflow-y-auto">
          {applicants?.map((contact) => (
            <button
              key={contact.id}
              type="button"
              onClick={() => {
                setComposeContact(contact);
                setPickingRecipient(false);
              }}
              className="flex flex-col items-start gap-0.5 border-b border-border px-4 py-3 text-left hover:bg-muted/50"
            >
              <span className="text-body-medium text-foreground">
                {contact.name}
              </span>
              {contact.email && (
                <span className="text-caption text-muted-foreground">
                  {contact.email}
                </span>
              )}
            </button>
          ))}
        </div>
      </div>
    );
  }

  if (conversations.length === 0) {
    return (
      <Empty className={cn("border-0 py-20", className)}>
        <EmptyMedia variant="icon">
          <Mail />
        </EmptyMedia>
        <EmptyHeader>
          <EmptyTitle>No emails to this client yet</EmptyTitle>
          <EmptyDescription>
            Email conversations with the applicant(s) on this loan will show up
            here as soon as one starts.
          </EmptyDescription>
        </EmptyHeader>
        {canCompose && (
          <EmptyContent>
            <Button onClick={handleComposeStart}>
              <Plus className="size-3.5" />
              New Email
            </Button>
          </EmptyContent>
        )}
      </Empty>
    );
  }

  const selected = selectedId
    ? conversations.find((c) => c.id === selectedId)
    : undefined;

  if (!selected) {
    return (
      <div className={cn("border border-border", className)}>
        <ConversationList
          conversations={conversations}
          compact
          compactLabel="Client emails"
          itemVariant="row"
          onSelect={setSelectedId}
          onCompose={canCompose ? handleComposeStart : undefined}
          className="w-full border-r-0"
        />
      </div>
    );
  }

  const messages = messagesByConversationId[selected.id] ?? [];

  // The reply composer is its own section pinned at the bottom of the
  // drawer; the email chain scrolls past it. 5.5rem = drawer tab bar +
  // the drawer's p-5 tab-content padding, so the panel's bottom edge
  // lands on the drawer's bottom edge.
  return (
    <div className={cn(PANEL_CLASS, className)}>
      <ChatThread
        contact={selected.contact}
        status={selected.status}
        hideStatusChip
        mode="manual"
        emailOnly
        messages={messages}
        emailReplySubject={messages[messages.length - 1]?.subject}
        hideEmailModeToggle
        onSendEmail={(payload) => onSendEmail?.(selected.id, payload)}
        onBack={() => setSelectedId(null)}
        showBackButton
        className="min-w-0 flex-1"
      />
    </div>
  );
}
