import { Show, type Accessor, type Component } from "solid-js"
import type { SessionThread } from "../../../stores/session-state"
import type { Session } from "../../../types/session"
import { keyboardRegistry, type KeyboardShortcut } from "../../../lib/keyboard-registry"
import type { DrawerViewState } from "./types"

import { PlusSquare, Search } from "lucide-solid"
import IconButton from "@suid/material/IconButton"
import MenuOpenIcon from "@suid/icons-material/MenuOpen"
import PushPinIcon from "@suid/icons-material/PushPin"
import PushPinOutlinedIcon from "@suid/icons-material/PushPinOutlined"
import InfoOutlinedIcon from "@suid/icons-material/InfoOutlined"

import SessionList from "../../session-list"
import KeyboardHint from "../../keyboard-hint"
import WorktreeSelector from "../../worktree-selector"
import AgentSelector from "../../agent-selector"
import ModelSelector from "../../model-selector"
import ThinkingSelector from "../../thinking-selector"
import { getLogger } from "../../../lib/logger"

const log = getLogger("session")

interface SessionSidebarProps {
  t: (key: string) => string
  instanceId: string
  threads: Accessor<SessionThread[]>
  activeSessionId: Accessor<string | null>
  activeSession: Accessor<Session | null>

  showSearch: Accessor<boolean>
  onToggleSearch: () => void

  keyboardShortcuts: Accessor<KeyboardShortcut[]>
  isPhoneLayout: Accessor<boolean>
  drawerState: Accessor<DrawerViewState>
  leftPinned: Accessor<boolean>

  onSelectSession: (sessionId: string) => void
  onNewSession: () => Promise<void> | void
  onSidebarAgentChange: (sessionId: string, agent: string) => Promise<void>
  onSidebarModelChange: (sessionId: string, model: { providerId: string; modelId: string }) => Promise<void>
  onPinLeftDrawer: () => void
  onUnpinLeftDrawer: () => void
  onCloseLeftDrawer: () => void

  setContentEl: (el: HTMLElement | null) => void
}

const SessionSidebar: Component<SessionSidebarProps> = (props) => (
    <div class="flex flex-col h-full min-h-0" ref={props.setContentEl}>
      <div class="flex flex-col gap-2 px-4 py-3 border-b border-base">
        <div class="flex items-center justify-between gap-2">
          <span class="session-sidebar-title text-sm font-semibold uppercase text-primary">
            {props.t("instanceShell.leftPanel.sessionsTitle")}
          </span>
          <div class="flex items-center gap-2 text-primary">
            <IconButton
              size="small"
              color="inherit"
              aria-label={props.t("sessionList.actions.newSession.ariaLabel")}
              title={props.t("sessionList.actions.newSession.title")}
              onClick={() => {
                const result = props.onNewSession()
                if (result instanceof Promise) {
                  void result.catch((error) => log.error("Failed to create session:", error))
                }
              }}
            >
              <PlusSquare class="w-5 h-5" />
            </IconButton>
            <IconButton
              size="small"
              color="inherit"
              aria-label={props.t("sessionList.filter.ariaLabel")}
              title={props.t("sessionList.filter.ariaLabel")}
              aria-pressed={props.showSearch()}
              onClick={props.onToggleSearch}
              sx={{
                color: props.showSearch() ? "var(--text-primary)" : "inherit",
                backgroundColor: props.showSearch() ? "var(--surface-hover)" : "transparent",
                "&:hover": {
                  backgroundColor: "var(--surface-hover)",
                },
              }}
            >
              <Search class="w-5 h-5" />
            </IconButton>
            <IconButton
              size="small"
              color="inherit"
              aria-label={props.t("instanceShell.leftPanel.instanceInfo")}
              title={props.t("instanceShell.leftPanel.instanceInfo")}
              onClick={() => props.onSelectSession("info")}
            >
              <InfoOutlinedIcon fontSize="small" />
            </IconButton>
            <Show when={!props.isPhoneLayout()}>
              <IconButton
                size="small"
                color="inherit"
                aria-label={props.leftPinned() ? props.t("instanceShell.leftDrawer.unpin") : props.t("instanceShell.leftDrawer.pin")}
                onClick={() => (props.leftPinned() ? props.onUnpinLeftDrawer() : props.onPinLeftDrawer())}
              >
                {props.leftPinned() ? <PushPinIcon fontSize="small" /> : <PushPinOutlinedIcon fontSize="small" />}
              </IconButton>
            </Show>
            <Show when={props.drawerState() === "floating-open"}>
              <IconButton
                size="small"
                color="inherit"
                aria-label={props.t("instanceShell.leftDrawer.toggle.close")}
                title={props.t("instanceShell.leftDrawer.toggle.close")}
                onClick={props.onCloseLeftDrawer}
              >
                <MenuOpenIcon fontSize="small" />
              </IconButton>
            </Show>
          </div>
        </div>
        <div class="session-sidebar-shortcuts">
          <Show when={props.keyboardShortcuts().length}>
            <KeyboardHint shortcuts={props.keyboardShortcuts()} separator=" " showDescription={false} />
          </Show>
        </div>
      </div>

      <div class="session-sidebar flex flex-col flex-1 min-h-0">
        <SessionList
          instanceId={props.instanceId}
          threads={props.threads()}
          activeSessionId={props.activeSessionId()}
          onSelect={props.onSelectSession}
          onNew={() => {
            const result = props.onNewSession()
            if (result instanceof Promise) {
              void result.catch((error) => log.error("Failed to create session:", error))
            }
          }}
          enableFilterBar={props.showSearch()}
          showHeader={false}
          showFooter={false}
        />

        <div class="session-sidebar-separator" />
        <Show when={props.activeSession()}>
          {(activeSession) => (
            <div class="session-sidebar-controls px-4 py-4 border-t border-base flex flex-col gap-3">
              <WorktreeSelector instanceId={props.instanceId} sessionId={activeSession().id} />

              <AgentSelector
                instanceId={props.instanceId}
                sessionId={activeSession().id}
                currentAgent={activeSession().agent}
                onAgentChange={(agent) => props.onSidebarAgentChange(activeSession().id, agent)}
              />

              <ModelSelector
                instanceId={props.instanceId}
                sessionId={activeSession().id}
                currentModel={activeSession().model}
                onModelChange={(model) => props.onSidebarModelChange(activeSession().id, model)}
              />

              <ThinkingSelector instanceId={props.instanceId} currentModel={activeSession().model} />

              <KeyboardHint
                class="session-sidebar-selector-hints"
                ariaHidden={true}
                shortcuts={[
                  keyboardRegistry.get("open-agent-selector"),
                  keyboardRegistry.get("focus-model"),
                  keyboardRegistry.get("focus-variant"),
                ].filter((shortcut): shortcut is KeyboardShortcut => Boolean(shortcut))}
                separator=" "
                showDescription={false}
              />
            </div>
          )}
        </Show>
      </div>
    </div>
  )

export default SessionSidebar
