import {
  Box, Typography, Button, Grid,
  FormControl, Select, MenuItem, InputLabel
} 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 { isNotificationsEnabled, getNotifPositionFromSettings } from '../utils/notifications';
import { translateServer } from '../utils/serverTranslator';

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)'; // сероватый
  }
}

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);

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

  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;
      setNotifMsg('Ошибка при загрузке прокачки!');
      setNotifSeverity('error');
      setNotifPos({ vertical: 'top', horizontal: 'center' });
      setNotifOpen(true);
    } 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([]);
    }
  };

  // Функция для загрузки плащей пользователя
  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;
      setNotifMsg('Плащ успешно куплен!');
      setNotifSeverity('success');
      setNotifPos({ vertical: 'top', horizontal: 'center' });
      setNotifOpen(true);
    } catch (error) {
      console.error('Ошибка при покупке плаща:', error);

      if (!isNotificationsEnabled()) return;
      setNotifMsg('Ошибка при покупке плаща!');
      setNotifSeverity('error');
      setNotifPos({ vertical: 'top', horizontal: 'center' });
      setNotifOpen(true);
    }
  };

  // Загрузка кейсов
  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;
      setNotifMsg('Не найдено имя игрока. Авторизируйтесь в лаунчере!');
      setNotifSeverity('error');
      setNotifPos({ vertical: 'top', horizontal: 'center' });
      setNotifOpen(true);
      return;
    }

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

        playBuySound();

        await loadBonuses(username);

        if (!isNotificationsEnabled()) return;
        setNotifMsg('Прокачка успешно куплена!');
        setNotifSeverity('success');
        setNotifPos({ vertical: 'top', horizontal: 'center' });
        setNotifOpen(true);
      } catch (error) {
        console.error('Ошибка при покупке прокачки:', error);

        if (!isNotificationsEnabled()) return;
        setNotifMsg('Ошибка при прокачке!');
        setNotifSeverity('error');
        setNotifPos({ vertical: 'top', horizontal: 'center' });
        setNotifOpen(true);
      }
    });
  };

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

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

        await loadBonuses(username);

        if (!isNotificationsEnabled()) return;
        setNotifMsg('Бонус улучшен!');
        setNotifSeverity('success');
        setNotifPos({ vertical: 'top', horizontal: 'center' });
        setNotifOpen(true);
      } catch (error) {
        console.error('Ошибка при улучшении бонуса:', error);

        if (!isNotificationsEnabled()) return;
        setNotifMsg('Ошибка при улучшении бонуса!');
        setNotifSeverity('error');
        setNotifPos({ vertical: 'top', horizontal: 'center' });
        setNotifOpen(true);
      }
    });
  };

  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;
        setNotifMsg('Ошибка при переключении бонуса!');
        setNotifSeverity('error');
        setNotifPos({ vertical: 'top', horizontal: 'center' });
        setNotifOpen(true);
      }
    });
  };

  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;
    setNotifMsg('Не найдено имя игрока. Авторизуйтесь в лаунчере!');
    setNotifSeverity('error');
    setNotifPos({ vertical: 'top', horizontal: 'center' });
    setNotifOpen(true);
    return;
  }

  if (!selectedCaseServerIp) {
    if (!isNotificationsEnabled()) return;
    setNotifMsg('Выберите сервер для открытия кейса!');
    setNotifSeverity('warning');
    setNotifPos({ vertical: 'top', horizontal: 'center' });
    setNotifOpen(true);
    return;
  }

  const allowedIps = caseData.server_ips || [];
  if (allowedIps.length > 0 && !allowedIps.includes(selectedCaseServerIp)) {
    if (!isNotificationsEnabled()) return;
    setNotifMsg(
      `Этот кейс доступен на: ${allowedIps
        .map((ip) => translateServer(`Server ${ip}`))
        .join(', ')}`,
    );
    setNotifSeverity('warning');
    setNotifPos({ vertical: 'top', horizontal: 'center' });
    setNotifOpen(true);
    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;
    setNotifMsg('Кейс открыт!');
    setNotifSeverity('success');
    setNotifPos({ vertical: 'top', horizontal: 'center' });
    setNotifOpen(true);
  } catch (error) {
    console.error('Ошибка при открытии кейса:', error);

    if (!isNotificationsEnabled()) return;
    setNotifMsg(String(error instanceof Error ? error.message : 'Ошибка при открытии кейса!'));
    setNotifSeverity('error');
    setNotifPos({ vertical: 'top', horizontal: 'center' });
    setNotifOpen(true);
  } 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%',
            gap: '2vw',
            overflow: 'auto',
            paddingBottom: '5vw',
            paddingLeft: '2.5vw',
            paddingRight: '1.5vw',
          }}
        >
          {/* Блок прокачки */}
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: 2,
              mt: '2vh'
            }}
          >
            <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>

          {/* Блок кейсов */}
          <Box
            sx={{
              display: 'flex',
              alignItems: 'flex-start',
              gap: 2,
              mb: 1,
              flexDirection: 'column',
            }}
          >
            <Box sx={{ display: 'flex', 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>

              {caseServers.length > 0 && (
              <FormControl size="small" sx={{ minWidth: 220 }}>
              <InputLabel id="cases-server-label" sx={{ fontFamily: 'Benzin-Bold', color: 'rgba(255,255,255,0.75)' }}>
                Сервер
              </InputLabel>
              <Select
                labelId="cases-server-label"
                label="Сервер"
                value={selectedCaseServerIp}
                onChange={(e) => setSelectedCaseServerIp(String(e.target.value))}
                MenuProps={{
                    PaperProps: {
                      sx: {
                        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',
                        },
                        '& .MuiMenuItem-root.Mui-selected': {
                          backgroundColor: 'rgba(242,113,33,0.16)',
                        },
                        '& .MuiMenuItem-root:hover': {
                          backgroundColor: 'rgba(233,64,205,0.14)',
                        },
                      },
                    },
                  }}
                  sx={{
                    borderRadius: '999px',
                    bgcolor: 'rgba(255,255,255,0.04)',
                    color: 'rgba(255,255,255,0.92)',
                    fontFamily: 'Benzin-Bold',
                    '& .MuiSelect-select': {
                      py: '0.9vw',
                      px: '1.2vw',
                    },
                    '& .MuiOutlinedInput-notchedOutline': {
                      borderColor: 'rgba(255,255,255,0.14)',
                    },
                    '&:hover .MuiOutlinedInput-notchedOutline': {
                      borderColor: 'rgba(242,113,33,0.55)',
                    },
                    '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
                      borderColor: 'rgba(233,64,205,0.65)',
                      borderWidth: '2px',
                    },
                    '& .MuiSelect-icon': {
                      color: 'rgba(255,255,255,0.75)',
                    },
                  }}
              >
                {caseServers.map((ip) => (
                  <MenuItem key={ip} value={ip}>
                    {translateServer(`Server ${ip}`)}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
            )}
            </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>

          {/* Блок плащей (как был) */}

          {/* Блок плащей */}
          <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>
        </Box>
      )}

      {/* Компонент с анимацией рулетки */}
      <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>
  );
}
