import * as React from "react";
import { PanelRight } from "lucide-react";
import { cn } from "@/lib/utils";
import { formatCurrentMonthYear } from "@/lib/format-date";
import { Button } from "@/components/ui/button";
import { PageTopBar } from "@/components/ui/page-top-bar";
import { PolicyAIPanel } from "./policy-ai-panel";
import { PolicyAIHistoryPanel } from "./policy-ai-history-panel";
import { PolicyAIContextSidebar } from "./policy-ai-context-sidebar";
import type {
  PolicyAIMessage,
  PolicyConversationItem,
  PolicyQueryContext,
} from "./policy-ai-primitives";

// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------

export interface PolicyAIPageProps {
  // ── Chat area (pass-through to PolicyAIPanel inline) ──
  messages?: PolicyAIMessage[];
  suggestedQuestions?: Record<string, string[]>;
  isStreaming?: boolean;
  isLoading?: boolean;
  thinkingSteps?: string[];
  onSendMessage?: (text: string) => void;
  onAttachFile?: (files: FileList) => void;
  onAttachImage?: (files: FileList) => void;
  onReset?: () => void;
  /** 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 user scrolls near the top of the chat — fetch older messages. */
  onLoadMoreMessages?: () => void;

  // ── History panel (left) ──
  conversations?: PolicyConversationItem[];
  activeConversationId?: string;
  onSelectConversation?: (id: string) => void;
  onNewChat?: () => void;
  /** Whether more conversations can be loaded (cursor pagination). */
  hasMoreConversations?: boolean;
  /** Load the next page of conversations. */
  onLoadMoreConversations?: () => void;
  /** Whether a conversations load-more request is in flight. */
  isLoadingMoreConversations?: boolean;
  /**
   * Notified when the history search query changes. Use to drive a server-side
   * search (the panel always also filters the current list client-side).
   */
  onSearchConversations?: (query: string) => void;

  // ── Context sidebar (right) ──
  /**
   * Whether the context panel starts visible.
   * Renamed from `showContextPanel` to make uncontrolled semantics explicit —
   * the toggle button owns the state after mount.
   */
  defaultShowContextPanel?: boolean;
  bankCount?: number;
  categoryCount?: number;
  lastUpdated?: string;
  /**
   * Suggested follow-up questions (e.g. backend-generated). When provided, these
   * override the built-in `deriveFollowUps` heuristic; falls back to it when omitted.
   */
  suggestedFollowUps?: string[];
  /** Opens the Support Agent panel — wired to PageTopBar "Ask Support" button. */
  onAskSupport?: () => void;

  className?: string;
}

// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------

/** Derives suggested follow-up questions from the last assistant message's query context. */
function deriveFollowUps(context: PolicyQueryContext | undefined): string[] {
  if (!context) return [];

  const { queryType, policyType, bankName } = context;

  if (queryType === "cross_bank_comparison") {
    return [
      `Which of these banks is best overall for ${context.categories[0] ?? policyType}?`,
      bankName
        ? `Does ${bankName} have any exceptions?`
        : "Which bank has the most flexible policy?",
      "Show me the ranked list of lenders.",
    ];
  }
  if (queryType === "ranking") {
    return [
      `What are the full details for the #1 ranked bank?`,
      `Which banks in the list accept cases under 80% LVR?`,
      `Compare the top 3 banks side by side.`,
    ];
  }
  if (queryType === "single_bank") {
    return [
      `How does ${bankName ?? "this bank"} compare to other lenders?`,
      `What documentation does ${bankName ?? "this bank"} require?`,
      `Which banks have a better policy than ${bankName ?? "this bank"}?`,
    ];
  }
  if (queryType === "threshold_filter") {
    return [
      `What is the maximum LVR across all filtered banks?`,
      `Are any of these banks on a specialist product?`,
      `Rank the filtered banks best to worst.`,
    ];
  }
  return [];
}

// ---------------------------------------------------------------------------
// PolicyAIPage (Template)
// ---------------------------------------------------------------------------

/**
 * Dedicated full-page layout for the Policy AI feature.
 *
 * 3-panel layout modelled on the AI Conversations page:
 * - **Left** (260px): `PolicyAIHistoryPanel` — recent conversations + search
 * - **Center** (flex-1): `PolicyAIPanel` in inline mode — chat + response cards
 * - **Right** (280px, toggle-able): `PolicyAIContextSidebar` — coverage stats +
 *   last query context + suggested follow-ups
 *
 * @example
 * <PolicyAIPage
 *   messages={messages}
 *   conversations={conversations}
 *   activeConversationId={activeId}
 *   onSendMessage={handleSend}
 *   onSelectConversation={setActiveId}
 *   onNewChat={handleNewChat}
 * />
 */
export function PolicyAIPage({
  // Chat
  messages = [],
  suggestedQuestions,
  isStreaming = false,
  isLoading = false,
  thinkingSteps,
  onSendMessage,
  onAttachFile,
  onAttachImage,
  onReset,
  hasMoreMessages,
  isLoadingMoreMessages,
  onLoadMoreMessages,
  // History
  conversations = [],
  activeConversationId,
  onSelectConversation,
  onNewChat,
  hasMoreConversations = false,
  onLoadMoreConversations,
  isLoadingMoreConversations = false,
  onSearchConversations,
  // Context
  defaultShowContextPanel = true,
  bankCount = 0,
  categoryCount = 0,
  lastUpdated = formatCurrentMonthYear(),
  suggestedFollowUps,
  onAskSupport,
  className,
}: PolicyAIPageProps) {
  const [showContextPanel, setShowContextPanel] = React.useState(
    defaultShowContextPanel,
  );
  const [historySearch, setHistorySearch] = React.useState("");

  // Walk backwards to find the most recent assistant message that carries a
  // queryContext. This keeps the sidebar populated while a new (streaming)
  // reply is pending — the in-flight message won't carry a queryContext yet.
  // Single-pass: no intermediate array allocation.
  const lastQueryContext = React.useMemo(() => {
    for (let i = messages.length - 1; i >= 0; i--) {
      const m = messages[i];
      if (m.role === "assistant" && m.queryContext) return m.queryContext;
    }
    return undefined;
  }, [messages]);

  // Prefer caller-supplied (e.g. backend-generated) follow-ups; otherwise derive
  // from the last query context. deriveFollowUps is cheap — no useMemo needed.
  const followUps = suggestedFollowUps ?? deriveFollowUps(lastQueryContext);

  const handleNewChat = () => {
    onReset?.();
    onNewChat?.();
  };

  // Derive once — used for both aria-label and title on the toggle button.
  const panelToggleLabel = showContextPanel
    ? "Hide context panel"
    : "Show context panel";

  return (
    <div
      data-slot="policy-ai-page"
      className={cn("flex flex-col h-full bg-background", className)}
    >
      {/* ── Page header — uses shared PageTopBar (same as Loan CRM, Contact, etc.) ── */}
      <PageTopBar
        title="Policy AI"
        actions={
          <Button
            variant="ghost"
            size="icon-sm"
            onClick={() => setShowContextPanel((v) => !v)}
            aria-label={panelToggleLabel}
            aria-pressed={showContextPanel}
            title={panelToggleLabel}
          >
            <PanelRight className="size-4" aria-hidden="true" />
          </Button>
        }
        onAskSupport={onAskSupport}
      />

      {/* ── 3-panel body ── */}
      <div className="flex flex-1 min-h-0 overflow-hidden">
        {/* Left — conversation history */}
        <PolicyAIHistoryPanel
          conversations={conversations}
          activeId={activeConversationId}
          onSelect={onSelectConversation}
          onNewChat={handleNewChat}
          searchQuery={historySearch}
          onSearchChange={(q) => {
            setHistorySearch(q);
            onSearchConversations?.(q);
          }}
          hasMore={hasMoreConversations}
          onLoadMore={onLoadMoreConversations}
          isLoadingMore={isLoadingMoreConversations}
          className="w-[260px]"
        />

        {/* Center — chat area (PolicyAIPanel inline).
            min-h-0 lets it shrink inside the flex row; the panel owns its
            own overflow-y-auto so the footer stays pinned at the bottom. */}
        <div className="flex-1 flex flex-col min-w-0 min-h-0">
          <PolicyAIPanel
            inline
            messages={messages}
            suggestedQuestions={suggestedQuestions}
            isStreaming={isStreaming}
            isLoading={isLoading}
            thinkingSteps={thinkingSteps}
            onSendMessage={onSendMessage}
            onAttachFile={onAttachFile}
            onAttachImage={onAttachImage}
            onReset={onReset}
            hasMoreMessages={hasMoreMessages}
            isLoadingMoreMessages={isLoadingMoreMessages}
            onLoadMoreMessages={onLoadMoreMessages}
            className="flex-1 min-h-0"
          />
        </div>

        {/* Right — context sidebar: only shown once a conversation is active */}
        {showContextPanel && messages.length > 0 && (
          <PolicyAIContextSidebar
            lastQueryContext={lastQueryContext}
            suggestedFollowUps={followUps}
            onFollowUpClick={onSendMessage}
            bankCount={bankCount}
            categoryCount={categoryCount}
            lastUpdated={lastUpdated}
            className="w-[280px]"
          />
        )}
      </div>
    </div>
  );
}
