"use client";

// The CRM messenger, now rendered by the shared @insignia/iios-messaging-ui SDK instead of a
// bespoke in-CRM implementation. The CRM only supplies an adapter (transport) + theming; all the
// UI + messaging logic lives in the SDK. Live path = the be-crm data door (CrmMessagingAdapter);
// demo path = the SDK's own MockAdapter.

import { useEffect, useMemo, useState } from "react";
import { useAppShell, useAuth, useQuery } from "@abe-kap/appshell-sdk/react";
import { MessageSocket } from "@insignia/iios-kernel-client";
import { MessagingProvider, Messenger as SdkMessenger, type MessagingAdapter } from "@insignia/iios-messaging-ui";
import { MockAdapter } from "@insignia/iios-messaging-ui/adapters/mock";
import "@insignia/iios-messaging-ui/styles.css";
import { isShellConfigured } from "@/lib/appshell";
import { CrmMessagingAdapter, type DataDoor } from "@/lib/crm-messaging-adapter";
import { PageHead } from "./ui";

interface RealtimeDTO { url: string; audience: string; token?: string }

/** Open the IIOS message socket with the delegated token the BFF mints (crm.messenger.realtime). */
function useRealtimeSocket(): MessageSocket | null {
  const rt = useQuery<RealtimeDTO>("crm.messenger.realtime", {});
  const [socket, setSocket] = useState<MessageSocket | null>(null);
  const url = rt.data?.url;
  const token = rt.data?.token;
  useEffect(() => {
    if (!url || !token) return;
    const s = new MessageSocket({ serviceUrl: url, token, autoConnect: false });
    s.connect();
    setSocket(s);
    return () => {
      s.disconnect();
      setSocket(null);
    };
  }, [url, token]);
  return socket;
}

const SHELL = isShellConfigured();

export function MessengerSdk() {
  return (
    <div className="view">
      <PageHead
        eyebrow="Communication"
        title="Messenger"
        subtitle="Chat with your team and clients — rendered by the messaging SDK"
        icon="send"
      />
      {!SHELL && (
        <div
          style={{
            margin: "0 0 14px",
            padding: "8px 14px",
            borderRadius: 10,
            background: "var(--panel-2)",
            color: "var(--muted)",
            fontSize: 13,
            border: "1px solid var(--border)",
          }}
        >
          Demo mode — running on the SDK&apos;s mock adapter.
        </div>
      )}
      <div className="miu-host">{SHELL ? <LiveHost /> : <DemoHost />}</div>
    </div>
  );
}

// SHELL is a build-time constant, so exactly one of these mounts for the life of the app
// (Rules-of-Hooks safe — the other branch never renders).
function DemoHost() {
  const adapter = useMemo<MessagingAdapter>(() => new MockAdapter(), []);
  return (
    <MessagingProvider adapter={adapter}>
      <SdkMessenger />
    </MessagingProvider>
  );
}

function LiveHost() {
  const { sdk } = useAppShell();
  const { user } = useAuth();
  const socket = useRealtimeSocket();
  // Rebuilds once the socket connects: the first adapter (no socket) polls; the second runs live.
  const adapter = useMemo<MessagingAdapter | null>(
    () => (user?.id ? new CrmMessagingAdapter(sdk as unknown as DataDoor, user.id, socket ?? undefined) : null),
    [sdk, user?.id, socket],
  );
  if (!adapter) return <div className="miu-empty">Loading…</div>;
  return (
    <MessagingProvider adapter={adapter}>
      <SdkMessenger />
    </MessagingProvider>
  );
}
