import { useEffect, useRef, useState } from 'react';
import SkinViewer from '../components/SkinViewer';
import {
  fetchPlayer,
  uploadSkin,
  fetchCapes,
  Cape,
  activateCape,
  deactivateCape,
} from '../api';

import {
  Box,
  Typography,
  Paper,
  Button,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Alert,
} from '@mui/material';

import CapeCard from '../components/CapeCard';
import { FullScreenLoader } from '../components/FullScreenLoader';
import { OnlinePlayersPanel } from '../components/OnlinePlayersPanel';
import DailyRewards from '../components/Profile/DailyRewards';
import CustomNotification from '../components/Notifications/CustomNotification';
import type { NotificationPosition } from '../components/Notifications/CustomNotification';
import { useNavigate } from 'react-router-dom';
import { isNotificationsEnabled, getNotifPositionFromSettings } from '../utils/notifications';

export default function Profile() {
  const navigate = useNavigate();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [skin, setSkin] = useState<string>('');
  const [cape, setCape] = useState<string>('');
  const [username, setUsername] = useState<string>('');
  const [skinFile, setSkinFile] = useState<File | null>(null);
  const [skinModel, setSkinModel] = useState<string>(''); // slim или classic
  const [uploadStatus, setUploadStatus] = useState<
    'idle' | 'loading' | 'success' | 'error'
  >('idle');
  const [statusMessage, setStatusMessage] = useState<string>('');
  const [isDragOver, setIsDragOver] = useState<boolean>(false);
  const [capes, setCapes] = useState<Cape[]>([]);
  const [uuid, setUuid] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);

  const [viewerWidth, setViewerWidth] = useState(500);
  const [viewerHeight, setViewerHeight] = useState(600);

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

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

  const [autoRotate, setAutoRotate] = useState(true);
  const [walkingSpeed, setWalkingSpeed] = useState(0.5);

  useEffect(() => {
    const savedConfig = localStorage.getItem('launcher_config');
    if (savedConfig) {
      const config = JSON.parse(savedConfig);
      if (config.uuid) {
        loadPlayerData(config.uuid);
        setUsername(config.username || '');
        loadCapesData(config.username || '');
        setUuid(config.uuid || '');
      }
    }
  }, []);

  useEffect(() => {
    // Функция для обновления размеров
    const updateDimensions = () => {
      setViewerWidth(window.innerWidth * 0.4); // 25vw
      setViewerHeight(window.innerWidth * 0.5); // 30vw
    };

    // Вызываем один раз при монтировании
    updateDimensions();

    // Добавляем слушатель изменения размера окна
    window.addEventListener('resize', updateDimensions);

    // Очистка при размонтировании
    return () => {
      window.removeEventListener('resize', updateDimensions);
    };
  }, []);

  const loadPlayerData = async (uuid: string) => {
    try {
      setLoading(true);
      const player = await fetchPlayer(uuid);
      setSkin(player.skin_url);
      setCape(player.cloak_url);
      setLoading(false);
    } catch (error) {
      console.error('Ошибка при получении данных игрока:', error);
      setSkin('');
      setCape('');
    }
  };

  const loadCapesData = async (username: string) => {
    try {
      setLoading(true);
      const capesData = await fetchCapes(username);
      setCapes(capesData);
      setLoading(false);
    } catch (error) {
      console.error('Ошибка при получении плащей:', error);
      setCapes([]);
    }
  };

  // Обработка перетаскивания файла
  const handleFileDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDragOver(false);

    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      const file = e.dataTransfer.files[0];
      if (file.type === 'image/png') {
        setSkinFile(file);
        setStatusMessage(`Файл "${file.name}" готов к загрузке`);
      } else {
        setStatusMessage('Пожалуйста, выберите файл в формате PNG');
        setUploadStatus('error');
      }
    }
  };

  // Обработка выбора файла
  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      const file = e.target.files[0];
      if (file.type === 'image/png') {
        setSkinFile(file);
        setStatusMessage(`Файл "${file.name}" готов к загрузке`);
      } else {
        setStatusMessage('Пожалуйста, выберите файл в формате PNG');
        setUploadStatus('error');
      }
    }
  };

  const handleActivateCape = async (cape_id: string) => {
    setLoading(true);
    await activateCape(username, cape_id);
    await loadCapesData(username);
    setLoading(false);
  };

  const handleDeactivateCape = async (cape_id: string) => {
    setLoading(true);
    await deactivateCape(username, cape_id);
    await loadCapesData(username);
    await loadPlayerData(uuid);
    setLoading(false);
  };

  // Отправка запроса на установку скина
  const handleUploadSkin = async () => {
    setLoading(true);
    if (!skinFile || !username) {
      const msg = 'Необходимо выбрать файл и указать имя пользователя';
      setStatusMessage(msg);
      setUploadStatus('error');

      setLoading(false);

      // notification
      if (!isNotificationsEnabled()) return;
      setNotifMsg(msg);
      setNotifSeverity('error');
      setNotifOpen(true);
      return;
    }

    setUploadStatus('loading');

    try {
      await uploadSkin(username, skinFile, skinModel);

      setStatusMessage('Скин успешно загружен!');
      setUploadStatus('success');

      // 1) подтягиваем свежий skin_url с бэка
      const config = JSON.parse(localStorage.getItem('launcher_config') || '{}');
      if (config.uuid) {
        await loadPlayerData(config.uuid);
      }

      // 2) сообщаем TopBar'у, что скин обновился
      window.dispatchEvent(new CustomEvent('skin-updated'));

      // notification
      if (!isNotificationsEnabled()) return;
      setNotifMsg('Скин успешно загружен!');
      setNotifSeverity('success');
      setNotifPos(getNotifPositionFromSettings());
      setNotifOpen(true);
    } catch (error) {
      const msg = `Ошибка: ${
        error instanceof Error ? error.message : 'Не удалось загрузить скин'
      }`;

      setStatusMessage(msg);
      setUploadStatus('error');

      // notification
      if (!isNotificationsEnabled()) return;
      setNotifMsg(msg);
      setNotifSeverity('error');
      setNotifPos(getNotifPositionFromSettings());
      setNotifOpen(true);
    } finally {
      setLoading(false);
    }
  };

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

  useEffect(() => {
    const STORAGE_KEY = 'launcher_settings';

    const read = () => {
      try {
        const raw = localStorage.getItem(STORAGE_KEY);
        const s = raw ? JSON.parse(raw) : null;
        setAutoRotate(s?.autoRotateSkinViewer ?? true);
        setWalkingSpeed(s?.walkingSpeed ?? 0.5);
      } catch {
        setAutoRotate(true);
        setWalkingSpeed(0.5);
      }
    };

    read();

    // если хочешь, чтобы обновлялось сразу, когда Settings сохраняют:
    const onStorage = (e: StorageEvent) => {
      if (e.key === STORAGE_KEY) read();
    };
    window.addEventListener('storage', onStorage);

    // и наш “локальный” евент (для Electron/одного окна storage может не стрелять)
    const onSettingsUpdated = () => read();
    window.addEventListener('settings-updated', onSettingsUpdated as EventListener);

    return () => {
      window.removeEventListener('storage', onStorage);
      window.removeEventListener('settings-updated', onSettingsUpdated as EventListener);
    };
  }, []);

  return (
    <Box
      sx={{
        mt: '10vh',
        width: '100%',
        height: '100%',
        overflowY: 'auto',
        boxSizing: 'border-box',
        px: '2vw',
      }}
    >
      <CustomNotification
        open={notifOpen}
        message={notifMsg}
        severity={notifSeverity}
        position={notifPos}
        onClose={() => setNotifOpen(false)}
        autoHideDuration={2500}
      />

      {loading ? (
        <FullScreenLoader message="Загрузка вашего профиля" />
      ) : (
        <Box
          sx={{
            display: 'grid',
            gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)',
            gap: '3vw',
            alignItems: 'start',
          }}
        >
          {/* LEFT COLUMN */}
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '1vw',
              minWidth: 0,
            }}
          >
            {/* Плашка с ником */}
            <Typography
              sx={{
                fontFamily: 'Benzin-Bold',
                alignSelf: 'center',
                justifySelf: 'center',
                textAlign: 'center',
                fontSize: '3vw',
                position: 'relative',
                px: '5vw',
                py: '0.9vw',
                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,
                },
              }}
            >
              {username}
            </Typography>

            {/* SkinViewer */}
            <Box
              sx={{
                overflow: 'hidden',
                display: 'flex',
                justifyContent: 'center',
              }}
            >
              <SkinViewer
                width={400}
                height={465}
                skinUrl={skin}
                capeUrl={cape}
                walkingSpeed={walkingSpeed}
                autoRotate={autoRotate}
              />
            </Box>

            {/* Загрузчик скинов */}
            <Box
              sx={{
                width: '100%',
                p: '2.2vw',
                borderRadius: '1.2vw',
                boxSizing: 'border-box',
                minWidth: 0,
                overflow: 'hidden',
                position: 'relative',
                background:
                  '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)',
                border: '1px solid rgba(255,255,255,0.08)',
                boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)',
                backdropFilter: 'blur(14px)',
              }}
            >
              {/* dropzone */}
              <Box
                sx={{
                  borderRadius: '1.1vw',
                  p: '1.6vw',
                  mb: '1.1vw',
                  textAlign: 'center',
                  cursor: 'pointer',
                  position: 'relative',
                  overflow: 'hidden',
                  background: 'rgba(255,255,255,0.04)',
                  border: '1px solid rgba(255,255,255,0.10)',
                  transition:
                    'transform 0.18s ease, border-color 0.18s ease, background 0.18s ease',
                  '&:hover': {
                    transform: 'scale(1.005)',
                    borderColor: 'rgba(242,113,33,0.35)',
                    background: 'rgba(255,255,255,0.05)',
                  },
                  ...(isDragOver
                    ? {
                        borderColor: 'rgba(233,64,205,0.55)',
                        background:
                          'linear-gradient(120deg, rgba(242,113,33,0.10), rgba(233,64,205,0.08), rgba(138,35,135,0.10))',
                      }
                    : null),
                  '&:after': {
                    content: '""',
                    position: 'absolute',
                    left: 0,
                    top: 0,
                    bottom: 0,
                    width: '0.35vw',
                    background: GRADIENT,
                    opacity: 0.9,
                    pointerEvents: 'none',
                  },
                }}
                onDragOver={(e) => {
                  e.preventDefault();
                  setIsDragOver(true);
                }}
                onDragLeave={() => setIsDragOver(false)}
                onDrop={handleFileDrop}
                onClick={() => fileInputRef.current?.click()}
              >
                <input
                  type="file"
                  ref={fileInputRef}
                  accept=".png"
                  style={{ display: 'none' }}
                  onChange={handleFileSelect}
                />

                <Typography
                  sx={{
                    color: 'rgba(255,255,255,0.92)',
                    fontWeight: 800,
                  }}
                >
                  {skinFile
                    ? `Выбран файл: ${skinFile.name}`
                    : 'Перетащите PNG файл скина или кликните для выбора'}
                </Typography>

                <Typography
                  sx={{
                    mt: 0.6,
                    color: 'rgba(255,255,255,0.60)',
                    fontWeight: 700,
                    fontSize: '0.9vw',
                  }}
                >
                  Только .png • Рекомендуется 64×64
                </Typography>
              </Box>

              {/* select */}
              <FormControl
                fullWidth
                size="small"
                sx={{
                  mb: '1.1vw',
                  '& .MuiInputLabel-root': {
                    color: 'rgba(255,255,255,0.75)',
                    fontFamily: 'Benzin-Bold',
                  },
                  '& .MuiInputLabel-root.Mui-focused': {
                    color: 'rgba(242,113,33,0.95)',
                  },
                }}
              >
                <InputLabel>Модель скина</InputLabel>
                <Select
                  value={skinModel}
                  label="Модель скина"
                  onChange={(e) => setSkinModel(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)',
                    },
                  }}
                >
                  <MenuItem value="">По умолчанию</MenuItem>
                  <MenuItem value="slim">Тонкая (Alex)</MenuItem>
                  <MenuItem value="classic">Классическая (Steve)</MenuItem>
                </Select>
              </FormControl>

              {/* button */}
              <Button
                variant="contained"
                fullWidth
                onClick={handleUploadSkin}
                disabled={uploadStatus === 'loading' || !skinFile}
                disableRipple
                sx={{
                  borderRadius: '2.5vw',
                  py: '0.95vw',
                  fontFamily: 'Benzin-Bold',
                  color: '#fff',
                  background: GRADIENT,
                  boxShadow: '0 1.0vw 2.8vw rgba(0,0,0,0.45)',
                  transition:
                    'transform 0.18s ease, filter 0.18s ease, opacity 0.18s ease',
                  '&:hover': {
                    transform: 'scale(1.01)',
                    filter: 'brightness(1.05)',
                  },
                  '&.Mui-disabled': {
                    background: 'rgba(255,255,255,0.10)',
                    color: 'rgba(255,255,255,0.55)',
                  },
                }}
              >
                {uploadStatus === 'loading' ? 'Загрузка...' : 'Установить скин'}
              </Button>
            </Box>
          </Box>

          {/* RIGHT COLUMN */}
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '1vw',
              minWidth: 0,
              maxWidth: '44vw',
              justifySelf: 'start',
            }}
          >
            {/* Плащи */}
            <Paper
              elevation={0}
              sx={{
                p: '1.6vw',
                borderRadius: '1.2vw',
                background:
                  '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)',
                border: '1px solid rgba(255,255,255,0.08)',
                boxShadow: '0 1.2vw 3.2vw rgba(0,0,0,0.55)',
                backdropFilter: 'blur(14px)',
              }}
            >
              <Typography
                sx={{
                  fontFamily: 'Benzin-Bold',
                  fontSize: '1.35vw',
                  lineHeight: 1.1,
                  backgroundImage: GRADIENT,
                  WebkitBackgroundClip: 'text',
                  WebkitTextFillColor: 'transparent',
                  mb: '1.0vw',
                }}
              >
                Ваши плащи
              </Typography>

              <Box
                sx={{
                  display: 'flex',
                  flexWrap: 'wrap',
                  gap: '1.2vw',
                }}
              >
                {capes.map((cape) => (
                  <CapeCard
                    key={cape.cape_id}
                    cape={cape}
                    mode="profile"
                    onAction={cape.is_active ? handleDeactivateCape : handleActivateCape}
                    actionDisabled={loading}
                  />
                ))}
              </Box>
            </Paper>

            {/* Онлайн */}
            <OnlinePlayersPanel currentUsername={username} />
          </Box>
        </Box>
      )}
    </Box>
  );
}
