import {
  Box,
  Typography,
  Button,
  Grid,
  FormControl,
  Select,
  MenuItem,
  InputLabel,
  Tabs,
  Tab,
  TextField,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
} from '@mui/material';
import {
  Cape,
  fetchCapes,
  fetchCapesStore,
  purchaseCape,
  StoreCape,
  Case,
  CaseItem,
  fetchCases,
  fetchCase,
  openCase,
  Server,
  fetchPlayer,
  BonusType,
  UserBonus,
  fetchBonusTypes,
  fetchUserBonuses,
  purchaseBonus,
  upgradeBonus,
  toggleBonusActivation,
} from '../api';
import { useEffect, useState } from 'react';
import { FullScreenLoader } from '../components/FullScreenLoader';
import { getPlayerServer } from '../utils/playerOnlineCheck';
import CaseRoulette from '../components/CaseRoulette';
import BonusShopItem from '../components/BonusShopItem';
import ShopItem from '../components/ShopItem';
import { playBuySound, primeSounds } from '../utils/sounds';
import CustomNotification from '../components/Notifications/CustomNotification';
import type { NotificationPosition } from '../components/Notifications/CustomNotification';
import {
  executePrank,
  fetchPrankCommands,
  fetchPrankServers,
  PrankCommand,
  PrankServer,
} from '../api/commands';

import {
  isNotificationsEnabled,
  getNotifPositionFromSettings,
} from '../utils/notifications';
import { translateServer } from '../utils/serverTranslator';
import { Server } from 'http';

interface TabPanelProps {
  children?: React.ReactNode;
  index: number;
  value: number;
}

function TabPanel(props: TabPanelProps) {
  const { children, value, index, ...other } = props;

  return (
    <div role="tabpanel" hidden={value !== index} {...other}>
      {value === index && <Box>{children}</Box>}
    </div>
  );
}

function getRarityByWeight(
  weight?: number,
): 'common' | 'rare' | 'epic' | 'legendary' {
  if (weight === undefined || weight === null) return 'common';

  if (weight <= 5) return 'legendary';
  if (weight <= 20) return 'epic';
  if (weight <= 50) return 'rare';
  return 'common';
}

function getRarityColor(weight?: number): string {
  const rarity = getRarityByWeight(weight);
  switch (rarity) {
    case 'legendary':
      return 'rgba(255, 215, 0, 1)'; // золотой
    case 'epic':
      return 'rgba(186, 85, 211, 1)'; // фиолетовый
    case 'rare':
      return 'rgba(65, 105, 225, 1)'; // синий
    case 'common':
    default:
      return 'rgba(255, 255, 255, 0.25)'; // сероватый
  }
}

const GRADIENT =
  'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)';

const GLASS_DIALOG_SX = {
  borderRadius: '1.4vw',
  background:
    'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.16), transparent 55%), rgba(10,10,20,0.92)',
  border: '1px solid rgba(255,255,255,0.10)',
  boxShadow: '0 1.6vw 4vw rgba(0,0,0,0.6)',
  backdropFilter: 'blur(16px)',
};

export default function Shop() {
  const [storeCapes, setStoreCapes] = useState<StoreCape[]>([]);
  const [userCapes, setUserCapes] = useState<Cape[]>([]);
  const [username, setUsername] = useState<string>('');
  const [uuid, setUuid] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);

  const [playerSkinUrl, setPlayerSkinUrl] = useState<string>('');

  const [selectedCaseServerIp, setSelectedCaseServerIp] = useState<string>('');

  // Уведомления

  const [notifOpen, setNotifOpen] = useState(false);
  const [notifMsg, setNotifMsg] = useState<React.ReactNode>('');
  const [notifSeverity, setNotifSeverity] = useState<
    'success' | 'info' | 'warning' | 'error'
  >('info');

  const [notifPos, setNotifPos] = useState<NotificationPosition>({
    vertical: 'bottom',
    horizontal: 'center',
  });

  // Прокачка

  const [bonusTypes, setBonusTypes] = useState<BonusType[]>([]);
  const [userBonuses, setUserBonuses] = useState<UserBonus[]>([]);
  const [bonusesLoading, setBonusesLoading] = useState<boolean>(false);
  const [processingBonusIds, setProcessingBonusIds] = useState<string[]>([]);

  // Кейсы
  const [cases, setCases] = useState<Case[]>([]);
  const [casesLoading, setCasesLoading] = useState<boolean>(false);

  // Онлайн/сервер (по аналогии с Marketplace)
  const [isOnline, setIsOnline] = useState<boolean>(false);
  const [playerServer, setPlayerServer] = useState<Server | null>(null);
  const [onlineCheckLoading, setOnlineCheckLoading] = useState<boolean>(true);

  // Рулетка
  const [isOpening, setIsOpening] = useState<boolean>(false);
  const [selectedCase, setSelectedCase] = useState<Case | null>(null);

  const [rouletteOpen, setRouletteOpen] = useState(false);
  const [rouletteCaseItems, setRouletteCaseItems] = useState<CaseItem[]>([]);
  const [rouletteReward, setRouletteReward] = useState<CaseItem | null>(null);

  // TABS
  const [tabValue, setTabValue] = useState<number>(0);

  const handleTabChange = (_: React.SyntheticEvent, newValue: number) => {
    setTabValue(newValue);
  };

  //команды

  const [prankCommands, setPrankCommands] = useState<PrankCommand[]>([]);
  const [prankServers, setPrankServers] = useState<PrankServer[]>([]);

  const [pranksLoading, setPranksLoading] = useState(false);

  const [selectedPrankServer, setSelectedPrankServer] = useState<string>('');
  const [targetPlayer, setTargetPlayer] = useState<string>('');
  const [processingCommandId, setProcessingCommandId] = useState<string | null>(
    null,
  );

  const [prankDialogOpen, setPrankDialogOpen] = useState(false);
  const [selectedPrank, setSelectedPrank] = useState<PrankCommand | null>(null);

  const [prankTarget, setPrankTarget] = useState('');
  const [prankServerId, setPrankServerId] = useState<string>('');
  const [prankProcessing, setPrankProcessing] = useState(false);

  // Уведомления
  const [notification, setNotification] = useState<{
    open: boolean;
    message: string;
    type: 'success' | 'error';
  }>({
    open: false,
    message: '',
    type: 'success',
  });

  const showNotification = (
    message: React.ReactNode,
    severity: 'success' | 'info' | 'warning' | 'error' = 'info',
    position: NotificationPosition = getNotifPositionFromSettings(),
  ) => {
    if (!isNotificationsEnabled()) return;
    setNotifMsg(message);
    setNotifSeverity(severity);
    setNotifPos(position);
    setNotifOpen(true);
  };

  const loadBonuses = async (username: string) => {
    try {
      setBonusesLoading(true);
      const [types, user] = await Promise.all([
        fetchBonusTypes(),
        fetchUserBonuses(username),
      ]);
      setBonusTypes(types);
      setUserBonuses(user);
    } catch (error) {
      console.error('Ошибка при получении прокачек:', error);

      if (!isNotificationsEnabled()) return;
      showNotification('Ошибка при загрузке прокачки!', 'error');
    } finally {
      setBonusesLoading(false);
    }
  };

  const loadPlayerSkin = async (uuid: string) => {
    try {
      const player = await fetchPlayer(uuid);
      setPlayerSkinUrl(player.skin_url);
    } catch (error) {
      console.error('Ошибка при получении скина игрока:', error);
      setPlayerSkinUrl('');
    }
  };

  // Функция для загрузки плащей из магазина
  const loadStoreCapes = async () => {
    try {
      const capes = await fetchCapesStore();
      setStoreCapes(capes);
    } catch (error) {
      console.error('Ошибка при получении плащей магазина:', error);
      setStoreCapes([]);
    }
  };

  // Загрузка команд
  useEffect(() => {
    if (tabValue !== 3) return;

    const load = async () => {
      try {
        setPranksLoading(true);
        const [commands, servers] = await Promise.all([
          fetchPrankCommands(),
          fetchPrankServers(),
        ]);
        setPrankCommands(commands);
        setPrankServers(servers);
        if (servers.length) setSelectedPrankServer(servers[0].id);
      } catch (e) {
        console.error(e);
        showNotification('Ошибка загрузки пакостей', 'error');
      } finally {
        setPranksLoading(false);
      }
    };

    load();
  }, [tabValue]);

  // Функция для загрузки плащей пользователя
  const loadUserCapes = async (username: string) => {
    try {
      const userCapes = await fetchCapes(username);
      setUserCapes(userCapes);
    } catch (error) {
      console.error('Ошибка при получении плащей пользователя:', error);
      setUserCapes([]);
    }
  };

  const handlePurchaseCape = async (cape_id: string) => {
    try {
      await purchaseCape(username, cape_id);
      await loadUserCapes(username);

      playBuySound();

      if (!isNotificationsEnabled()) return;
      showNotification('Плащ успешно куплен!', 'success');
    } catch (error) {
      console.error('Ошибка при покупке плаща:', error);

      if (!isNotificationsEnabled()) return;
      showNotification('Ошибка при покупке плаща!', 'error');
    }
  };

  // Загрузка кейсов
  const loadCases = async () => {
    try {
      setCasesLoading(true);
      const casesData = await fetchCases();
      setCases(casesData);
    } catch (error) {
      console.error('Ошибка при получении кейсов:', error);
      setCases([]);
    } finally {
      setCasesLoading(false);
    }
  };

  // Проверка онлайна игрока (по аналогии с Marketplace.tsx)
  const checkPlayerStatus = async () => {
    if (!username) return;

    try {
      setOnlineCheckLoading(true);
      const { online, server } = await getPlayerServer(username);
      setIsOnline(online);
      setPlayerServer(server || null);
    } catch (error) {
      console.error('Ошибка при проверке онлайн-статуса:', error);
      setIsOnline(false);
      setPlayerServer(null);
    } finally {
      setOnlineCheckLoading(false);
    }
  };

  // Загружаем базовые данные при монтировании
  useEffect(() => {
    const savedConfig = localStorage.getItem('launcher_config');
    if (savedConfig) {
      const config = JSON.parse(savedConfig);
      if (config.uuid && config.username) {
        setUsername(config.username);
        setUuid(config.uuid);

        setLoading(true);

        Promise.all([
          loadStoreCapes(),
          loadUserCapes(config.username),
          loadCases(),
          loadPlayerSkin(config.uuid),
          loadBonuses(config.username),
        ])
          .catch((err) => console.error(err))
          .finally(() => {
            setLoading(false);
          });
      }
    }
  }, []);

  // Проверяем онлайн после того, как знаем username
  useEffect(() => {
    if (username) {
      checkPlayerStatus();
    }
  }, [username]);

  const withProcessing = async (id: string, fn: () => Promise<void>) => {
    setProcessingBonusIds((prev) => [...prev, id]);
    try {
      await fn();
    } finally {
      setProcessingBonusIds((prev) => prev.filter((x) => x !== id));
    }
  };

  const handlePurchaseBonus = async (bonusTypeId: string) => {
    if (!username) {
      if (!isNotificationsEnabled()) return;
      showNotification(
        'Не найдено имя игрока. Авторизируйтесь в лаунчере!',
        'error',
      );
      return;
    }

    await withProcessing(bonusTypeId, async () => {
      try {
        const res = await purchaseBonus(username, bonusTypeId);

        playBuySound();

        await loadBonuses(username);

        if (!isNotificationsEnabled()) return;
        showNotification('Прокачка успешно куплена!', 'success');
      } catch (error) {
        console.error('Ошибка при покупке прокачки:', error);

        if (!isNotificationsEnabled()) return;
        showNotification('Ошибка при прокачке!', 'error');
      }
    });
  };

  const handleUpgradeBonus = async (bonusId: string) => {
    if (!username) return;

    await withProcessing(bonusId, async () => {
      try {
        await upgradeBonus(username, bonusId);

        await loadBonuses(username);

        if (!isNotificationsEnabled()) return;
        showNotification('Бонус улучшен!', 'success');
      } catch (error) {
        console.error('Ошибка при улучшении бонуса:', error);

        if (!isNotificationsEnabled()) return;
        showNotification('Ошибка при улучшении бонуса!', 'error');
      }
    });
  };

  const handleToggleBonusActivation = async (bonusId: string) => {
    if (!username) return;

    await withProcessing(bonusId, async () => {
      try {
        await toggleBonusActivation(username, bonusId);
        await loadBonuses(username);
      } catch (error) {
        console.error('Ошибка при переключении бонуса:', error);
        if (!isNotificationsEnabled()) return;
        showNotification('Ошибка при переключении бонуса!', 'error');
      }
    });
  };

  const caseServers = Array.from(
    new Set((cases || []).flatMap((c) => c.server_ips || []).filter(Boolean)),
  );

  useEffect(() => {
    if (caseServers.length > 0) {
      // если игрок онлайн — по умолчанию его сервер, если он есть в кейсах
      const preferred =
        playerServer?.ip && caseServers.includes(playerServer.ip)
          ? playerServer.ip
          : caseServers[0];

      setSelectedCaseServerIp(preferred);
    }
  }, [caseServers.length, playerServer?.ip]);

  const filteredCases = (cases || []).filter((c) => {
    const allowed = c.server_ips || [];
    // если список пуст — значит кейс доступен везде
    if (allowed.length === 0) return true;

    // иначе — показываем только те, где выбранный сервер разрешён
    return !!selectedCaseServerIp && allowed.includes(selectedCaseServerIp);
  });

  // Фильтруем плащи, которые уже куплены пользователем
  const availableCapes = storeCapes.filter(
    (storeCape) =>
      !userCapes.some((userCape) => userCape.cape_id === storeCape.id),
  );

  const handleOpenCase = async (caseData: Case) => {
    if (!username) {
      if (!isNotificationsEnabled()) return;
      showNotification(
        'Не найдено имя игрока. Авторизуйтесь в лаунчере!',
        'error',
      );
      return;
    }

    if (!selectedCaseServerIp) {
      if (!isNotificationsEnabled()) return;
      showNotification('Выберите сервер для открытия кейса!', 'warning');
      return;
    }

    const allowedIps = caseData.server_ips || [];
    if (allowedIps.length > 0 && !allowedIps.includes(selectedCaseServerIp)) {
      if (!isNotificationsEnabled()) return;
      showNotification(
        `Этот кейс доступен на: ${allowedIps
          .map((ip) => translateServer(`Server ${ip}`))
          .join(', ')}`,
        'warning',
      );
      return;
    }

    if (isOpening) return;

    try {
      setIsOpening(true);

      const fullCase = await fetchCase(caseData.id);
      const caseItems: CaseItem[] = fullCase.items || [];
      setSelectedCase(fullCase);

      // ✅ открываем на выбранном сервере (даже если игрок не на сервере)
      const result = await openCase(
        fullCase.id,
        username,
        selectedCaseServerIp,
      );

      setRouletteCaseItems(caseItems);
      setRouletteReward(result.reward);
      setRouletteOpen(true);
      playBuySound();

      if (!isNotificationsEnabled()) return;
      showNotification('Кейс открыт!', 'success');
    } catch (error) {
      console.error('Ошибка при открытии кейса:', error);

      if (!isNotificationsEnabled()) return;
      showNotification(
        String(
          error instanceof Error ? error.message : 'Ошибка при открытии кейса!',
        ),
        'error',
      );
    } finally {
      setIsOpening(false);
    }
  };

  const handleCloseNotification = () => {
    setNotification((prev) => ({ ...prev, open: false }));
  };

  const handleCloseRoulette = () => {
    setRouletteOpen(false);
  };

  useEffect(() => {
    const onFirstUserGesture = () => primeSounds();

    window.addEventListener('pointerdown', onFirstUserGesture, { once: true });
    return () => window.removeEventListener('pointerdown', onFirstUserGesture);
  }, []);

  return (
    <Box
      sx={{
        display: 'flex',
        gap: '2vw',
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'center',
        overflow: 'hidden',
      }}
    >
      {(loading || onlineCheckLoading) && (
        <FullScreenLoader message="Загрузка магазина..." />
      )}

      {!loading && !onlineCheckLoading && (
        <Box
          sx={{
            display: 'flex',
            flexDirection: 'column',
            width: '100%',
            height: '100%',
            overflow: 'auto',
            paddingBottom: '2w',
            paddingLeft: '7vw',
            paddingRight: '1.5vw',
            gap: '2vw',
          }}
        >
          <Tabs
            value={tabValue}
            onChange={handleTabChange}
            disableRipple
            sx={{
              // minHeight: '3vw',
              // mb: '1.2vw',
              '& .MuiTabs-indicator': {
                height: '0.35vw',
                borderRadius: '999px',
                background: GRADIENT,
              },
              '&:focus': {
                background: 'transparent',
              },
            }}
          >
            {['Прокачка', 'Кейсы', 'Плащи', 'Предметы'].map((label) => (
              <Tab
                key={label}
                label={label}
                disableRipple
                sx={{
                  minHeight: '3vw',
                  fontFamily: 'Benzin-Bold',
                  color: 'rgba(255,255,255,0.85)',
                  textTransform: 'uppercase',
                  letterSpacing: 0.4,
                  borderRadius: '999px',
                  mx: '0.2vw',
                  '&.Mui-selected': {
                    color: '#fff',
                  },
                  '&:hover': {
                    color: '#fff',
                    background: 'rgba(255,255,255,0.06)',
                  },
                  '&:focus': {
                    background: 'transparent',
                  },
                  transition: 'all 0.18s ease',
                }}
              />
            ))}
          </Tabs>
          <TabPanel value={tabValue} index={0}>
            {/* Блок прокачки */}
            <Box
              sx={{
                display: 'flex',
                flexDirection: 'column',
                gap: 2,
              }}
            >
              {/* <Typography
                variant="h6"
                sx={{
                  fontFamily: 'Benzin-Bold',
                  backgroundImage:
                    'linear-gradient(136deg, rgb(242,113,33), rgb(233,64,87), rgb(138,35,135))',
                  WebkitBackgroundClip: 'text',
                  WebkitTextFillColor: 'transparent',
                }}
              >
                Прокачка
              </Typography> */}

              {bonusesLoading ? (
                <FullScreenLoader
                  fullScreen={false}
                  message="Загрузка прокачки..."
                />
              ) : bonusTypes.length > 0 ? (
                <Grid container spacing={2} sx={{ mb: 4 }}>
                  {bonusTypes.map((bt) => {
                    const userBonus = userBonuses.find(
                      (ub) => ub.bonus_type_id === bt.id,
                    );
                    const owned = !!userBonus;

                    const level = owned ? userBonus!.level : 0;
                    const effectValue = owned
                      ? userBonus!.effect_value
                      : bt.base_effect_value;
                    const nextEffectValue =
                      owned && userBonus!.can_upgrade
                        ? bt.base_effect_value +
                          userBonus!.level * bt.effect_increment
                        : undefined;

                    const isActive = owned ? userBonus!.is_active : false;
                    const isPermanent = owned
                      ? userBonus!.is_permanent
                      : bt.duration === 0;

                    const cardId = owned ? userBonus!.id : bt.id;
                    const processing = processingBonusIds.includes(cardId);

                    return (
                      <Grid item xs={12} sm={6} md={4} lg={3} key={bt.id}>
                        <BonusShopItem
                          id={cardId}
                          name={bt.name}
                          description={bt.description}
                          imageUrl={bt.image_url}
                          level={level}
                          effectValue={effectValue}
                          nextEffectValue={nextEffectValue}
                          price={bt.price}
                          upgradePrice={bt.upgrade_price}
                          canUpgrade={userBonus?.can_upgrade ?? false}
                          mode={owned ? 'upgrade' : 'buy'}
                          isActive={isActive}
                          isPermanent={isPermanent}
                          disabled={processing}
                          onBuy={
                            !owned
                              ? () => handlePurchaseBonus(bt.id)
                              : undefined
                          }
                          onUpgrade={
                            owned
                              ? () => handleUpgradeBonus(userBonus!.id)
                              : undefined
                          }
                          onToggleActive={
                            owned
                              ? () => handleToggleBonusActivation(userBonus!.id)
                              : undefined
                          }
                        />
                      </Grid>
                    );
                  })}
                </Grid>
              ) : (
                <Typography>Прокачка временно недоступна.</Typography>
              )}
            </Box>
          </TabPanel>

          <TabPanel value={tabValue} index={1}>
            {/* Блок кейсов */}
            <Box
              sx={{
                display: 'flex',
                alignItems: 'flex-start',
                gap: 2,
                mb: 1,
                flexDirection: 'column',
              }}
            >
              {caseServers.length > 1 ? (
              <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
                <Typography
                  variant="h6"
                  sx={{
                    fontFamily: 'Benzin-Bold',
                    backgroundImage:
                      'linear-gradient(136deg, rgb(242,113,33), rgb(233,64,87), rgb(138,35,135))',
                    WebkitBackgroundClip: 'text',
                    WebkitTextFillColor: 'transparent',
                  }}
                >
                  Выберите сервер:
                </Typography>

                <FormControl
                  size="small"
                  sx={{
                    // textTransform: 'uppercase',
                    // чтобы по ширине вел себя как бейдж
                    // minWidth: '18vw',
                    // maxWidth: '28vw',

                    '& .MuiInputLabel-root': { display: 'none' },

                    '& .MuiOutlinedInput-root': {
                      borderRadius: '3vw',
                      position: 'relative',
                      px: '1.2vw',
                      py: '0.5vw',

                      color: 'rgba(255,255,255,0.95)',
                      background:
                        'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.20), transparent 55%), radial-gradient(circle at 90% 20%, rgba(233,64,205,0.16), transparent 55%), rgba(10,10,20,0.92)',
                      border: '1px solid rgba(255,255,255,0.10)',
                      boxShadow: '0 1.4vw 3.8vw rgba(0,0,0,0.55)',
                      backdropFilter: 'blur(14px)',
                      overflow: 'hidden',

                      transition: 'transform 0.18s ease, filter 0.18s ease',
                      '&:hover': {
                        transform: 'scale(1.02)',
                        // filter: 'brightness(1.03)',
                      },

                      '& .MuiOutlinedInput-notchedOutline': {
                        border: 'none',
                      },

                      // нижняя градиентная полоска как у username
                      '&:after': {
                        content: '""',
                        position: 'absolute',
                        left: '0%',
                        right: '0%',
                        bottom: 0,
                        height: '0.15vw',
                        borderRadius: '999px',
                        background: GRADIENT,
                        opacity: 0.9,
                        pointerEvents: 'none',
                        width: '100%',
                      },
                    },

                    '& .MuiSelect-select': {
                      // стиль текста как у плашки username
                      fontFamily: 'Benzin-Bold',
                      fontSize: '1.9vw',
                      lineHeight: 1.1,
                      textAlign: 'center',

                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',

                      // убираем “инпутный” паддинг
                      padding: 0,
                      minHeight: 'unset',

                      // чтобы длинные названия не ломали
                      whiteSpace: 'nowrap',
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                    },
                  }}
                >
                  <Select
                    labelId="cases-server-label"
                    label="Сервер"
                    value={selectedCaseServerIp}
                    onChange={(e) =>
                      setSelectedCaseServerIp(String(e.target.value))
                    }
                    MenuProps={{
                      PaperProps: {
                        sx: {
                          mt: 1,
                          bgcolor: 'rgba(10,10,20,0.96)',
                          border: '1px solid rgba(255,255,255,0.10)',
                          borderRadius: '1vw',
                          backdropFilter: 'blur(14px)',
                         '& .MuiMenuItem-root': {
                            color: 'rgba(255,255,255,0.9)',
                            fontFamily: 'Benzin-Bold',
                            fontSize: '1.1vw',
                          },
                          '& .MuiMenuItem-root.Mui-selected': {
                            backgroundColor: 'rgba(242,113,33,0.18)',
                          },
                          '& .MuiMenuItem-root:hover': {
                            backgroundColor: 'rgba(233,64,205,0.14)',
                          },
                        },
                      },
                    }}
                  >
                    {caseServers.map((ip) => (
                      <MenuItem key={ip} value={ip}>
                        {translateServer(`Server ${ip}`)}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
              </Box>
              ) : (
                <Box sx={{ display: 'flex', alignItems: 'center', gap: '1vw', position: 'absolute', top: '93%', left: '35%' }}>
                  <Typography
                    variant="h6"
                    sx={{
                      fontFamily: 'Benzin-Bold',
                      backgroundImage:
                        'linear-gradient(136deg, rgb(242,113,33), rgb(233,64,87), rgb(138,35,135))',
                      WebkitBackgroundClip: 'text',
                      WebkitTextFillColor: 'transparent',
                    }}
                  >
                  Сервер:
                </Typography>
                  <Typography
                    variant="h6"
                    sx={{
                      fontFamily: 'Benzin-Bold',
                      alignSelf: 'center',
                      justifySelf: 'center',
                      textAlign: 'center',
                      fontSize: '2vw',
                      position: 'relative',
                      px: '1vw',
                      borderRadius: '3vw',
                      color: 'rgba(255,255,255,0.95)',
                      background:
                      'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.20), transparent 55%), radial-gradient(circle at 90% 20%, rgba(233,64,205,0.16), transparent 55%), rgba(10,10,20,0.92)',
                      border: '1px solid rgba(255,255,255,0.10)',
                      boxShadow: '0 1.4vw 3.8vw rgba(0,0,0,0.55)',
                      backdropFilter: 'blur(14px)',
                      overflow: 'hidden',
                      '&:after': {
                        content: '""',
                        position: 'absolute',
                        left: '8%',
                        right: '8%',
                        bottom: 0,
                        height: '0.35vw',
                        borderRadius: '999px',
                        background: GRADIENT,
                        opacity: 0.9,
                      },
                    }}
                  >
                    {caseServers.map((ip) => (
                      <MenuItem key={ip} value={ip} sx={{ fontFamily: 'Benzin-Bold' }}>
                        {translateServer(`Server ${ip}`)}
                      </MenuItem>
                    ))}
                  </Typography>
                </Box>
              )}

              {casesLoading ? (
                <FullScreenLoader
                  fullScreen={false}
                  message="Загрузка кейсов..."
                />
              ) : cases.length > 0 ? (
                <Grid container spacing={2} sx={{ mb: 4 }}>
                  {filteredCases.map((c) => (
                    <Grid item xs={12} sm={6} md={4} lg={3} key={c.id}>
                      <ShopItem
                        type="case"
                        id={c.id}
                        name={c.name}
                        description={c.description}
                        imageUrl={c.image_url}
                        price={c.price}
                        itemsCount={c.items_count}
                        isOpening={isOpening && selectedCase?.id === c.id}
                        disabled={isOpening || !selectedCaseServerIp}
                        onClick={() => handleOpenCase(c)}
                      />
                    </Grid>
                  ))}
                </Grid>
              ) : (
                <Typography>Кейсы временно недоступны.</Typography>
              )}
            </Box>
          </TabPanel>

          <TabPanel value={tabValue} index={2}>
            {/* Блок плащей */}
            <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <Typography
                variant="h6"
                sx={{
                  fontFamily: 'Benzin-Bold',
                  backgroundImage:
                    'linear-gradient(136deg, rgb(242,113,33), rgb(233,64,87), rgb(138,35,135))',
                  WebkitBackgroundClip: 'text',
                  WebkitTextFillColor: 'transparent',
                }}
              >
                Плащи
              </Typography>

              {availableCapes.length > 0 ? (
                <Grid container spacing={2}>
                  {availableCapes.map((cape) => (
                    <Grid item xs={12} sm={6} md={4} lg={3} key={cape.id}>
                      <ShopItem
                        type="cape"
                        id={cape.id}
                        name={cape.name}
                        description={cape.description}
                        imageUrl={cape.image_url}
                        price={cape.price}
                        disabled={false}
                        playerSkinUrl={playerSkinUrl}
                        onClick={() => handlePurchaseCape(cape.id)}
                      />
                    </Grid>
                  ))}
                </Grid>
              ) : (
                <Typography>У вас уже есть все доступные плащи!</Typography>
              )}
            </Box>
          </TabPanel>

          <TabPanel value={tabValue} index={3}>
            <Grid container spacing={2}>
              {prankCommands.map((cmd) => (
                <Grid item xs={12} sm={6} md={4} lg={3} key={cmd.id}>
                  <Box
                    sx={{
                      width: '20vw',
                      height: '100%',
                      borderRadius: '1.4vw',
                      background:
                        'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.14), transparent 55%), rgba(10,10,20,0.88)',
                      border: '1px solid rgba(255,255,255,0.10)',
                      boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)',
                      backdropFilter: 'blur(14px)',
                      display: 'flex',
                      flexDirection: 'column',
                      overflow: 'hidden',
                      transition: 'transform 0.18s ease',
                      '&:hover': {
                        transform: 'scale(1.03)',
                      },
                    }}
                  >
                    {/* Картинка */}
                    <Box
                      sx={{
                        height: '9vw',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        background: 'rgba(0,0,0,0.25)',
                      }}
                    >
                      <Box
                        component="img"
                        src={`https://cdn.minecraft.popa-popa.ru/textures/${cmd.material?.toLowerCase()}.png`}
                        alt={cmd.material}
                        sx={{
                          width: '6vw',
                          height: '6vw',
                          imageRendering: 'pixelated',
                        }}
                      />
                    </Box>

                    {/* Контент */}
                    <Box
                      sx={{
                        p: '1vw',
                        display: 'flex',
                        flexDirection: 'column',
                        gap: '0.6vw',
                        flexGrow: 1,
                      }}
                    >
                      <Typography
                        sx={{
                          fontFamily: 'Benzin-Bold',
                          fontSize: '1.1vw',
                          background: GRADIENT,
                          WebkitBackgroundClip: 'text',
                          WebkitTextFillColor: 'transparent',
                        }}
                      >
                        {cmd.name}
                      </Typography>

                      <Typography
                        sx={{
                          color: 'rgba(255,255,255,0.75)',
                          fontSize: '0.95vw',
                          flexGrow: 1,
                        }}
                      >
                        {cmd.description}
                      </Typography>

                      <Typography
                        sx={{
                          fontWeight: 900,
                          fontSize: '1vw',
                        }}
                      >
                        Цена: {cmd.price} монет
                      </Typography>

                      <Button
                        disableRipple
                        onClick={() => {
                          setSelectedPrank(cmd);
                          setPrankTarget('');
                          setPrankDialogOpen(true);
                        }}
                        sx={{
                          mt: '0.6vw',
                          borderRadius: '999px',
                          fontFamily: 'Benzin-Bold',
                          color: '#fff',
                          background: GRADIENT,
                          py: '0.5vw',
                          '&:hover': { filter: 'brightness(1.05)' },
                        }}
                      >
                        Купить
                      </Button>
                    </Box>
                  </Box>
                </Grid>
              ))}
            </Grid>
          </TabPanel>
        </Box>
      )}

      <Dialog
        open={prankDialogOpen}
        onClose={() => setPrankDialogOpen(false)}
        fullWidth
        maxWidth="xs"
        PaperProps={{ sx: GLASS_DIALOG_SX }}
      >
        <DialogTitle sx={{ fontFamily: 'Benzin-Bold' }}>
          {selectedPrank?.name}
        </DialogTitle>

        <DialogContent dividers sx={{ borderColor: 'rgba(255,255,255,0.10)' }}>
          <Typography sx={{ opacity: 0.75, mb: 2 }}>
            {selectedPrank?.description}
          </Typography>

          {/* сервер */}
          <FormControl fullWidth sx={{ mb: 2 }}>
            <Select
              value={prankServerId}
              onChange={(e) => setPrankServerId(String(e.target.value))}
              displayEmpty
            >
              <MenuItem disabled value="">
                Выберите сервер
              </MenuItem>
              {prankServers.map((s) => (
                <MenuItem key={s.id} value={s.id}>
                  {translateServer(s.name)} ({s.online_players}/{s.max_players})
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          {/* цель */}
          <TextField
            fullWidth
            label="Ник игрока"
            value={prankTarget}
            onChange={(e) => setPrankTarget(e.target.value)}
          />
        </DialogContent>

        <DialogActions sx={{ p: '1.2vw' }}>
          <Button
            onClick={() => setPrankDialogOpen(false)}
            sx={{ color: 'rgba(255,255,255,0.75)', fontFamily: 'Benzin-Bold' }}
          >
            Отмена
          </Button>

          <Button
            disabled={!prankTarget || !prankServerId || prankProcessing}
            onClick={async () => {
              if (!selectedPrank) return;

              try {
                setPrankProcessing(true);
                await executePrank(
                  username,
                  selectedPrank.id,
                  prankTarget,
                  prankServerId,
                );

                playBuySound();
                showNotification(
                  selectedPrank.globalDescription
                    .replace('{username}', username)
                    .replace('{targetPlayer}', prankTarget),
                  'success',
                );

                setPrankDialogOpen(false);
              } catch (e) {
                showNotification(
                  e instanceof Error ? e.message : 'Ошибка выполнения',
                  'error',
                );
              } finally {
                setPrankProcessing(false);
              }
            }}
            sx={{
              fontFamily: 'Benzin-Bold',
              color: '#fff',
              background: GRADIENT,
              borderRadius: '999px',
              px: '1.6vw',
            }}
          >
            Подтвердить
          </Button>
        </DialogActions>
      </Dialog>

      {/* Компонент с анимацией рулетки */}
      <CaseRoulette
        open={rouletteOpen}
        onClose={handleCloseRoulette}
        caseName={selectedCase?.name}
        items={rouletteCaseItems}
        reward={rouletteReward}
      />

      {/* Уведомления */}
      <CustomNotification
        open={notifOpen}
        message={notifMsg}
        severity={notifSeverity}
        position={notifPos}
        onClose={() => setNotifOpen(false)}
        autoHideDuration={2500}
      />
    </Box>
  );
}
