import {
  type ReactNode, type RefObject,
} from 'react'
import {
  Palette, PencilSimple, Trash,
} from '@phosphor-icons/react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import type { ViewDefinition, ViewFile } from '../../types'
import { translate, type AppLocale } from '../../lib/i18n'
import { TypeCustomizePopover } from '../TypeCustomizePopover'
import { getContextMenuPositionStyle } from '../contextMenuPosition'
import { useSidebarInlineRenameInput } from './sidebarHooks'

export interface MenuPosition {
  x: number
  y: number
}

export type ViewDefinitionPatchHandler = (filename: string, patch: Partial<ViewDefinition>, rootPath?: string) => void

const VIEW_CONTEXT_MENU_SURFACE_CLASSNAME =
  'fixed z-50 inline-flex w-fit max-w-[calc(100vw-16px)] flex-col rounded-md border bg-popover p-1 text-popover-foreground shadow-md'
const VIEW_CONTEXT_MENU_BUTTON_CLASSNAME =
  'h-auto w-auto max-w-full justify-start gap-2 rounded-sm px-2 py-1.5 text-left text-sm font-normal'

function updateViewDefinition(
  view: ViewFile,
  patch: Partial<ViewDefinition>,
  onUpdateViewDefinition: ViewDefinitionPatchHandler,
) {
  if (view.rootPath) onUpdateViewDefinition(view.filename, patch, view.rootPath)
  else onUpdateViewDefinition(view.filename, patch)
}

export function ViewRenameInput({
  initialValue,
  locale,
  onCancel,
  onSubmit,
}: {
  initialValue: string
  locale: AppLocale
  onCancel: () => void
  onSubmit: (value: string) => void
}) {
  const {
    handleKeyDown,
    inputRef,
    setValue,
    submitValue,
    value,
  } = useSidebarInlineRenameInput({ initialValue, onCancel, onSubmit })

  return (
    <Input
      ref={inputRef}
      aria-label={translate(locale, 'sidebar.view.name')}
      className="h-6 min-w-0 flex-1 rounded border-primary bg-background px-1.5 py-0 text-[13px] font-medium"
      value={value}
      onBlur={() => { void submitValue() }}
      onChange={(event) => setValue(event.target.value)}
      onClick={(event) => event.stopPropagation()}
      onDoubleClick={(event) => event.stopPropagation()}
      onKeyDown={handleKeyDown}
    />
  )
}

function ViewMenuButton({
  children,
  destructive = false,
  onClick,
}: {
  children: ReactNode
  destructive?: boolean
  onClick: () => void
}) {
  const className = `${VIEW_CONTEXT_MENU_BUTTON_CLASSNAME}${destructive ? ' text-destructive hover:text-destructive' : ''}`
  return (
    <Button type="button" variant="ghost" size="sm" className={className} onClick={onClick}>
      {children}
    </Button>
  )
}

export function ViewContextMenu({
  pos,
  canCustomize,
  canDelete,
  canEdit,
  locale,
  innerRef,
  onCustomize,
  onDelete,
  onEdit,
}: {
  pos: MenuPosition | null
  canCustomize: boolean
  canDelete: boolean
  canEdit: boolean
  locale: AppLocale
  innerRef: RefObject<HTMLDivElement | null>
  onCustomize: () => void
  onDelete: () => void
  onEdit: () => void
}) {
  if (!pos || (!canEdit && !canCustomize && !canDelete)) return null

  return (
    <div
      ref={innerRef}
      className={VIEW_CONTEXT_MENU_SURFACE_CLASSNAME}
      style={getContextMenuPositionStyle(pos)}
      data-testid="sidebar-view-context-menu"
    >
      {canEdit && (
        <ViewMenuButton onClick={onEdit}>
          <PencilSimple size={14} />
          {translate(locale, 'sidebar.action.editView')}
        </ViewMenuButton>
      )}
      {canCustomize && (
        <ViewMenuButton onClick={onCustomize}>
          <Palette size={14} />
          {translate(locale, 'sidebar.action.customizeIconColor')}
        </ViewMenuButton>
      )}
      {canDelete && (
        <>
          <hr className="my-1 h-px border-0 bg-border" />
          <ViewMenuButton destructive onClick={onDelete}>
            <Trash size={14} />
            {translate(locale, 'sidebar.action.deleteView')}
          </ViewMenuButton>
        </>
      )}
    </div>
  )
}

export function ViewCustomizePanel({
  pos,
  view,
  locale,
  innerRef,
  onClose,
  onUpdateViewDefinition,
}: {
  pos: MenuPosition | null
  view: ViewFile
  locale: AppLocale
  innerRef: RefObject<HTMLDivElement | null>
  onClose: () => void
  onUpdateViewDefinition?: ViewDefinitionPatchHandler
}) {
  if (!pos || !onUpdateViewDefinition) return null

  return (
    <div ref={innerRef} className="fixed z-50" style={getContextMenuPositionStyle(pos)}>
      <TypeCustomizePopover
        currentIcon={view.definition.icon}
        currentColor={view.definition.color}
        currentTemplate={null}
        onChangeIcon={(icon) => updateViewDefinition(view, { icon }, onUpdateViewDefinition)}
        onChangeColor={(color) => updateViewDefinition(view, { color }, onUpdateViewDefinition)}
        onChangeTemplate={() => {}}
        onClose={onClose}
        showTemplate={false}
        locale={locale}
      />
    </div>
  )
}
