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

export default function Profile() {
  const navigate = useNavigate();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [walkingSpeed, setWalkingSpeed] = useState<number>(0.5);
  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',
  });

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

      // notification
      setNotifMsg(msg);
      setNotifSeverity('error');
      setNotifOpen(true);

      setLoading(false);
      return;
    }

    setUploadStatus('loading');

    try {
      await uploadSkin(username, skinFile, skinModel);
      setStatusMessage('Скин успешно загружен!');
      setUploadStatus('success');

      // notification
      setNotifMsg('Скин успешно загружен!');
      setNotifSeverity('success');
      setNotifPos({ vertical: 'bottom', horizontal: 'left' });
      setNotifOpen(true);

      // Обновляем информацию о игроке, чтобы увидеть новый скин
      const config = JSON.parse(
        localStorage.getItem('launcher_config') || '{}',
      );
      if (config.uuid) {
        loadPlayerData(config.uuid);
      }
    } catch (error) {
      const msg = `Ошибка: ${
        error instanceof Error ? error.message : 'Не удалось загрузить скин'
      }`;

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

      // notification
      setNotifMsg(msg);
      setNotifSeverity('error');
      setNotifPos({ vertical: 'bottom', horizontal: 'left' });
      setNotifOpen(true);
    } finally {
      setLoading(false);
    }
  };

  return (
    <Box
      sx={{
        mt: '10vh',
        display: 'grid',
        gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)',
        gap: '3vw',
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'start',
        overflowY: 'auto',
      }}
    >
      <CustomNotification
        open={notifOpen}
        message={notifMsg}
        severity={notifSeverity}
        position={notifPos}
        onClose={() => setNotifOpen(false)}
        autoHideDuration={2500}
      />
      {loading ? (
        <FullScreenLoader message="Загрузка вашего профиля" />
      ) : (
        <>
          <Paper
            elevation={0}
            sx={{
              p: 0,
              borderRadius: 2,
              overflow: 'hidden',
              bgcolor: 'transparent',
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
            }}
          >
            {/* Используем переработанный компонент SkinViewer */}
            <Typography
              sx={{
                fontFamily: 'Benzin-Bold',
                alignSelf: 'center',
                justifySelf: 'center',
                textAlign: 'center',
                mb: '2vw',
                fontSize: '3vw',
                color: 'white',
                borderRadius: '3vw',
                p: '0.5vw 5vw',
                bgcolor: 'rgb(255, 77, 77)',
                boxShadow: '0 0 1vw 0 rgba(0, 0, 0, 0.5)',
              }}
            >
              {username}
            </Typography>
            <SkinViewer
              width={viewerWidth}
              height={viewerHeight}
              skinUrl={skin}
              capeUrl={cape}
              walkingSpeed={walkingSpeed}
              autoRotate={true}
            />
          </Paper>

          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '1vw',
              width: '100%',
              maxWidth: '44vw',
              justifySelf: 'start'
            }}
          >
            <Box
              sx={{
                width: '100%',
                bgcolor: 'rgba(255, 255, 255, 0.05)',
                padding: '3vw',
                borderRadius: '1vw',
                flexShrink: 0,
                boxSizing: 'border-box',
                minWidth: 0,
              }}
            >
              <Box
                sx={{
                  border: '2px dashed',
                  borderColor: isDragOver ? 'primary.main' : 'grey.400',
                  borderRadius: '1vw',
                  p: '1.5vw',
                  mb: '1vw',
                  textAlign: 'center',
                  cursor: 'pointer',
                  bgcolor: isDragOver
                    ? 'rgba(25, 118, 210, 0.08)'
                    : 'transparent',
                  transition: 'all 0.2s',
                }}
                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: 'white' }}>
                  {skinFile
                    ? `Выбран файл: ${skinFile.name}`
                    : 'Перетащите PNG файл скина или кликните для выбора'}
                </Typography>
              </Box>

              <FormControl
                color="primary"
                fullWidth
                sx={{
                  mb: '1vw',
                  color: 'white',
                  '&:hover .MuiInputLabel-root': {
                    color: 'rgb(255, 77, 77)',
                    transition: 'all 0.3s ease-in-out',
                  },
                }}
              >
                <InputLabel
                  sx={{
                    fontFamily: 'Benzin-Bold',
                    color: 'white',
                    '&.Mui-focused': {
                      color: 'rgb(255, 77, 77)',
                      transition: 'all 0.3s ease-in-out',
                    },
                    transform: 'translate(14px, -9px) scale(0.75)',
                    '&.MuiInputLabel-shrink': {
                      transform: 'translate(14px, -9px) scale(0.75)',
                      transition: 'all 0.3s ease-in-out',
                    },
                  }}
                >
                  Модель скина
                </InputLabel>
                <Select
                  value={skinModel}
                  label="Модель скина"
                  onChange={(e) => setSkinModel(e.target.value)}
                  displayEmpty
                  sx={{
                    border: 'none',
                    '& .MuiSelect-select': {
                      fontFamily: 'Benzin-Bold',
                      color: 'white',
                      paddingTop: '1vw',
                      paddingBottom: '1vw',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '&:hover': {
                      '& .MuiSelect-select': {
                        color: 'rgb(255, 77, 77)',
                        transition: 'all 0.3s ease-in-out',
                      },
                    },
                    '&.Mui-focused': {
                      '& .MuiSelect-select': {
                        color: 'rgb(255, 77, 77)',
                        transition: 'all 0.3s ease-in-out',
                      },
                    },
                    '& .MuiOutlinedInput-notchedOutline': {
                      borderRadius: '5vw',
                      borderColor: 'rgb(255, 255, 255)',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '&:hover .MuiOutlinedInput-notchedOutline': {
                      borderColor: 'rgb(255, 77, 77)',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
                      borderColor: 'rgb(255, 77, 77)',
                      borderWidth: '2px',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '& .MuiSelect-icon': {
                      color: 'white',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '&:hover .MuiSelect-icon': {
                      color: 'rgb(255, 77, 77)',
                      transition: 'all 0.3s ease-in-out',
                    },
                    '&.Mui-focused .MuiSelect-icon': {
                      color: 'rgb(255, 77, 77)',
                      transition: 'all 0.3s ease-in-out',
                    },
                  }}
                >
                  <MenuItem value="">По умолчанию</MenuItem>
                  <MenuItem value="slim">Тонкая (Alex)</MenuItem>
                  <MenuItem value="classic">Классическая (Steve)</MenuItem>
                </Select>
              </FormControl>
              <Button
                sx={{
                  color: 'white',
                  borderRadius: '20px',
                  p: '10px 25px',
                  backgroundColor: 'rgb(0, 134, 0)',
                  '&:hover': {
                    backgroundColor: 'rgba(0, 134, 0, 0.5)',
                  },
                  fontFamily: 'Benzin-Bold',
                }}
                variant="contained"
                fullWidth
                onClick={handleUploadSkin}
                disabled={uploadStatus === 'loading' || !skinFile}
                startIcon={
                  uploadStatus === 'loading' ? (
                    <FullScreenLoader fullScreen={false} />
                  ) : null
                }
              >
                {uploadStatus === 'loading' ? (
                  <FullScreenLoader message="Загрузка..." />
                ) : (
                  <Typography sx={{ color: 'white' }}>
                    Установить скин
                  </Typography>
                )}
              </Button>
            </Box>
            <Box
              sx={{
                display: 'flex',
                justifyContent: 'center',
                flexDirection: 'column',
                gap: '2vw',
              }}
            >
              <Typography>Ваши плащи</Typography>
              <Box
                sx={{
                  display: 'flex',
                  flexDirection: 'row',
                  gap: '2vw',
                  flexWrap: 'wrap',
                }}
              >
                {capes.map((cape) => (
                  <CapeCard
                    key={cape.cape_id}
                    cape={cape}
                    mode="profile"
                    onAction={
                      cape.is_active ? handleDeactivateCape : handleActivateCape
                    }
                    actionDisabled={loading}
                  />
                ))}
              </Box>
            </Box>
            <OnlinePlayersPanel currentUsername={username} />
          </Box>
        </>
      )}
    </Box>
  );
}
