import { Tooltip } from "@novaclaw/ui/tooltip"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import {
  children,
  createEffect,
  createMemo,
  createSignal,
  type JSXElement,
  onMount,
  type ParentProps,
  Show,
} from "solid-js"
import { useLanguage } from "@/context/language"
import { type ServerConnection, serverName } from "@/context/server"
import type { ServerHealth } from "@/utils/server-health"

interface ServerRowProps extends ParentProps {
  conn: ServerConnection.Any
  status?: ServerHealth
  class?: string
  nameClass?: string
  versionClass?: string
  dimmed?: boolean
  badge?: JSXElement
  showCredentials?: boolean
}

export function ServerRow(props: ServerRowProps) {
  const language = useLanguage()
  const [truncated, setTruncated] = createSignal(false)
  let nameRef: HTMLSpanElement | undefined
  let versionRef: HTMLSpanElement | undefined
  const name = createMemo(() => serverName(props.conn))

  const check = () => {
    const nameTruncated = nameRef ? nameRef.scrollWidth > nameRef.clientWidth : false
    const versionTruncated = versionRef ? versionRef.scrollWidth > versionRef.clientWidth : false
    setTruncated(nameTruncated || versionTruncated)
  }

  createEffect(() => {
    name()
    props.conn.http.url
    props.status?.version
    queueMicrotask(check)
  })

  onMount(() => {
    if (typeof ResizeObserver !== "function") return
    createResizeObserver([nameRef, versionRef], check)
    check()
  })

  const tooltipValue = () => (
    <span class="flex items-center gap-2">
      <span>{serverName(props.conn, true)}</span>
      <Show when={props.status?.version}>
        <span class="text-text-invert-weak">v{props.status?.version}</span>
      </Show>
    </span>
  )

  const badge = children(() => props.badge)

  return (
    <Tooltip
      class="flex-1 min-w-0"
      value={tooltipValue()}
      contentStyle={{ "max-width": "none", "white-space": "nowrap" }}
      placement="top-start"
      inactive={!truncated() && !props.conn.displayName}
    >
      <div class={props.class} classList={{ "opacity-50": props.dimmed }}>
        <div class="flex flex-col items-start min-w-0 w-full">
          <div class="flex flex-row items-center gap-2 min-w-0 w-full">
            <span ref={nameRef} class={`${props.nameClass ?? "truncate"} min-w-0`}>
              {name()}
            </span>
            <Show
              when={badge()}
              fallback={
                <Show when={props.status?.version}>
                  <span
                    ref={versionRef}
                    class={`${props.versionClass ?? "text-text-weak text-14-regular truncate"} min-w-0`}
                  >
                    v{props.status?.version}
                  </span>
                </Show>
              }
            >
              {(badge) => badge()}
            </Show>
          </div>
          <Show when={props.showCredentials && props.conn.type === "http" && props.conn}>
            {(conn) => (
              <div class="flex flex-row gap-3">
                <span>
                  {conn().http.username ? (
                    <span class="text-text-weak">{conn().http.username}</span>
                  ) : (
                    <span class="text-text-weaker">{language.t("server.row.noUsername")}</span>
                  )}
                </span>
                {conn().http.password && <span class="text-text-weak">••••••••</span>}
              </div>
            )}
          </Show>
        </div>
        {props.children}
      </div>
    </Tooltip>
  )
}

export function ServerHealthIndicator(props: { health?: ServerHealth }) {
  return (
    <div
      classList={{
        "size-1.5 rounded-full shrink-0 my-[3.5px]": true,
        "bg-icon-success-base": props.health?.healthy === true,
        "bg-icon-critical-base": props.health?.healthy === false,
        "bg-border-weak-base": props.health === undefined,
      }}
    />
  )
}
