import { css, keyframes } from '@emotion/react';
import { useState } from 'react';
import elementsData from '../../data/elements.json';
import recipesData from '../../data/recipes.json';
import { useGameStore } from '../../store/useGameStore';
import { FloatingOverlay } from '../FloatingOverlay';
import { useFloatingItems } from '../../hooks/useFloatingItems';
import { trackGameEvent } from '../../platform/analytics';
import { showRewardedAd } from '../../platform/ads';
import { DiscoveryHero } from '../DiscoveryHero';
import { playRaritySfx, vibrate } from '../../lib/sfx';

// TDS 색상 팔레트
const tds = {
  blue: '#3182F6',
  blueLight: '#EEF4FF',
  blueDark: '#1B64DA',
  orange: '#FF6B35',
  orangeLight: '#FFF3EE',
  gold: '#F7C12A',
  goldLight: '#FFFBEA',
  green: '#00C853',
  greenLight: '#E8FAF0',
  red: '#F04452',
  gray100: '#F8F8F8',
  gray200: '#F0F0F0',
  gray300: '#E0E0E0',
  gray400: '#C0C0C0',
  gray500: '#8B8B8B',
  gray700: '#4A4A4A',
  gray900: '#191919',
  white: '#FFFFFF',
  border: '#F0F0F0',
};

const popIn = keyframes`
  0%   { transform: scale(0.5); opacity: 0; }
  70%  { transform: scale(1.15); }
  100% { transform: scale(1); opacity: 1; }
`;

const shimmer = keyframes`
  0%   { background-position: -200% center; }
  100% { background-position: 200% center; }
`;

// 합성 이펙트 keyframes
const popInBlue = keyframes`
  0%   { transform: scale(0.3); opacity: 0; filter: drop-shadow(0 0 12px #3182F6); }
  60%  { transform: scale(1.25); filter: drop-shadow(0 0 16px #3182F6); }
  100% { transform: scale(1); opacity: 1; filter: drop-shadow(0 0 0px #3182F6); }
`;

const popInPurple = keyframes`
  0%   { transform: scale(0.3) rotate(-15deg); opacity: 0; filter: drop-shadow(0 0 14px #9C27B0); }
  55%  { transform: scale(1.3) rotate(5deg); filter: drop-shadow(0 0 20px #9C27B0); }
  100% { transform: scale(1) rotate(0deg); opacity: 1; filter: drop-shadow(0 0 4px #9C27B0); }
`;

const legendaryBurst = keyframes`
  0%   { transform: scale(0) rotate(-20deg); opacity: 0; filter: brightness(3) drop-shadow(0 0 16px #F7C12A); }
  30%  { transform: scale(1.5) rotate(8deg); filter: brightness(2) drop-shadow(0 0 24px #F7C12A); }
  60%  { transform: scale(0.92) rotate(-3deg); filter: brightness(1.4) drop-shadow(0 0 12px #FF6B35); }
  100% { transform: scale(1) rotate(0deg); opacity: 1; filter: drop-shadow(0 0 6px #F7C12A); }
`;

const particleAnim = (dx: number, dy: number) => keyframes`
  0%   { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(${dx}px, ${dy}px) scale(0); opacity: 0; }
`;

const PARTICLE_DIRS = [
  { dx: 0,   dy: -55 },
  { dx: 39,  dy: -39 },
  { dx: 55,  dy: 0   },
  { dx: 39,  dy: 39  },
  { dx: 0,   dy: 55  },
  { dx: -39, dy: 39  },
  { dx: -55, dy: 0   },
  { dx: -39, dy: -39 },
];

const RARITY_ANIM: Record<string, ReturnType<typeof keyframes>> = {
  common:   popIn,
  uncommon: popIn,
  rare:     popInBlue,
  epic:     popInPurple,
  legendary: legendaryBurst,
};

const RARITY_GLOW: Record<string, string> = {
  common:   'none',
  uncommon: '0 0 12px #00C853',
  rare:     '0 0 16px #3182F6',
  epic:     '0 0 20px #9C27B0',
  legendary: '0 0 28px #F7C12A, 0 0 48px #FF6B35',
};

const elementMap = Object.fromEntries(elementsData.map((el) => [el.id, el]));

const RARITY_COLOR: Record<string, string> = {
  common: tds.gray500,
  uncommon: tds.green,
  rare: tds.blue,
  epic: '#9C27B0',
  legendary: tds.gold,
};

// ─── 스타일 ──────────────────────────────────────────────────────────────────

const containerStyle = css`
  display: flex;
  flex-direction: column;
  height: 100%;
  background: ${tds.gray100};
`;

const headerStyle = css`
  padding: 20px 20px 0;
  background: ${tds.white};
`;

const titleStyle = css`
  font-size: 20px;
  font-weight: 700;
  color: ${tds.gray900};
  margin: 0 0 2px;
`;

const subtitleStyle = css`
  font-size: 13px;
  color: ${tds.gray500};
  margin: 0 0 16px;
`;

const fusionPanelStyle = css`
  padding: 16px 20px;
  background: ${tds.white};
  border-bottom: 1px solid ${tds.border};
`;

const slotsRowStyle = css`
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
`;

const slotStyle = (filled: boolean, active: boolean) => css`
  flex: 1;
  height: 76px;
  border: 2px ${filled ? 'solid' : 'dashed'} ${active ? tds.orange : filled ? tds.blue : tds.gray300};
  border-radius: 16px;
  background: ${active ? tds.orangeLight : filled ? tds.blueLight : tds.gray100};
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  gap: 2px;
  transition: border-color 0.15s, background 0.15s;
`;

const slotEmojiStyle = css`
  font-size: 28px;
  line-height: 1;
`;

const slotLabelStyle = css`
  font-size: 11px;
  color: ${tds.gray500};
  font-weight: 500;
`;

const plusStyle = css`
  font-size: 22px;
  color: ${tds.gray400};
  flex-shrink: 0;
`;

const previewBannerStyle = css`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: ${tds.blueLight};
  border-radius: 10px;
  padding: 8px 12px;
  margin-bottom: 10px;
  font-size: 14px;
  font-weight: 600;
  color: ${tds.blue};
`;

const comboBarStyle = (active: boolean) => css`
  background: ${active ? 'linear-gradient(135deg, #101828, #27364f)' : tds.gray100};
  color: ${active ? '#ffffff' : tds.gray500};
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  font-weight: 800;
`;

const comboValueStyle = css`
  color: #ffd166;
`;

const fuseButtonStyle = (canFuse: boolean) => css`
  width: 100%;
  padding: 14px;
  background: ${canFuse
    ? `linear-gradient(135deg, ${tds.orange}, ${tds.gold})`
    : tds.gray200};
  color: ${canFuse ? tds.white : tds.gray400};
  border: none;
  border-radius: 14px;
  font-size: 15px;
  font-weight: 700;
  cursor: ${canFuse ? 'pointer' : 'not-allowed'};
  transition: opacity 0.15s;

  &:active {
    opacity: ${canFuse ? 0.85 : 1};
  }
`;

const resultBannerStyle = (rarity: string) => css`
  display: flex;
  align-items: center;
  gap: 10px;
  background: ${tds.greenLight};
  border-radius: 12px;
  padding: 10px 14px;
  margin-bottom: 10px;
  border: 1px solid ${tds.green};
  box-shadow: ${RARITY_GLOW[rarity] ?? 'none'};
  transition: box-shadow 0.3s;
`;

const resultEmojiStyle = (rarity: string) => css`
  font-size: 30px;
  animation: ${RARITY_ANIM[rarity] ?? popIn} ${rarity === 'legendary' ? '0.7s' : '0.45s'} ease-out;
`;

const fuseButtonWrapStyle = css`
  position: relative;
`;

const particleStyle = (dx: number, dy: number, color: string, delay: number) => css`
  position: absolute;
  left: 50%;
  top: 50%;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: ${color};
  pointer-events: none;
  margin: -4px 0 0 -4px;
  animation: ${particleAnim(dx, dy)} 0.7s ${delay}ms ease-out forwards;
`;

const resultTextStyle = css`
  flex: 1;
`;

const resultNameStyle = css`
  font-size: 14px;
  font-weight: 700;
  color: ${tds.gray900};
`;

const resultGoldStyle = css`
  font-size: 12px;
  color: ${tds.gray500};
  margin-top: 1px;
`;

const errorBannerStyle = css`
  background: #FFF1F1;
  border: 1px solid ${tds.red};
  border-radius: 10px;
  padding: 8px 12px;
  font-size: 13px;
  color: ${tds.red};
  font-weight: 600;
  text-align: center;
  margin-bottom: 10px;
`;

const assistBannerStyle = css`
  background: ${tds.goldLight};
  border: 1px solid ${tds.gold};
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 12px;
  color: ${tds.gray900};
  font-weight: 800;
  text-align: center;
  margin-bottom: 10px;
`;

const assistButtonStyle = (enabled: boolean) => css`
  margin-top: 8px;
  border: none;
  border-radius: 9px;
  background: ${enabled ? '#101828' : tds.gray200};
  color: ${enabled ? tds.white : tds.gray500};
  padding: 8px 10px;
  font-size: 12px;
  font-weight: 900;
  cursor: ${enabled ? 'pointer' : 'default'};
`;

// ─── 인벤토리 섹션 ──────────────────────────────────────────────────────────

const inventorySectionStyle = css`
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
`;

const sectionHeaderStyle = css`
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
`;

const sectionTitleStyle = css`
  font-size: 14px;
  font-weight: 700;
  color: ${tds.gray900};
`;

const sectionCountStyle = css`
  font-size: 12px;
  color: ${tds.gray500};
`;

const inventoryGridStyle = css`
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 20px;
`;

const inventoryCardStyle = (
  owned: boolean,
  selected: boolean,
  selectMode: boolean
) => css`
  display: flex;
  flex-direction: column;
  align-items: center;
  background: ${selected ? tds.orangeLight : tds.white};
  border: 2px solid ${selected ? tds.orange : owned ? tds.gray300 : tds.gray200};
  border-radius: 14px;
  padding: 10px 4px 8px;
  gap: 4px;
  cursor: ${owned && selectMode ? 'pointer' : 'default'};
  opacity: ${owned ? 1 : 0.4};
  transition: border-color 0.12s, background 0.12s;

  ${owned && selectMode && !selected
    ? `&:hover { border-color: ${tds.orange}; background: ${tds.orangeLight}; }`
    : ''}
`;

const cardEmojiStyle = css`
  font-size: 22px;
  line-height: 1;
`;

const cardNameStyle = css`
  font-size: 10px;
  font-weight: 600;
  color: ${tds.gray900};
  text-align: center;
  line-height: 1.2;
`;

const cardCountStyle = (rarity: string) => css`
  font-size: 10px;
  font-weight: 700;
  color: ${RARITY_COLOR[rarity] ?? tds.gray500};
`;

const discoveredSectionStyle = css`
  margin-top: 8px;
`;

const recipeRowStyle = css`
  display: flex;
  align-items: center;
  gap: 8px;
  background: ${tds.white};
  border: 1px solid ${tds.border};
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 6px;
`;

const recipeEmojiStyle = css`
  font-size: 18px;
`;

const recipeArrowStyle = css`
  font-size: 11px;
  color: ${tds.gray400};
`;

const recipeNameStyle = css`
  flex: 1;
  font-size: 13px;
  color: ${tds.gray900};
  font-weight: 500;
`;

const shineBadgeStyle = css`
  font-size: 11px;
  background: linear-gradient(90deg, ${tds.gold}, ${tds.orange}, ${tds.gold});
  background-size: 200% auto;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: ${shimmer} 2s linear infinite;
  font-weight: 700;
`;

// ─── 컴포넌트 ────────────────────────────────────────────────────────────────

export function FusionScreen() {
  const {
    elements,
    discoveredElements,
    comboCount,
    comboExpiresAt,
    sfxEnabled,
    hapticEnabled,
    adRewardProgress,
    claimAdFusionAssist,
    fuse,
  } = useGameStore();
  const [slot1, setSlot1] = useState<string | null>(null);
  const [slot2, setSlot2] = useState<string | null>(null);
  const [selectingSlot, setSelectingSlot] = useState<1 | 2 | null>(null);
  const [lastResult, setLastResult] = useState<{
    type: 'success' | 'error';
    resultId?: string;
    goldGained?: number;
    message?: string;
  } | null>(null);
  const [isFusing, setIsFusing] = useState(false);
  const [assistLoading, setAssistLoading] = useState(false);
  const [assistMessage, setAssistMessage] = useState<string | null>(null);
  const [fuseRarity, setFuseRarity] = useState<string>('common');
  const [hero, setHero] = useState<{
    elementId: string;
    name: string;
    color: string;
    tier: number;
    rarity: string;
    discoveredCount: number;
    isLucky: boolean;
  } | null>(null);
  const { items: floatItems, add: addFloat } = useFloatingItems(1100);
  const comboRemainingSec = Math.max(0, Math.ceil((comboExpiresAt - Date.now()) / 1000));
  const comboMultiplier = comboCount >= 10 ? 3 : comboCount >= 6 ? 2 : comboCount >= 3 ? 1.5 : 1;
  const comboActive = comboRemainingSec > 0 && comboCount > 0;

  // 보유 중인 원소 목록 (보유량 > 0)
  const ownedElements = elementsData.filter((el) => (elements[el.id] ?? 0) > 0);

  const getMatchingRecipe = () => {
    if (!slot1 || !slot2) return null;
    return recipesData.find(
      (r) =>
        (r.ingredients[0] === slot1 && r.ingredients[1] === slot2) ||
        (r.ingredients[0] === slot2 && r.ingredients[1] === slot1)
    );
  };

  const matchingRecipe = getMatchingRecipe();
  const sameSelectedElement = slot1 !== null && slot1 === slot2;
  const canFuse =
    !!matchingRecipe &&
    (sameSelectedElement
      ? (elements[slot1 ?? ''] ?? 0) >= 2
      : (elements[slot1 ?? ''] ?? 0) > 0 && (elements[slot2 ?? ''] ?? 0) > 0);

  const findAssistRecipe = () =>
    recipesData.find((recipe) => {
      const [first, second] = recipe.ingredients;
      const same = first === second;
      if (same) return (elements[first] ?? 0) >= 2;
      return (elements[first] ?? 0) > 0 && (elements[second] ?? 0) > 0;
    });

  const handleFusionAssist = async () => {
    if (assistLoading || adRewardProgress.fusionAssistUses >= 5) return;
    const recipe = findAssistRecipe();
    if (!recipe) {
      setAssistMessage('추천할 수 있는 조합이 아직 없습니다. 원소를 더 모아보세요.');
      return;
    }

    setAssistLoading(true);
    try {
      const adResult = await showRewardedAd();
      if (adResult.rewarded && claimAdFusionAssist()) {
        setSlot1(recipe.ingredients[0]);
        setSlot2(recipe.ingredients[1]);
        setSelectingSlot(null);
        const resultEl = elementMap[recipe.result];
        setAssistMessage(`${resultEl?.emoji ?? '✨'} ${resultEl?.name ?? '새 원소'} 조합을 슬롯에 넣었습니다.`);
        setLastResult(null);
        trackGameEvent('rewarded_ad_claimed', {
          placement: 'fusion_assist',
          recipe_id: recipe.id,
          result_id: recipe.result,
        });
      }
    } finally {
      setAssistLoading(false);
    }
  };

  const handleFuse = () => {
    if (!slot1 || !slot2) return;
    const result = fuse(slot1, slot2);
    if (result.success && result.resultId) {
      const resultEl = elementMap[result.resultId];
      const rarity = resultEl?.rarity ?? 'common';
      setFuseRarity(rarity);
      setIsFusing(true);
      setTimeout(() => setIsFusing(false), 750);
      playRaritySfx(rarity, sfxEnabled);
      vibrate(rarity === 'legendary' ? [80, 40, 80] : 50, hapticEnabled);
      if (rarity === 'legendary') {
        window.dispatchEvent(new CustomEvent('legendaryImpact'));
      }

      // 골드 획득 플로팅 텍스트
      const cx = window.innerWidth / 2 - 30;
      const cy = window.innerHeight * 0.45;
      addFloat({ text: `+${result.goldGained} 💰`, x: cx + (Math.random() - 0.5) * 60, y: cy, color: tds.gold, fontSize: 14 });
      if (result.comboMultiplier && result.comboMultiplier > 1) {
        addFloat({
          text: `${result.comboCount} COMBO x${result.comboMultiplier}`,
          x: cx + (Math.random() - 0.5) * 80,
          y: cy - 28,
          color: '#FFD166',
          fontSize: 15,
        });
      }
      if (result.isLucky) {
        addFloat({
          text: '🍀 LUCKY!',
          x: cx + (Math.random() - 0.5) * 80,
          y: cy - 54,
          color: '#22C55E',
          fontSize: 16,
        });
      }

      trackGameEvent('fusion_completed', {
        result_id: result.resultId,
        result_name: resultEl?.name ?? '',
        result_tier: rarity,
        gold_gained: result.goldGained ?? 0,
        combo_count: result.comboCount ?? 1,
        combo_multiplier: result.comboMultiplier ?? 1,
        lucky: result.isLucky ?? false,
        ingredient_1: slot1,
        ingredient_2: slot2,
      });

      if (result.isNewDiscovery && resultEl) {
        setHero({
          elementId: result.resultId,
          name: resultEl.name,
          color: resultEl.color,
          tier: resultEl.tier,
          rarity,
          discoveredCount: discoveredElements.length + 1,
          isLucky: result.isLucky ?? false,
        });
      }

      setLastResult({
        type: 'success',
        resultId: result.resultId,
        goldGained: result.goldGained,
      });
      setSlot1(null);
      setSlot2(null);
      setSelectingSlot(null);
    } else {
      setLastResult({
        type: 'error',
        message:
          result.error === 'no_recipe'
            ? '⚠️ 알 수 없는 조합입니다'
            : '⚠️ 원소가 부족합니다',
      });
      vibrate(35, hapticEnabled);
    }
    // 3초 후 피드백 초기화
    setTimeout(() => setLastResult(null), 3000);
  };

  const handleSlotClick = (slot: 1 | 2) => {
    if (selectingSlot === slot) {
      setSelectingSlot(null);
    } else {
      setSelectingSlot(slot);
    }
    setLastResult(null);
  };

  const handleSelectElement = (id: string) => {
    if (selectingSlot === 1) setSlot1(id);
    else if (selectingSlot === 2) setSlot2(id);
    setSelectingSlot(null);
  };

  const discoveredRecipes = recipesData.filter(
    (r) => (elements[r.result] ?? 0) > 0
  );

  const selectMode = selectingSlot !== null;

  return (
    <div css={containerStyle}>
      {/* ── 상단 헤더 ── */}
      <div css={headerStyle}>
        <h1 css={titleStyle}>합성</h1>
        <p css={subtitleStyle}>두 원소를 조합하여 새로운 원소를 만드세요</p>
      </div>

      {/* ── 합성 패널 ── */}
      <div css={fusionPanelStyle}>
        <div css={comboBarStyle(comboActive)}>
          <span>합성 콤보</span>
          <span css={comboValueStyle}>
            {comboActive ? `${comboCount} COMBO · x${comboMultiplier} · ${comboRemainingSec}s` : '8초 안에 연속 합성'}
          </span>
        </div>
        {/* 슬롯 */}
        <div css={slotsRowStyle}>
          <div
            css={slotStyle(!!slot1, selectingSlot === 1)}
            onClick={() => handleSlotClick(1)}
            data-tutorial="fusion-slot1"
          >
            {slot1 ? (
              <>
                <span css={slotEmojiStyle}>{elementMap[slot1]?.emoji}</span>
                <span css={slotLabelStyle}>{elementMap[slot1]?.name}</span>
              </>
            ) : (
              <span css={slotLabelStyle}>
                {selectingSlot === 1 ? '아래서 선택' : '원소 선택'}
              </span>
            )}
          </div>
          <span css={plusStyle}>+</span>
          <div
            css={slotStyle(!!slot2, selectingSlot === 2)}
            onClick={() => handleSlotClick(2)}
          >
            {slot2 ? (
              <>
                <span css={slotEmojiStyle}>{elementMap[slot2]?.emoji}</span>
                <span css={slotLabelStyle}>{elementMap[slot2]?.name}</span>
              </>
            ) : (
              <span css={slotLabelStyle}>
                {selectingSlot === 2 ? '아래서 선택' : '원소 선택'}
              </span>
            )}
          </div>
        </div>

        {/* 레시피 미리보기 */}
        {matchingRecipe && (
          <div css={previewBannerStyle}>
            <span>{elementMap[slot1 ?? '']?.emoji}</span>
            <span>+</span>
            <span>{elementMap[slot2 ?? '']?.emoji}</span>
            <span>=</span>
            <span>{elementMap[matchingRecipe.result]?.emoji}</span>
            <span>{elementMap[matchingRecipe.result]?.name}</span>
          </div>
        )}

        {/* 합성 결과 피드백 */}
        {lastResult?.type === 'success' && lastResult.resultId && (
          <div
            css={resultBannerStyle(elementMap[lastResult.resultId]?.rarity ?? 'common')}
            data-tutorial="fusion-result"
          >
            <span css={resultEmojiStyle(elementMap[lastResult.resultId]?.rarity ?? 'common')}>
              {elementMap[lastResult.resultId]?.emoji}
            </span>
            <div css={resultTextStyle}>
              <div css={resultNameStyle}>
                {lastResult.resultId && elementMap[lastResult.resultId]?.name} 합성 성공!
              </div>
              <div css={resultGoldStyle}>+{lastResult.goldGained} Gold 획득</div>
            </div>
            <span css={shineBadgeStyle}>
              {lastResult.resultId && elementMap[lastResult.resultId]?.rarity === 'legendary' ? 'LEGEND' : 'NEW'}
            </span>
          </div>
        )}
        {lastResult?.type === 'error' && (
          <div css={errorBannerStyle}>
            <div>{lastResult.message}</div>
            <button
              css={assistButtonStyle(!assistLoading && adRewardProgress.fusionAssistUses < 5)}
              onClick={handleFusionAssist}
              disabled={assistLoading || adRewardProgress.fusionAssistUses >= 5}
            >
              {assistLoading
                ? '광고 확인 중...'
                : adRewardProgress.fusionAssistUses >= 5
                  ? '오늘 힌트 한도 완료'
                  : '광고 보고 추천 조합'}
            </button>
          </div>
        )}
        {assistMessage && <div css={assistBannerStyle}>{assistMessage}</div>}

        {/* 합성 버튼 + 파티클 버스트 */}
        <div css={fuseButtonWrapStyle}>
          {isFusing && PARTICLE_DIRS.map((dir, i) => (
            <span
              key={i}
              css={particleStyle(
                dir.dx,
                dir.dy,
                RARITY_COLOR[fuseRarity] ?? tds.gold,
                i * 30
              )}
            />
          ))}
          <button
            css={fuseButtonStyle(canFuse)}
            onClick={handleFuse}
            disabled={!canFuse}
          >
            {isFusing
              ? '✨ 합성 중...'
              : !slot1 || !slot2
              ? '원소를 두 개 선택하세요'
              : !matchingRecipe
              ? '⚠️ 알 수 없는 조합'
              : '✨ 합성하기'}
          </button>
        </div>
      </div>

      {/* 플로팅 텍스트 오버레이 */}
      <FloatingOverlay items={floatItems} />

      {/* ── 인벤토리 + 발견한 레시피 ── */}
      <div css={inventorySectionStyle}>
        {/* 인벤토리 그리드 */}
        <div css={sectionHeaderStyle}>
          <span css={sectionTitleStyle}>
            {selectMode ? `슬롯 ${selectingSlot}에 넣을 원소를 선택하세요` : '보유 원소'}
          </span>
          <span css={sectionCountStyle}>
            {ownedElements.length} / {elementsData.length}종
          </span>
        </div>

        <div css={inventoryGridStyle}>
          {elementsData.map((el) => {
            const count = elements[el.id] ?? 0;
            const owned = count > 0;
            const selectedInSlot =
              (selectingSlot === 1 && slot1 === el.id) ||
              (selectingSlot === 2 && slot2 === el.id);

            return (
              <div
                key={el.id}
                css={inventoryCardStyle(owned, selectedInSlot, selectMode)}
                onClick={() => owned && selectMode && handleSelectElement(el.id)}
              >
                <span css={cardEmojiStyle}>{el.emoji}</span>
                <span css={cardNameStyle}>{el.name}</span>
                {owned && (
                  <span css={cardCountStyle(el.rarity)}>×{count}</span>
                )}
              </div>
            );
          })}
        </div>

        {/* 발견한 레시피 */}
        {discoveredRecipes.length > 0 && (
          <div css={discoveredSectionStyle}>
            <div css={sectionHeaderStyle}>
              <span css={sectionTitleStyle}>발견한 레시피</span>
              <span css={sectionCountStyle}>
                {discoveredRecipes.length} / {recipesData.length}
              </span>
            </div>
            {discoveredRecipes.map((r) => (
              <div key={r.id} css={recipeRowStyle}>
                <span css={recipeEmojiStyle}>{elementMap[r.ingredients[0]]?.emoji}</span>
                <span css={recipeArrowStyle}>+</span>
                <span css={recipeEmojiStyle}>{elementMap[r.ingredients[1]]?.emoji}</span>
                <span css={recipeArrowStyle}>→</span>
                <span css={recipeEmojiStyle}>{elementMap[r.result]?.emoji}</span>
                <span css={recipeNameStyle}>{elementMap[r.result]?.name}</span>
              </div>
            ))}
          </div>
        )}
      </div>

      {hero && (
        <DiscoveryHero
          elementId={hero.elementId}
          name={hero.name}
          color={hero.color}
          tier={hero.tier}
          rarity={hero.rarity}
          discoveredCount={hero.discoveredCount}
          isLucky={hero.isLucky}
          onClose={() => setHero(null)}
        />
      )}
    </div>
  );
}
