"use client"

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react"
import { PanelLeftCloseIcon, ServerIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet"
import {
  ALL_SERVERS_ID,
  ServerTileRail,
  hostnameOf,
  type ServerTileItem,
} from "@/components/server-tile-rail"
import { cn } from "@/lib/utils"

/** Preview: https://reui.io/preview/base/app-shell-12 · https://reui.io/preview/base/list-9 */

const STORAGE_KEY = "mm:server-rail-collapsed"
const DESKTOP_MQ = "(min-width: 768px)"

function readCollapsed(): boolean {
  try {
    return window.localStorage.getItem(STORAGE_KEY) === "1"
  } catch {
    return false
  }
}

function writeCollapsed(value: boolean) {
  try {
    window.localStorage.setItem(STORAGE_KEY, value ? "1" : "0")
  } catch {
    // quota / private mode
  }
}

interface ServerRailContextValue {
  openRail: () => void
  expandRail: () => void
  collapsed: boolean
  selectedLabel: string
}

const ServerRailContext = createContext<ServerRailContextValue | null>(null)

function useServerRail() {
  const ctx = useContext(ServerRailContext)
  if (!ctx) {
    throw new Error("ServerRailMobileButton must be used inside ServerRailLayout")
  }
  return ctx
}

function ServerRailMobileButton() {
  const { openRail, expandRail, collapsed, selectedLabel } = useServerRail()
  return (
    <Button
      size="sm"
      variant="outline"
      className={collapsed ? undefined : "md:hidden"}
      aria-label={collapsed ? "Показать список серверов" : "Серверы"}
      onClick={() => {
        if (window.matchMedia(DESKTOP_MQ).matches) {
          expandRail()
          return
        }
        openRail()
      }}
    >
      <ServerIcon data-icon="inline-start" />
      {selectedLabel}
    </Button>
  )
}

function ServerRailLayout({
  items,
  selectedId,
  onSelect,
  showAll = true,
  allCount = 0,
  showCount = true,
  showType = true,
  headerRight,
  loading = false,
  extra,
  header,
  banner,
  contentClassName,
  children,
}: {
  items: ServerTileItem[]
  selectedId: string
  onSelect: (id: string) => void
  showAll?: boolean
  allCount?: number
  showCount?: boolean
  showType?: boolean
  headerRight?: ReactNode
  loading?: boolean
  extra?: ReactNode
  header?: ReactNode
  banner?: ReactNode
  contentClassName?: string
  children: ReactNode
}) {
  const [railOpen, setRailOpen] = useState(false)
  const [collapsed, setCollapsed] = useState(false)
  const [hydrated, setHydrated] = useState(false)

  useEffect(() => {
    setCollapsed(readCollapsed())
    setHydrated(true)
  }, [])

  useEffect(() => {
    if (!hydrated) return
    writeCollapsed(collapsed)
  }, [collapsed, hydrated])

  const handleSelect = useCallback(
    (id: string) => {
      onSelect(id)
      setRailOpen(false)
    },
    [onSelect],
  )

  const expandRail = useCallback(() => {
    setCollapsed(false)
  }, [])

  const selectedLabel = useMemo(() => {
    if (showAll && selectedId === ALL_SERVERS_ID) return "Все серверы"
    const item = items.find((entry) => entry.id === selectedId)
    return item ? hostnameOf(item) : "Сервер"
  }, [items, selectedId, showAll])

  const ctx = useMemo<ServerRailContextValue>(
    () => ({
      openRail: () => setRailOpen(true),
      expandRail,
      collapsed,
      selectedLabel,
    }),
    [collapsed, expandRail, selectedLabel],
  )

  const railHeaderRight = (
    <>
      {headerRight}
      <Button
        type="button"
        variant="ghost"
        size="icon-sm"
        className="hidden md:inline-flex"
        aria-label="Свернуть список серверов"
        onClick={() => setCollapsed(true)}
      >
        <PanelLeftCloseIcon />
      </Button>
    </>
  )

  const rail = (
    <ServerTileRail
      items={items}
      selectedId={selectedId}
      onSelect={handleSelect}
      showAll={showAll}
      allCount={allCount}
      showCount={showCount}
      showType={showType}
      headerRight={railHeaderRight}
      loading={loading}
      className="min-h-0 flex-1"
    />
  )

  return (
    <ServerRailContext.Provider value={ctx}>
      <div className="flex h-full min-h-0 flex-col">
        {header}
        {banner}
        <div className="flex min-h-0 flex-1">
          {!collapsed ? (
            <aside className="hidden min-h-0 w-60 shrink-0 flex-col gap-3 p-3 pr-0 md:flex">
              {rail}
              {extra}
            </aside>
          ) : null}
          <div className={cn("min-w-0 flex-1 overflow-y-auto p-4 md:p-6", contentClassName)}>
            {children}
          </div>
        </div>
        <Sheet open={railOpen} onOpenChange={setRailOpen}>
          <SheetContent side="left" className="flex w-72 flex-col gap-3 p-3" showCloseButton>
            <SheetHeader className="px-1 pt-1">
              <SheetTitle>Серверы</SheetTitle>
            </SheetHeader>
            <div className="flex min-h-0 flex-1 flex-col gap-3">
              <ServerTileRail
                items={items}
                selectedId={selectedId}
                onSelect={handleSelect}
                showAll={showAll}
                allCount={allCount}
                showCount={showCount}
                showType={showType}
                showHeader={false}
                headerRight={headerRight}
                loading={loading}
                className="min-h-0 flex-1"
              />
              {extra}
            </div>
          </SheetContent>
        </Sheet>
      </div>
    </ServerRailContext.Provider>
  )
}

export { ServerRailLayout, ServerRailMobileButton }
