import { createEffect, createMemo, createResource, Show } from "solid-js"
import { A, useNavigate, useParams } from "@solidjs/router"
import { useLayout } from "@/context/layout"
import { useCommand } from "@/context/command"
import { useServer } from "@/context/server"
import { useDialog } from "@opencode-ai/ui/context/dialog"
import { useSync } from "@/context/sync"
import { useGlobalSDK } from "@/context/global-sdk"
import { getFilename } from "@opencode-ai/util/path"
import { base64Decode, base64Encode } from "@opencode-ai/util/encode"
import { iife } from "@opencode-ai/util/iife"
import { Icon } from "@opencode-ai/ui/icon"
import { IconButton } from "@opencode-ai/ui/icon-button"
import { Button } from "@opencode-ai/ui/button"
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
import { Select } from "@opencode-ai/ui/select"
import { Popover } from "@opencode-ai/ui/popover"
import { TextField } from "@opencode-ai/ui/text-field"
import { DialogSelectServer } from "@/components/dialog-select-server"
import { SessionLspIndicator } from "@/components/session-lsp-indicator"
import { SessionMcpIndicator } from "@/components/session-mcp-indicator"
import type { Session } from "@opencode-ai/sdk/v2/client"

export function SessionHeader() {
  const globalSDK = useGlobalSDK()
  const layout = useLayout()
  const params = useParams()
  const navigate = useNavigate()
  const command = useCommand()
  const server = useServer()
  const dialog = useDialog()
  const sync = useSync()

  const projectDirectory = createMemo(() => base64Decode(params.dir ?? ""))

  const sessions = createMemo(() => (sync.data.session ?? []).filter((s) => !s.parentID))
  const currentSession = createMemo(() => sessions().find((s) => s.id === params.id))
  const shareEnabled = createMemo(() => sync.data.config.share !== "disabled")

  function navigateToProject(directory: string) {
    navigate(`/${base64Encode(directory)}`)
  }

  function navigateToSession(session: Session | undefined) {
    if (!session) return
    navigate(`/${params.dir}/session/${session.id}`)
  }

  return (
    <header class="h-12 shrink-0 bg-background-base border-b border-border-weak-base flex">
      <button
        type="button"
        class="xl:hidden w-12 shrink-0 flex items-center justify-center border-r border-border-weak-base hover:bg-surface-raised-base-hover active:bg-surface-raised-base-active transition-colors"
        onClick={layout.mobileSidebar.toggle}
      >
        <Icon name="menu" size="small" />
      </button>
      <div class="px-4 flex items-center justify-between gap-4 w-full">
        <div class="flex items-center gap-3 min-w-0">
          <div class="flex items-center gap-2 min-w-0">
            <div class="hidden xl:flex items-center gap-2">
              <Select
                options={layout.projects.list().map((project) => project.worktree)}
                current={sync.project?.worktree ?? projectDirectory()}
                label={(x) => getFilename(x)}
                onSelect={(x) => (x ? navigateToProject(x) : undefined)}
                class="text-14-regular text-text-base"
                variant="ghost"
              >
                {/* @ts-ignore */}
                {(i) => (
                  <div class="flex items-center gap-2">
                    <Icon name="folder" size="small" />
                    <div class="text-text-strong">{getFilename(i)}</div>
                  </div>
                )}
              </Select>
              <div class="text-text-weaker">/</div>
            </div>
            <Select
              options={sessions()}
              current={currentSession()}
              placeholder="New session"
              label={(x) => x.title}
              value={(x) => x.id}
              onSelect={navigateToSession}
              class="text-14-regular text-text-base max-w-[calc(100vw-180px)] md:max-w-md"
              variant="ghost"
            />
          </div>
          <Show when={currentSession()}>
            <TooltipKeybind class="hidden xl:block" title="New session" keybind={command.keybind("session.new")}>
              <IconButton as={A} href={`/${params.dir}/session`} icon="edit-small-2" variant="ghost" />
            </TooltipKeybind>
          </Show>
        </div>
        <div class="flex items-center gap-3">
          <div class="hidden md:flex items-center gap-1">
            <Button
              size="small"
              variant="ghost"
              onClick={() => {
                dialog.show(() => <DialogSelectServer />)
              }}
            >
              <div
                classList={{
                  "size-1.5 rounded-full": true,
                  "bg-icon-success-base": server.healthy() === true,
                  "bg-icon-critical-base": server.healthy() === false,
                  "bg-border-weak-base": server.healthy() === undefined,
                }}
              />
              <Icon name="server" size="small" class="text-icon-weak" />
              <span class="text-12-regular text-text-weak truncate max-w-[200px]">{server.name}</span>
            </Button>
            <SessionLspIndicator />
            <SessionMcpIndicator />
          </div>
          <div class="flex items-center gap-1">
            <Show when={currentSession()?.summary?.files}>
              <TooltipKeybind
                class="hidden md:block shrink-0"
                title="Toggle review"
                keybind={command.keybind("review.toggle")}
              >
                <Button variant="ghost" class="group/review-toggle size-6 p-0" onClick={layout.review.toggle}>
                  <div class="relative flex items-center justify-center size-4 [&>*]:absolute [&>*]:inset-0">
                    <Icon
                      name={layout.review.opened() ? "layout-right" : "layout-left"}
                      size="small"
                      class="group-hover/review-toggle:hidden"
                    />
                    <Icon
                      name={layout.review.opened() ? "layout-right-partial" : "layout-left-partial"}
                      size="small"
                      class="hidden group-hover/review-toggle:inline-block"
                    />
                    <Icon
                      name={layout.review.opened() ? "layout-right-full" : "layout-left-full"}
                      size="small"
                      class="hidden group-active/review-toggle:inline-block"
                    />
                  </div>
                </Button>
              </TooltipKeybind>
            </Show>
            <TooltipKeybind
              class="hidden md:block shrink-0"
              title="Toggle terminal"
              keybind={command.keybind("terminal.toggle")}
            >
              <Button variant="ghost" class="group/terminal-toggle size-6 p-0" onClick={layout.terminal.toggle}>
                <div class="relative flex items-center justify-center size-4 [&>*]:absolute [&>*]:inset-0">
                  <Icon
                    size="small"
                    name={layout.terminal.opened() ? "layout-bottom-full" : "layout-bottom"}
                    class="group-hover/terminal-toggle:hidden"
                  />
                  <Icon
                    size="small"
                    name="layout-bottom-partial"
                    class="hidden group-hover/terminal-toggle:inline-block"
                  />
                  <Icon
                    size="small"
                    name={layout.terminal.opened() ? "layout-bottom" : "layout-bottom-full"}
                    class="hidden group-active/terminal-toggle:inline-block"
                  />
                </div>
              </Button>
            </TooltipKeybind>
          </div>
          <Show when={shareEnabled() && currentSession()}>
            <Popover
              title="Share session"
              trigger={
                <Tooltip class="shrink-0" value="Share session">
                  <IconButton icon="share" variant="ghost" class="" />
                </Tooltip>
              }
            >
              {iife(() => {
                const [url] = createResource(
                  () => currentSession(),
                  async (session) => {
                    if (!session) return
                    let shareURL = session.share?.url
                    if (!shareURL) {
                      shareURL = await globalSDK.client.session
                        .share({ sessionID: session.id, directory: projectDirectory() })
                        .then((r) => r.data?.share?.url)
                        .catch((e) => {
                          console.error("Failed to share session", e)
                          return undefined
                        })
                    }
                    return shareURL
                  },
                )
                return <Show when={url()}>{(url) => <TextField value={url()} readOnly copyable class="w-72" />}</Show>
              })}
            </Popover>
          </Show>
        </div>
      </div>
    </header>
  )
}
