import { SupportAuthorRole, type SupportMessageDto } from "@edr/types";
import { Affix, Indicator, Transition } from "@mantine/core";
import { Headset } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";

import useAuth from "@/hooks/useAuth";

import { SupportPanel } from "./SupportPanel";
import { useSupportUnreadCount } from "./useSupport";
import { useSupportSocket } from "./useSupportSocket";

/**
 * Toast blurb for an inbound reply. A message may carry files and no text at
 * all, which would otherwise toast a bare "Support replied:".
 */
function previewOf(message: SupportMessageDto): string {
  const body = message.body.trim();
  if (body) return body.length > 60 ? `${body.slice(0, 60)}…` : body;
  const count = message.attachments.length;
  return count === 1 ? "sent a file" : `sent ${count} files`;
}

/**
 * Floating customer-support launcher, mounted in the authenticated app shell.
 * Shows an unread badge and opens the chat panel; live pushes keep the badge
 * fresh and toast the customer when the panel is closed.
 */
export function SupportWidget() {
  const { isAuthenticated } = useAuth();
  const [open, setOpen] = useState(false);
  const { data: unread = 0 } = useSupportUnreadCount(isAuthenticated);

  useSupportSocket(isAuthenticated, (event) => {
    // Only the customer-visible side matters here; agent replies arrive as AGENT.
    if (!open && event.message.authorRole === SupportAuthorRole.AGENT) {
      toast(`Support replied: ${previewOf(event.message)}`, { icon: "💬" });
    }
  });

  if (!isAuthenticated) return null;

  return (
    <Affix position={{ bottom: 24, right: 24 }} zIndex={300}>
      <Transition mounted={open} transition="pop-bottom-right" duration={200}>
        {(styles) => (
          <div style={styles} className="mb-3">
            <SupportPanel onClose={() => setOpen(false)} />
          </div>
        )}
      </Transition>

      <Transition mounted={!open} transition="pop" duration={150}>
        {(styles) => (
          <div style={styles} className="flex justify-end">
            <Indicator
              label={unread > 9 ? "9+" : unread}
              size={20}
              offset={8}
              color="red"
              disabled={unread === 0}
              processing
              withBorder
            >
              <button
                type="button"
                aria-label="Open support chat"
                onClick={() => setOpen(true)}
                className="group relative flex cursor-pointer items-center gap-2.5 rounded-full bg-linear-135 from-edr-primary-dark to-edr-primary py-2 pr-2 pl-2 text-white shadow-[0_10px_28px_rgba(13,92,44,0.4)] transition-transform duration-150 hover:-translate-y-0.5 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-edr-primary active:translate-y-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 sm:pr-5"
              >
                {/* Faint breathing ring; the unread badge already pulses, so stand down then. */}
                {unread === 0 && (
                  <span className="pointer-events-none absolute -inset-1 animate-pulse rounded-full ring-2 ring-edr-primary/50 motion-reduce:animate-none" />
                )}

                <span className="relative grid size-[42px] shrink-0 place-items-center rounded-full bg-white/20">
                  <Headset size={22} />
                </span>

                <span className="relative hidden text-left leading-tight sm:block">
                  <span className="block text-sm font-semibold whitespace-nowrap">
                    👋 Need help?
                  </span>
                  <span className="block text-[11px] whitespace-nowrap opacity-85">
                    Chat with our team
                  </span>
                </span>
              </button>
            </Indicator>
          </div>
        )}
      </Transition>
    </Affix>
  );
}

export default SupportWidget;
