import { useEffect, useRef, useState } from "react";
import { api } from "../api/client";
import type { InboxItemDto } from "../api/types";
import "./richscripts-actions.js";

type Widget = { submit: (text: string) => Promise<boolean>; destroy: () => void };
type Props = { onOpenConversation: (id: number) => void };
declare global {
  interface Window { RichScriptsActions: { mount: (options: Record<string, unknown>) => Widget }; }
}
/** First integration uses registered READ actions and the existing authenticated API.
 * Command mode is explicit: no model calls, no duplicated credentials or write paths. */
export default function InboxActionAssistant({ onOpenConversation }: Props) {
  const host = useRef<HTMLDivElement>(null);
  const widget = useRef<Widget | null>(null);
  const open = useRef(onOpenConversation);
  open.current = onOpenConversation;
  const [results, setResults] = useState<InboxItemDto[]>([]);
  const [searched, setSearched] = useState(false);
  const [feedback, setFeedback] = useState("");
  useEffect(() => {
    let disposed = false;
    const schema = (properties: Record<string, unknown>) => ({ type: "object", properties, required: Object.keys(properties) });
    widget.current = window.RichScriptsActions.mount({
      target: host.current,
      title: "Inbox action assistant",
      subtitle: "Command mode · Real workspace data · Read only · No model calls",
      welcome: 'Try “Show open conversations”, “Show needs human conversations”, “Find Nora”, or “Open conversation 123”. No changes or messages are sent.',
      resolve: async ({ message }: { message: string }) => {
        const text = message.trim();
        const list = text.match(/^(?:show|list) (all|open|resolved|closed|pending|needs human) (?:conversations|chats)$/i);
        if (list) return { action: "find_conversations", arguments: { status: list[1].toLowerCase().replace("closed", "resolved").replace("needs human", "pending"), query: "" } };
        const find = text.match(/^find\s+(.{1,100})$/i);
        if (find) return { action: "find_conversations", arguments: { status: "all", query: find[1].trim() } };
        const thread = text.match(/^open (?:conversation|chat) #?(\d+)$/i);
        if (thread && Number.isSafeInteger(Number(thread[1])) && Number(thread[1]) > 0) return { action: "open_conversation", arguments: { id: Number(thread[1]) } };
        return { message: 'Command mode supports listing conversations, finding a customer, and opening a conversation by number. Resolving, deleting and sending messages are unavailable here.' };
      },
      actions: [
        { name: "find_conversations", readOnly: true, parameters: schema({ status: { type: "string", enum: ["all", "open", "resolved", "pending"] }, query: { type: "string", maxLength: 100 } }), execute: async (args: { status: string; query: string }) => {
          const rows = await api.getInbox({ take: 50, statusFilter: args.status, q: args.query });
          if (disposed) return "Assistant closed.";
          setResults(rows); setSearched(true); setFeedback("");
          return rows.length ? `Showing ${rows.length} matching conversations below (up to 50). Choose a result to open it.` : "No matching conversations in your accessible workspace.";
        } },
        { name: "open_conversation", readOnly: true, parameters: schema({ id: { type: "integer", minimum: 1, maximum: Number.MAX_SAFE_INTEGER } }), execute: async (args: { id: number }) => {
          await api.getConversation(args.id); // Re-check access; never navigate from an unchecked identifier.
          if (!disposed) open.current(args.id);
          return `Opened conversation #${args.id}.`;
        } },
      ],
    });
    return () => { disposed = true; widget.current?.destroy(); widget.current = null; };
  }, []);
  async function ask(text: string) {
    if (!await widget.current?.submit(text)) setFeedback("Wait for the current request, or check the assistant's error message.");
    else setFeedback("");
  }
  return <details className="inbox-action-assistant">
    <summary><strong>Inbox action assistant</strong><span>Search and open conversations with short commands</span></summary>
    <p className="inbox-action-notice">Read-only developer preview using your existing workspace permissions. Command parsing runs locally; no AI provider is called.</p>
    <div ref={host} />
    <div className="inbox-action-examples">
      <button className="btn-action" onClick={() => void ask("Show open conversations")}>Open conversations</button>
      <button className="btn-action" onClick={() => void ask("Show needs human conversations")}>Needs human</button>
      <button className="btn-action" onClick={() => void ask("Show resolved conversations")}>Resolved</button>
    </div>
    {feedback && <p role="status">{feedback}</p>}
    {searched && <section aria-label="Assistant search results"><h3>{results.length ? "Matching conversations" : "No matching conversations"}</h3>
      <div className="inbox-action-results">{results.map(row => <button key={row.ConversationId} onClick={() => void ask(`Open conversation ${row.ConversationId}`)}>
        <strong>{row.ContactName || "Anonymous visitor"} · #{row.ConversationId}</strong><span>{row.Status} · {row.Channel}</span>
      </button>)}</div>
    </section>}
  </details>;
}
