import { useEffect, useState } from 'react';
import { Box, Typography, Grid, Button, Paper, FormControl, Select, MenuItem, InputLabel  } from '@mui/material';

import { FullScreenLoader } from '../components/FullScreenLoader';
import { translateServer } from '../utils/serverTranslator';
import {
  fetchInventoryItems,
  withdrawInventoryItem,
  type InventoryRawItem,
  type InventoryItemsResponse,
} from '../api';
import CustomTooltip from '../components/Notifications/CustomTooltip';
import { getPlayerServer } from '../utils/playerOnlineCheck';

const KNOWN_SERVER_IPS = [
  'minecraft.hub.popa-popa.ru',
  'minecraft.survival.popa-popa.ru',
  'minecraft.minigames.popa-popa.ru',
];

const STORAGE_KEY = 'inventory_layout';

function stripMinecraftColors(text?: string | null): string {
  if (!text) return '';
  return text.replace(/§[0-9A-FK-ORa-fk-or]/g, '');
}

const CARD_BG =
  'radial-gradient(circle at 10% 10%, rgba(242,113,33,0.14), transparent 55%), radial-gradient(circle at 90% 20%, rgba(233,64,205,0.12), transparent 55%), rgba(10,10,20,0.86)';

const CardFacePaperSx = {
  borderRadius: '1.2vw',
  background: CARD_BG,
  border: '1px solid rgba(255,255,255,0.08)',
  boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)',
  color: 'white',
} as const;

function readInventoryLayout(): any {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    return raw ? JSON.parse(raw) : {};
  } catch {
    return {};
  }
}

function writeInventoryLayout(next: any) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
}

function getLayout(username: string, serverIp: string): Record<string, number> {
  const inv = readInventoryLayout();
  return inv?.[username]?.[serverIp] ?? {};
}

function setLayout(username: string, serverIp: string, layout: Record<string, number>) {
  const inv = readInventoryLayout();
  inv[username] ??= {};
  inv[username][serverIp] = layout;
  writeInventoryLayout(inv);
}

function buildSlots(
  items: InventoryRawItem[],
  layout: Record<string, number>,
  size = 28,
): (InventoryRawItem | null)[] {
  const slots: (InventoryRawItem | null)[] = Array.from({ length: size }, () => null);

  const byId = new Map(items.map((it) => [it.id, it]));
  const used = new Set<string>();

  // 1) ставим туда, куда сохранено
  for (const [id, idx] of Object.entries(layout)) {
    const i = Number(idx);
    const it = byId.get(id);
    if (!it) continue;
    if (Number.isFinite(i) && i >= 0 && i < size && !slots[i]) {
      slots[i] = it;
      used.add(id);
    }
  }

  // 2) остальные — в первые пустые
  for (const it of items) {
    if (used.has(it.id)) continue;
    const empty = slots.findIndex((x) => x === null);
    if (empty === -1) break;
    slots[empty] = it;
    used.add(it.id);
  }

  return slots;
}

export default function Inventory() {
  const [username, setUsername] = useState('');
  const [loading, setLoading] = useState(true);
  const [availableServers, setAvailableServers] = useState<string[]>([]);
  const [selectedServerIp, setSelectedServerIp] = useState<string>('');
  const [items, setItems] = useState<InventoryRawItem[]>([]);
  const [page, setPage] = useState(1);
  const limit = 28;
  const [total, setTotal] = useState(0);
  const [pages, setPages] = useState(1);
  const [withdrawingIds, setWithdrawingIds] = useState<string[]>([]);
  const [hoveredId, setHoveredId] = useState<string | null>(null);

  const [isOnline, setIsOnline] = useState(false);
  const [playerServer, setPlayerServer] = useState<string | null>(null);
  const [checkingOnline, setCheckingOnline] = useState(false);

  const [draggedItemId, setDraggedItemId] = useState<string | null>(null);
  const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);
  const [dragPos, setDragPos] = useState<{ x: number; y: number } | null>(null);

  type SlotItem = InventoryRawItem | null;

  const [slots, setSlots] = useState<SlotItem[]>(() => Array.from({ length: 28 }, () => null));
  const [draggedFromIndex, setDraggedFromIndex] = useState<number | null>(null);

  useEffect(() => {
    const handleMove = (e: MouseEvent) => {
      if (!draggedItemId) return;
      setDragPos({ x: e.clientX, y: e.clientY });
    };

    const handleUp = () => {
      if (
        draggedItemId &&
        draggedFromIndex !== null &&
        dragOverIndex !== null &&
        draggedFromIndex !== dragOverIndex
      ) {
        setSlots((prev) => {
          const next = [...prev];
          const moving = next[draggedFromIndex];
          if (!moving) return prev;

          // ✅ swap или move в пустоту
          const target = next[dragOverIndex];
          next[dragOverIndex] = moving;
          next[draggedFromIndex] = target ?? null;

          // ✅ сохраняем layout (позиции предметов)
          const layout: Record<string, number> = {};
          next.forEach((it, idx) => {
            if (it) layout[it.id] = idx;
          });

          if (username && selectedServerIp) {
            setLayout(username, selectedServerIp, layout);
          }

          return next;
        });
      }

      setDraggedItemId(null);
      setDraggedFromIndex(null);
      setDragOverIndex(null);
      setDragPos(null);
    };

    window.addEventListener('mousemove', handleMove);
    window.addEventListener('mouseup', handleUp);

    return () => {
      window.removeEventListener('mousemove', handleMove);
      window.removeEventListener('mouseup', handleUp);
    };
  }, [draggedItemId, dragOverIndex]);

  useEffect(() => {
    const savedConfig = localStorage.getItem('launcher_config');
    if (!savedConfig) {
      setLoading(false);
      return;
    }

    const config = JSON.parse(savedConfig);
    if (config?.username) setUsername(config.username);
    setLoading(false);
  }, []);

  const detectServersWithItems = async (u: string) => {
    const checks = await Promise.allSettled(
      KNOWN_SERVER_IPS.map(async (ip) => {
        const res = await fetchInventoryItems(u, ip, 1, 1);
        return { ip, has: (res.items || []).length > 0 || (res.total ?? 0) > 0 };
      }),
    );

    return checks
      .filter(
        (r): r is PromiseFulfilledResult<{ ip: string; has: boolean }> => r.status === 'fulfilled',
      )
      .filter((r) => r.value.has)
      .map((r) => r.value.ip);
  };

  const loadInventory = async (u: string, ip: string, p: number) => {
    const res: InventoryItemsResponse = await fetchInventoryItems(u, ip, p, limit);
    const list = res.items || [];

    setItems(res.items || []);
    setTotal(res.total ?? 0);
    setPages(Math.max(1, Math.ceil((res.total ?? 0) / (res.limit ?? limit))));

    const layout = getLayout(u, ip);
    setSlots(buildSlots(list, layout, 28));
  };

  useEffect(() => {
    if (!username) return;

    let cancelled = false;

    (async () => {
      try {
        setLoading(true);

        const servers = await detectServersWithItems(username);
        if (cancelled) return;

        setAvailableServers(servers);

        const defaultIp = servers[0] || '';
        setSelectedServerIp(defaultIp);
        setPage(1);

        if (defaultIp) {
          await loadInventory(username, defaultIp, 1);
        } else {
          setItems([]);
          setTotal(0);
          setPages(1);
        }
      } catch (e) {
        console.error(e);
        setAvailableServers([]);
        setSelectedServerIp('');
        setItems([]);
        setTotal(0);
        setPages(1);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [username]);

  useEffect(() => {
    if (!username || !selectedServerIp) return;

    let cancelled = false;

    (async () => {
      try {
        setLoading(true);
        setPage(1);
        await loadInventory(username, selectedServerIp, 1);
      } catch (e) {
        console.error(e);
        setItems([]);
        setTotal(0);
        setPages(1);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [selectedServerIp]);

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

  const handleWithdraw = async (item: InventoryRawItem) => {
    if (!username || !selectedServerIp) return;

    // сервер в UI может не совпадать — оставим защиту
    if (selectedServerIp !== item.server_ip) {
      alert('Ошибка! Вы не на том сервере для выдачи этого предмета.');
      return;
    }

    await withWithdrawing(item.id, async () => {
      try {
        await withdrawInventoryItem({
          username,
          item_id: item.id,
          server_ip: selectedServerIp,
        });

        setItems((prevItems) => prevItems.filter((prevItem) => prevItem.id !== item.id));

        setSlots((prev) => {
          const next = prev.map((x) => (x?.id === item.id ? null : x));

          const layout: Record<string, number> = {};
          next.forEach((it, idx) => {
            if (it) layout[it.id] = idx;
          });

          setLayout(username, selectedServerIp, layout);
          return next;
        });
      } catch (e) {
        console.error('Ошибка при выводе предмета:', e);
      }
    });
  };

  const checkPlayerStatus = async () => {
    if (!username) return;

    setCheckingOnline(true);
    try {
      const res = await getPlayerServer(username);
      setIsOnline(!!res?.online);
      setPlayerServer(res?.server?.ip ?? null);
    } catch (e) {
      console.error('Ошибка проверки онлайна:', e);
      setIsOnline(false);
      setPlayerServer(null);
    } finally {
      setCheckingOnline(false);
    }
  };

  useEffect(() => {
    if (!username) return;
    checkPlayerStatus();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [username]);

  const headerServerName = selectedServerIp ? translateServer(`Server ${selectedServerIp}`) : '';

  if (!username) {
    return (
      <Box sx={{ p: '2vw' }}>
        <Typography sx={{ color: 'rgba(255,255,255,0.75)' }}>
          Не найдено имя игрока. Авторизуйтесь в лаунчере.
        </Typography>
      </Box>
    );
  }

  const canPrev = page > 1;
  const canNext = page < pages;

  const handlePrev = async () => {
    if (!canPrev || !username || !selectedServerIp) return;
    const nextPage = page - 1;
    setPage(nextPage);
    setLoading(true);
    try {
      await loadInventory(username, selectedServerIp, nextPage);
    } finally {
      setLoading(false);
    }
  };

  const handleNext = async () => {
    if (!canNext || !username || !selectedServerIp) return;
    const nextPage = page + 1;
    setPage(nextPage);
    setLoading(true);
    try {
      await loadInventory(username, selectedServerIp, nextPage);
    } finally {
      setLoading(false);
    }
  };

  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        width: '100%',
        height: '100%',
        overflow: 'auto',
        px: '2.5vw',
        py: '2vw',
        gap: 2,
        mt: '12vh',
      }}
    >
      {/* ШАПКА + ПАГИНАЦИЯ */}
      <Box
        sx={{
          display: 'flex',
          alignItems: 'center',
          gap: 2,
          flexWrap: 'wrap',
          justifyContent: 'space-evenly',
          flexDirection: 'row-reverse',
        }}
      >
        {!!selectedServerIp && (
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
            <Button
              variant="outlined"
              disabled={!canPrev || loading}
              onClick={handlePrev}
              sx={{
                borderRadius: '2.5vw',
                fontFamily: 'Benzin-Bold',
                color: 'white',
                border: '1px solid rgba(255,255,255,0.15)',
              }}
            >
              Назад
            </Button>

            <Typography sx={{ color: 'rgba(255,255,255,0.7)' }}>
              Страница {page} / {pages} • Всего: {total}
            </Typography>

            <Button
              variant="outlined"
              disabled={!canNext || loading}
              onClick={handleNext}
              sx={{
                borderRadius: '2.5vw',
                fontFamily: 'Benzin-Bold',
                color: 'white',
                border: '1px solid rgba(255,255,255,0.15)',
              }}
            >
              Вперёд
            </Button>
          </Box>
        )}

        {availableServers.length > 0 && (
          <FormControl size="small" sx={{ minWidth: 260 }}>
            <InputLabel
              id="inventory-server-label"
              sx={{ fontFamily: 'Benzin-Bold', color: 'rgba(255,255,255,0.75)' }}
            >
              Сервер
            </InputLabel>

            <Select
              labelId="inventory-server-label"
              label="Сервер"
              value={selectedServerIp}
              onChange={(e) => setSelectedServerIp(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)',
                },
              }}
            >
              {availableServers.map((ip) => (
                <MenuItem key={ip} value={ip}>
                  {translateServer(`Server ${ip}`)}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        )}

        <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',
          }}
        >
          Инвентарь {headerServerName ? `— ${headerServerName}` : ''}
        </Typography>
      </Box>

      {/* GRID */}
      {loading ? ( 
        <FullScreenLoader fullScreen={false} message="Загрузка инвентаря..." />
      ) : (
      <Grid container spacing={2}>
        {Array.from({ length: 28 }).map((_, index) => {
          const item = slots[index];

          // ПУСТАЯ ЯЧЕЙКА
          if (!item) {
            return (
              <Grid
              item
              xs={3}
              key={index}
              onMouseEnter={() => {
                if (draggedItemId) setDragOverIndex(index);
              }}
              sx={{
                outline:
                  draggedItemId && dragOverIndex === index
                    ? '2px dashed rgba(255,255,255,0.4)'
                    : 'none',
              }}
              >
                <Paper
                  elevation={0}
                  sx={{
                    ...CardFacePaperSx,
                    overflow: 'hidden',
                    width: '12vw',
                    height: '12vw',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    color: 'rgba(255,255,255,0.5)',
                  }}
                >
                  <Typography>Пусто</Typography>
                </Paper>
              </Grid>
            );
          }

          const displayNameRaw =
            item.item_data?.meta?.display_name ?? item.item_data?.material ?? 'Предмет';
          const displayName = stripMinecraftColors(displayNameRaw);

          const amount =
            (item as any)?.amount ??
            (item as any)?.item_data?.amount ??
            (item as any)?.item_data?.meta?.amount ??
            1;

          const isHovered = hoveredId === item.id;
          const isWithdrawing = withdrawingIds.includes(item.id);

          // ✅ проверка: игрок реально онлайн на нужном сервере
          const isOnRightServer = isOnline && playerServer === item.server_ip;
          const canWithdraw = isOnRightServer && !loading && !checkingOnline && !isWithdrawing;

          const texture = item.item_data?.material
            ? `https://cdn.minecraft.popa-popa.ru/textures/${item.item_data.material.toLowerCase()}.png`
            : '';

          return (
            <Grid
              item
              xs={3}
              key={item.id}
              onMouseEnter={() => {
                if (draggedItemId) setDragOverIndex(index);
              }}
              sx={{
                outline:
                  draggedItemId && dragOverIndex === index
                    ? '2px dashed rgba(255,255,255,0.4)'
                    : 'none',
              }}
            >
              <Box
                sx={{
                  width: '100%',
                  perspective: '1200px',
                  cursor: draggedItemId === item.id ? 'grabbing' : 'grab',
                  opacity: draggedItemId === item.id ? 0.4 : 1,
                }}
                onMouseEnter={() => setHoveredId(item.id)}
                onMouseLeave={() => setHoveredId(null)}
                onMouseDown={(e) => {
                  const target = e.target as HTMLElement;
                  if (target.closest('button')) return;

                  e.preventDefault();
                  setDraggedItemId(item.id);
                  setDraggedFromIndex(index);
                  setDragPos({ x: e.clientX, y: e.clientY });
                }}
              >
                <Box
                  sx={{
                    position: 'relative',
                    width: '12vw',
                    height: '12vw', // фиксированная высота = Grid не дергается
                    transformStyle: 'preserve-3d',
                    transition: 'transform 0.5s cubic-bezier(0.4, 0.2, 0.2, 1)',
                    transform: isHovered ? 'rotateY(180deg)' : 'rotateY(0deg)',
                  }}
                >
                  {/* FRONT */}
                  <Paper
                    elevation={0}
                    sx={{
                      ...CardFacePaperSx,
                      position: 'absolute',
                      inset: 0,
                      backfaceVisibility: 'hidden',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      overflow: 'hidden',
                    }}
                  >
                    <Box
                      component="img"
                      src={texture}
                      sx={{
                        width: '5vw',
                        height: '5vw',
                        objectFit: 'contain',
                        imageRendering: 'pixelated',
                        userSelect: 'none',
                        transition: 'transform 0.25s ease',
                        transform: isHovered ? 'scale(1.05)' : 'scale(1)',
                      }}
                      draggable={false}
                      alt={displayName}
                    />
                  </Paper>

                  {/* BACK */}
                  <Paper
                    elevation={0}
                    sx={{
                      ...CardFacePaperSx,
                      position: 'absolute',
                      inset: 0,
                      backfaceVisibility: 'hidden',
                      transform: 'rotateY(180deg)',
                      display: 'flex',
                      flexDirection: 'column',
                      justifyContent: 'center',
                      gap: '0.8vw',
                      px: '1.1vw',
                      overflow: 'hidden',
                    }}
                  >
                    <Typography
                      sx={{
                        fontFamily: 'Benzin-Bold',
                        fontSize: '0.8vw',
                        lineHeight: 1.2,
                        textAlign: 'center',
                        wordBreak: 'break-word',
                      }}
                    >
                      {displayName}
                    </Typography>

                    <Typography
                      sx={{
                        fontSize: '0.7vw',
                        textAlign: 'center',
                        color: 'rgba(255,255,255,0.7)',
                      }}
                    >
                      Кол-во: {amount}
                    </Typography>

                    {!isOnRightServer ? (
                      <CustomTooltip
                        essential
                        title={
                          !isOnline
                            ? 'Вы должны быть онлайн на сервере'
                            : `Перейдите на сервер ${item.server_ip}`
                        }
                        placement="top"
                        arrow
                      >
                        <span>
                          <Button
                            disabled
                            fullWidth
                            variant="outlined"
                            sx={{
                              fontSize: '0.8vw',
                              borderRadius: '2vw',
                              fontFamily: 'Benzin-Bold',
                              border: '1px solid rgba(255,255,255,0.15)',
                              color: 'rgba(255,255,255,0.5)',
                            }}
                          >
                            Выдать
                          </Button>
                        </span>
                      </CustomTooltip>
                    ) : (
                      <Button
                        fullWidth
                        variant="outlined"
                        disabled={!canWithdraw}
                        onClick={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          handleWithdraw(item);
                        }}
                        sx={{
                          fontSize: '0.8vw',
                          borderRadius: '2vw',
                          fontFamily: 'Benzin-Bold',
                          border: '1px solid rgba(255,255,255,0.15)',
                          color: 'white',
                        }}
                      >
                        {isWithdrawing ? 'Выдача...' : 'Выдать'}
                      </Button>
                    )}
                  </Paper>
                </Box>
              </Box>
            </Grid>
          );
        })}
      </Grid>
      )}
      {draggedItemId && dragPos && (() => {
        const draggedItem = items.find(i => i.id === draggedItemId);
        if (!draggedItem) return null;

        const texture = `https://cdn.minecraft.popa-popa.ru/textures/${draggedItem.item_data.material.toLowerCase()}.png`;

        return (
          <Box
            sx={{
              position: 'fixed',
              left: dragPos.x,
              top: dragPos.y,
              transform: 'translate(-50%, -50%)',
              //width: '12vw',
              //height: '12vw',
              pointerEvents: 'none',
              zIndex: 9999,
              opacity: 0.9,
            }}
          >
            <Paper
              elevation={0}
              sx={{
                ...CardFacePaperSx,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                width: '12vw',
                height: '12vw',
              }}
            >
              <Box
                component="img"
                src={texture}
                sx={{
                  width: '5vw',
                  height: '5vw',
                  imageRendering: 'pixelated',
                }}
              />
            </Paper>
          </Box>
        );
      })()}
    </Box>
  );
}
