import React, { useState, useEffect } from 'react'
import { useInventoryContext } from '../../context/InventoryContext'
import { useTextures } from '../../context/TextureContext'
import { useScale } from '../../context/ScaleContext'

// Bundled payment item textures (not available via texture provider in the full client)
import netherite_ingot_png from '../../assets/beacon/netherite_ingot.png'
import emerald_png from '../../assets/beacon/emerald.png'
import diamond_png from '../../assets/beacon/diamond.png'
import gold_ingot_png from '../../assets/beacon/gold_ingot.png'
import iron_ingot_png from '../../assets/beacon/iron_ingot.png'

const SPRITE_BASE = '1.21.11/textures/gui/sprites/container/beacon'
const MOB_EFFECT_BASE = '1.21.11/textures/mob_effect'

// Effect IDs matching vanilla BeaconMenu.encodeEffect: registry_id + 1
// ContainerData: ≤0 = none, 1+ = effect (1-based)
// Protocol set_beacon_effect option(varint) uses the same 1-based encoding
const EFFECTS = {
  NONE: -1,
  SPEED: 1,          // registry 0 + 1
  HASTE: 3,          // registry 2 + 1
  STRENGTH: 5,       // registry 4 + 1
  JUMP_BOOST: 8,     // registry 7 + 1
  REGENERATION: 10,  // registry 9 + 1
  RESISTANCE: 11,    // registry 10 + 1
} as const

const EFFECT_INFO: Record<number, { name: string; sprite: string }> = {
  [EFFECTS.SPEED]: { name: 'Speed', sprite: 'speed' },
  [EFFECTS.HASTE]: { name: 'Haste', sprite: 'haste' },
  [EFFECTS.RESISTANCE]: { name: 'Resistance', sprite: 'resistance' },
  [EFFECTS.JUMP_BOOST]: { name: 'Jump Boost', sprite: 'jump_boost' },
  [EFFECTS.STRENGTH]: { name: 'Strength', sprite: 'strength' },
  [EFFECTS.REGENERATION]: { name: 'Regeneration', sprite: 'regeneration' },
}

// Primary buttons: 3 tiers of effects
const PRIMARY_TIERS: { tier: number; y: number; effects: number[] }[] = [
  { tier: 0, y: 22, effects: [EFFECTS.SPEED, EFFECTS.HASTE] },
  { tier: 1, y: 47, effects: [EFFECTS.RESISTANCE, EFFECTS.JUMP_BOOST] },
  { tier: 2, y: 72, effects: [EFFECTS.STRENGTH] },
]

const PRIMARY_CENTER_X = 76

// Payment indicator items shown next to the payment slot (vanilla renderBg)
const PAYMENT_ITEMS: { src: string; x: number }[] = [
  { src: netherite_ingot_png, x: 20 },
  { src: emerald_png, x: 41 },
  { src: diamond_png, x: 63 },
  { src: gold_ingot_png, x: 86 },
  { src: iron_ingot_png, x: 108 },
]

interface BeaconEffectsProps {
  properties: Record<string, number>
}

export function BeaconEffects({ properties }: BeaconEffectsProps) {
  const { sendAction, getSlot } = useInventoryContext()
  const textures = useTextures()
  const { scale } = useScale()

  const levels = properties.levels ?? 0
  // ContainerData: ≤0 means "no effect" (server sends -1 for uninitialized, vanilla sends 0)
  const serverPrimary = (properties.primaryEffect ?? -1) > 0 ? properties.primaryEffect! : EFFECTS.NONE
  const serverSecondary = (properties.secondaryEffect ?? -1) > 0 ? properties.secondaryEffect! : EFFECTS.NONE

  const [selectedPrimary, setSelectedPrimary] = useState(serverPrimary)
  const [selectedSecondary, setSelectedSecondary] = useState(serverSecondary)
  const [hoveredButton, setHoveredButton] = useState<string | null>(null)

  // Sync local state when server properties change
  useEffect(() => {
    setSelectedPrimary(serverPrimary)
    setSelectedSecondary(serverSecondary)
  }, [serverPrimary, serverSecondary])

  // Payment slot is index 0 in the beacon container
  const paymentSlot = getSlot(0)
  const hasPayment = paymentSlot?.item != null

  // Confirm requires payment AND a primary selection (valid effects are > 0)
  const canConfirm = hasPayment && selectedPrimary > 0

  // Upgrade button mirrors the LOCAL selected primary (vanilla: BeaconScreen.this.primary)
  const showUpgrade = selectedPrimary > 0

  const getButtonSprite = (disabled: boolean, selected: boolean, hovered: boolean) => {
    if (disabled) return textures.getGuiTextureUrl(`${SPRITE_BASE}/button_disabled.png`)
    if (selected) return textures.getGuiTextureUrl(`${SPRITE_BASE}/button_selected.png`)
    if (hovered) return textures.getGuiTextureUrl(`${SPRITE_BASE}/button_highlighted.png`)
    return textures.getGuiTextureUrl(`${SPRITE_BASE}/button.png`)
  }

  const getEffectSprite = (effect: number) => {
    const info = EFFECT_INFO[effect]
    if (!info) return undefined
    return textures.getGuiTextureUrl(`${MOB_EFFECT_BASE}/${info.sprite}.png`)
  }

  const handleConfirm = () => {
    if (!canConfirm) return
    sendAction({
      type: 'beacon',
      primaryEffect: selectedPrimary,
      secondaryEffect: selectedSecondary,
    })
    sendAction({ type: 'close' })
  }

  const handleCancel = () => {
    sendAction({ type: 'close' })
  }

  // Center buttons around a given X coordinate
  const getButtonX = (centerX: number, index: number, count: number) => {
    const totalWidth = count * 22 + (count - 1) * 2
    return centerX + index * 24 - totalWidth / 2
  }

  const renderEffectButton = (
    effect: number,
    x: number,
    y: number,
    disabled: boolean,
    isSelected: boolean,
    isPrimary: boolean,
    key: string,
    tooltip?: string,
  ) => {
    const hovered = hoveredButton === key && !disabled
    const info = EFFECT_INFO[effect]
    const title = tooltip ?? info?.name

    return (
      <div
        key={key}
        onClick={() => {
          if (disabled) return
          if (isPrimary) {
            setSelectedPrimary(effect)
          } else {
            setSelectedSecondary(effect)
          }
        }}
        onMouseEnter={() => setHoveredButton(key)}
        onMouseLeave={() => setHoveredButton(null)}
        title={title}
        style={{
          position: 'absolute',
          left: x * scale,
          top: y * scale,
          width: 22 * scale,
          height: 22 * scale,
          cursor: disabled ? 'default' : 'pointer',
        }}
      >
        <img
          src={getButtonSprite(disabled, isSelected, hovered)}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: 0,
            top: 0,
            width: 22 * scale,
            height: 22 * scale,
            imageRendering: 'pixelated',
          }}
        />
        {getEffectSprite(effect) && (
          <img
            src={getEffectSprite(effect)}
            alt=""
            draggable={false}
            style={{
              position: 'absolute',
              left: 2 * scale,
              top: 2 * scale,
              width: 18 * scale,
              height: 18 * scale,
              imageRendering: 'pixelated',
            }}
          />
        )}
      </div>
    )
  }

  const labelStyle = (x: number): React.CSSProperties => ({
    position: 'absolute',
    left: x * scale,
    top: 10 * scale,
    fontSize: 8 * scale,
    fontFamily: "'Minecraft', monospace",
    color: '#E0E0E0',
    textShadow: 'none',
    transform: 'translateX(-50%)',
    whiteSpace: 'nowrap',
    pointerEvents: 'none',
  })

  return (
    <>
      {/* Labels */}
      <span style={labelStyle(62)}>Primary Power</span>
      <span style={labelStyle(169)}>Secondary Power</span>

      {/* Payment item indicators (decorative icons showing valid payment items) */}
      {PAYMENT_ITEMS.map(({ src, x }) => (
        <img
          key={`pay-${x}`}
          src={src}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: x * scale,
            top: 109 * scale,
            width: 16 * scale,
            height: 16 * scale,
            imageRendering: 'pixelated',
            pointerEvents: 'none',
          }}
        />
      ))}

      {/* Primary effect buttons (3 tiers) */}
      {PRIMARY_TIERS.map(({ tier, y, effects }) =>
        effects.map((effect, idx) => {
          const x = getButtonX(PRIMARY_CENTER_X, idx, effects.length)
          const disabled = tier >= levels
          const isSelected = selectedPrimary === effect
          return renderEffectButton(effect, x, y, disabled, isSelected, true, `primary-${effect}`)
        })
      )}

      {/* Secondary: Regeneration button (fixed position x=144) */}
      {renderEffectButton(
        EFFECTS.REGENERATION,
        144,
        47,
        3 >= levels,
        selectedSecondary === EFFECTS.REGENERATION,
        false,
        'secondary-regen',
      )}

      {/* Secondary: Upgrade button (fixed position x=168, mirrors local primary selection) */}
      {showUpgrade && renderEffectButton(
        selectedPrimary,
        168,
        47,
        3 >= levels,
        selectedSecondary === selectedPrimary,
        false,
        'secondary-upgrade',
        `${EFFECT_INFO[selectedPrimary]?.name ?? 'Effect'} II`,
      )}

      {/* Confirm button */}
      <div
        onClick={handleConfirm}
        onMouseEnter={() => setHoveredButton('confirm')}
        onMouseLeave={() => setHoveredButton(null)}
        title="Done"
        style={{
          position: 'absolute',
          left: 164 * scale,
          top: 107 * scale,
          width: 22 * scale,
          height: 22 * scale,
          cursor: canConfirm ? 'pointer' : 'default',
        }}
      >
        <img
          src={getButtonSprite(!canConfirm, false, hoveredButton === 'confirm' && canConfirm)}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: 0,
            top: 0,
            width: 22 * scale,
            height: 22 * scale,
            imageRendering: 'pixelated',
          }}
        />
        <img
          src={textures.getGuiTextureUrl(`${SPRITE_BASE}/confirm.png`)}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: 2 * scale,
            top: 2 * scale,
            width: 18 * scale,
            height: 18 * scale,
            imageRendering: 'pixelated',
          }}
        />
      </div>

      {/* Cancel button */}
      <div
        onClick={handleCancel}
        onMouseEnter={() => setHoveredButton('cancel')}
        onMouseLeave={() => setHoveredButton(null)}
        title="Cancel"
        style={{
          position: 'absolute',
          left: 190 * scale,
          top: 107 * scale,
          width: 22 * scale,
          height: 22 * scale,
          cursor: 'pointer',
        }}
      >
        <img
          src={getButtonSprite(false, false, hoveredButton === 'cancel')}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: 0,
            top: 0,
            width: 22 * scale,
            height: 22 * scale,
            imageRendering: 'pixelated',
          }}
        />
        <img
          src={textures.getGuiTextureUrl(`${SPRITE_BASE}/cancel.png`)}
          alt=""
          draggable={false}
          style={{
            position: 'absolute',
            left: 2 * scale,
            top: 2 * scale,
            width: 18 * scale,
            height: 18 * scale,
            imageRendering: 'pixelated',
          }}
        />
      </div>
    </>
  )
}
