"use client"

import * as React from "react"
import { toast } from "sonner"

import {
  Example,
  ExampleWrapper,
} from "@/registry/bases/aria/components/example"
import {
  Bubble,
  BubbleContent,
  BubbleGroup,
  BubbleReactions,
} from "@/registry/bases/aria/ui/bubble"
import { Button } from "@/registry/bases/aria/ui/button"
import { Collapsible } from "@/registry/bases/aria/ui/collapsible"
import { Marker, MarkerContent } from "@/registry/bases/aria/ui/marker"
import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"

export default function BubbleExample() {
  return (
    <ExampleWrapper>
      <BubbleSizes />
      <BubbleVariants />
      <BubbleAlignment />
      <BubbleGrouped />
      <BubbleCollapsible />
      <BubbleButtonLinks />
      <BubbleWithReactions />
      <BubbleReactionsButtons />
    </ExampleWrapper>
  )
}

function BubbleVariants() {
  return (
    <Example title="Variants">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Bubble>
          <BubbleContent>
            Default bubbles use the primary color for the active user side of a
            chat.
          </BubbleContent>
        </Bubble>
        <Bubble variant="secondary">
          <BubbleContent>
            Secondary bubbles are the standard neutral surface for assistant and
            conversation content.
          </BubbleContent>
        </Bubble>
        <Bubble variant="muted">
          <BubbleContent>
            Muted bubbles lower the emphasis for quiet system notes or for
            displaying supporting content.
          </BubbleContent>
        </Bubble>
        <Bubble variant="tinted" align="end">
          <BubbleContent>
            Tinted bubbles use a softer primary tint when primary fill is too
            strong.
          </BubbleContent>
        </Bubble>
        <Bubble variant="outline">
          <BubbleContent>
            Outline bubbles can be used to frame message content and give it a
            border.
          </BubbleContent>
        </Bubble>
        <Bubble variant="destructive">
          <BubbleContent>
            Destructive bubbles flag errors or failed actions in a conversation.
          </BubbleContent>
        </Bubble>
        <Bubble variant="ghost">
          <BubbleContent>
            <span className="whitespace-pre-wrap">
              {`Ghost bubbles work for assistant text and other content that should not be framed.

This is perfect for assistant messages that should not have a frame and can take the full width of the container.

Ghost bubbles are full width and can take the full width of the container.
`}
            </span>
          </BubbleContent>
        </Bubble>
      </div>
    </Example>
  )
}

function BubbleSizes() {
  return (
    <Example title="Sizes">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Bubble>
          <BubbleContent>This is a one line bubble.</BubbleContent>
        </Bubble>
        <Bubble>
          <BubbleContent>
            This bubble has multiple lines. It should wrap to the next line and
            you should see a different radius on the corners.
          </BubbleContent>
        </Bubble>
        <Bubble>
          <BubbleContent>
            <p>This bubble has multiple lines.</p>
            <p>
              It should wrap to the next line and you should see a different
              radius on the corners.
            </p>
            <p>Here is some more text to see how it wraps.</p>
          </BubbleContent>
        </Bubble>
      </div>
    </Example>
  )
}

function BubbleGrouped() {
  return (
    <Example title="Grouped">
      <div className="flex w-full max-w-md flex-col gap-8">
        <BubbleGroup>
          <Bubble variant="secondary">
            <BubbleContent>I finished the audit pass.</BubbleContent>
          </Bubble>
          <Bubble variant="secondary">
            <BubbleContent>
              The registry output looks clean, but I found one stale route.
            </BubbleContent>
          </Bubble>
          <Bubble variant="secondary">
            <BubbleContent>Want me to remove it now?</BubbleContent>
          </Bubble>
        </BubbleGroup>
        <BubbleGroup>
          <Bubble variant="tinted" align="end">
            <BubbleContent>Yes, clean that up.</BubbleContent>
          </Bubble>
          <Bubble variant="tinted" align="end">
            <BubbleContent>Then rerun the registry build.</BubbleContent>
          </Bubble>
        </BubbleGroup>
      </div>
    </Example>
  )
}

const text = `The accessibility review found two focus states that were visually too subtle in dark mode.

I checked the dialog, menu, and drawer paths because each one renders focusable controls inside a layered surface.

The dialog and drawer are fine. The menu needs the hover and focus tokens split so keyboard focus stays visible when the pointer is not involved.

I also recommend keeping the change in the style file instead of the primitive so the other themes can choose their own focus treatment later.`

const previewLength = 180

function BubbleCollapsible() {
  const [open, setOpen] = React.useState(false)
  const isLong = text.length > previewLength
  const preview = `${text.slice(0, previewLength)}...`

  return (
    <Example title="Collapsible">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Collapsible isExpanded={open} onExpandedChange={setOpen}>
          <Bubble variant="muted" align="end">
            <BubbleContent className="whitespace-pre-line">
              <div>{open || !isLong ? text : preview}</div>
              {isLong ? (
                <Button
                  slot="trigger"
                  variant="link"
                  className="gap-1 p-0 text-muted-foreground"
                >
                  {open ? "Show less" : "Show more"}
                  <IconPlaceholder
                    lucide="ChevronDownIcon"
                    tabler="IconChevronDown"
                    hugeicons="ArrowDown01Icon"
                    phosphor="CaretDownIcon"
                    remixicon="RiArrowDownSLine"
                    data-icon="inline-end"
                    className="group-data-panel-open/button:rotate-180"
                  />
                </Button>
              ) : null}
            </BubbleContent>
          </Bubble>
        </Collapsible>
        <Bubble variant="ghost">
          <BubbleContent>
            <span className="whitespace-pre-wrap">
              {`Ghost bubbles work for assistant text and other content that should not be framed.

This is perfect for assistant messages that should not have a frame and can take the full width of the container.

Use this for content that needs the whole row.`}
            </span>
          </BubbleContent>
        </Bubble>
      </div>
    </Example>
  )
}

function BubbleWithReactions() {
  return (
    <Example title="Reaction Placement">
      <div className="flex w-full max-w-md flex-col gap-12">
        <Marker variant="separator">
          <MarkerContent>side=bottom align=end</MarkerContent>
        </Marker>
        <Bubble>
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions
            side="bottom"
            align="end"
            role="img"
            aria-label="Reaction: thumbs up"
          >
            <span>👍</span>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="secondary" align="end">
          <BubbleContent>
            A longer message that wraps across lines so the reaction offset is
            easier to inspect.
          </BubbleContent>
          <BubbleReactions
            side="bottom"
            align="start"
            role="img"
            aria-label="Reactions: thumbs up, surprised"
          >
            <span>👍</span>
            <span>😮</span>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="tinted">
          <BubbleContent>
            A longer message that wraps across lines so the reaction offset is
            easier to inspect.
          </BubbleContent>
          <BubbleReactions
            side="bottom"
            align="end"
            role="img"
            aria-label="Reactions: thumbs up, surprised, fire, eyes, and 8 more"
          >
            <span>👍</span>
            <span>😮</span>
            <span>🔥</span>
            <span>👀</span>
            <span>+8</span>
          </BubbleReactions>
        </Bubble>
        <Marker variant="separator">
          <MarkerContent>side=bottom align=start</MarkerContent>
        </Marker>
        <Bubble variant="secondary">
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions
            side="bottom"
            align="start"
            role="img"
            aria-label="Reaction: fire"
          >
            <span>🔥</span>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="secondary">
          <BubbleContent>
            A longer message that wraps across lines so the reaction offset is
            easier to inspect.
          </BubbleContent>
          <BubbleReactions
            side="bottom"
            align="start"
            role="img"
            aria-label="Reactions: thumbs up, surprised, fire, eyes"
          >
            <span>👍</span>
            <span>😮</span>
            <span>🔥</span>
            <span>👀</span>
          </BubbleReactions>
        </Bubble>
        <Marker variant="separator">
          <MarkerContent>side=top align=start</MarkerContent>
        </Marker>
        <Bubble variant="secondary">
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions
            side="top"
            align="start"
            role="img"
            aria-label="Reaction: fire"
          >
            <span>🔥</span>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="secondary">
          <BubbleContent>
            A longer message that wraps across lines so the reaction offset is
            easier to inspect.
          </BubbleContent>
          <BubbleReactions
            side="top"
            align="start"
            role="img"
            aria-label="Reactions: thumbs up, surprised, fire, eyes"
          >
            <span>👍</span>
            <span>😮</span>
            <span>🔥</span>
            <span>👀</span>
          </BubbleReactions>
        </Bubble>
        <Marker variant="separator">
          <MarkerContent>side=bottom align=end</MarkerContent>
        </Marker>
        <Bubble variant="muted">
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions
            side="top"
            align="end"
            role="img"
            aria-label="Reaction: thumbs up"
          >
            <span>👍</span>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="muted">
          <BubbleContent>
            A longer message that wraps across lines so the reaction offset.
          </BubbleContent>
          <BubbleReactions
            side="top"
            align="end"
            role="img"
            aria-label="Reactions: thumbs up, surprised, fire, eyes"
            className="px-1.5 py-0.5"
          >
            <span>👍</span>
            <span>😮</span>
            <span>🔥</span>
            <span>👀</span>
          </BubbleReactions>
        </Bubble>
      </div>
    </Example>
  )
}

function BubbleReactionsButtons() {
  return (
    <Example title="Reactions Buttons">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Bubble>
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions>
            <Button
              variant="outline"
              size="xs"
              onClick={() =>
                toast("You clicked the button in the bubble reaction")
              }
            >
              Button
            </Button>
          </BubbleReactions>
        </Bubble>
        <Bubble align="end">
          <BubbleContent>This is a one line message.</BubbleContent>
          <BubbleReactions align="start">
            <Button
              variant="ghost"
              size="icon-xs"
              onClick={() => toast("Confetti!")}
            >
              🎉
            </Button>
          </BubbleReactions>
        </Bubble>
        <Bubble variant="tinted">
          <BubbleContent>
            We are going to the movies first then dinner. Are you in?
          </BubbleContent>
          <BubbleReactions className="gap-1 bg-background">
            <Button
              variant="secondary"
              size="icon-xs"
              aria-label="Thumbs up"
              onClick={() => toast("You agree!")}
            >
              <IconPlaceholder
                lucide="ThumbsUpIcon"
                tabler="IconThumbUp"
                hugeicons="ThumbsUpIcon"
                phosphor="ThumbsUpIcon"
                remixicon="RiThumbUpLine"
              />
            </Button>
            <Button
              variant="secondary"
              size="icon-xs"
              aria-label="Thumbs down"
              onClick={() => toast("You disagree!")}
            >
              <IconPlaceholder
                lucide="ThumbsDownIcon"
                tabler="IconThumbDown"
                hugeicons="ThumbsDownIcon"
                phosphor="ThumbsDownIcon"
                remixicon="RiThumbDownLine"
              />
            </Button>
          </BubbleReactions>
        </Bubble>
      </div>
    </Example>
  )
}

function BubbleAlignment() {
  return (
    <Example title="Alignment">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Bubble variant="muted">
          <BubbleContent>This bubble is aligned to the start.</BubbleContent>
        </Bubble>
        <Bubble align="end">
          <BubbleContent>This bubble is aligned to the end.</BubbleContent>
        </Bubble>
        <Bubble variant="muted">
          <BubbleContent>
            This multiline bubble is aligned to the start. The corners should
            adjust when the text wraps to show the grouped side of the
            conversation.
          </BubbleContent>
        </Bubble>
        <Bubble align="end">
          <BubbleContent>
            This multiline bubble is aligned to the end. It should sit on the
            opposite side with the matching corner radius for wrapped text.
          </BubbleContent>
        </Bubble>
      </div>
    </Example>
  )
}

const quickReplies = [
  {
    label: "I need help with my account.",
    message: "I need help with my account.",
  },
  {
    label: "I forgot my password.",
    message: "I forgot my password.",
  },
  {
    label:
      "I have another question. I'd like to talk to a human. Can you help me?",
    message: "I have another question.",
  },
]

function BubbleButtonLinks() {
  return (
    <Example title="Button & Links">
      <div className="flex w-full max-w-md flex-col gap-8">
        <Bubble>
          <BubbleContent render={(props) => <a href="#" {...props} />}>
            This bubble is a link.
          </BubbleContent>
        </Bubble>
        <Bubble variant="secondary">
          <BubbleContent
            render={(props) => <button type="button" {...props} />}
          >
            This one is a button you can click.
          </BubbleContent>
        </Bubble>
        <Bubble variant="muted">
          <BubbleContent
            render={(props) => <button type="button" {...props} />}
          >
            You can also do tinted buttons. Even ones that are multilines.
          </BubbleContent>
        </Bubble>
        <Marker variant="separator">
          <MarkerContent>Chat Suggestions</MarkerContent>
        </Marker>
        <Bubble>
          <BubbleContent>How can I help you today?</BubbleContent>
        </Bubble>
        <BubbleGroup>
          {quickReplies.map((reply) => (
            <Bubble key={reply.label} variant="outline" align="end">
              <BubbleContent
                className="border-dashed border-primary"
                render={(props) => (
                  <button
                    type="button"
                    onClick={() => toast(reply.message)}
                    {...props}
                  />
                )}
              >
                {reply.label}
              </BubbleContent>
            </Bubble>
          ))}
        </BubbleGroup>
      </div>
    </Example>
  )
}
