import { Checkbox } from '@mui/material';
import { useRef } from 'react';
import { twc } from 'react-twc';
import { theme } from '../../Data/theme';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { useSafeRotate } from '../../Hooks/useSafeRotate';
import {
  Cross,
  Energy,
  Exit,
  Experience,
  FullscreenOff,
  FullscreenOn,
  PartnerTax,
  Poison,
  ResetGame,
} from '../../Icons/generated';
import { Player, Rotation } from '../../Types/Player';
import { PreStartMode } from '../../Types/Settings';
import { RotationDivProps } from '../Buttons/CommanderDamage';

const PlayerMenuWrapper = twc.div`
  flex
  flex-col
  absolute
  w-full
  h-full
  bg-background-settings
  backdrop-blur-[3px]
  items-center
  justify-center
  z-[2]
  webkit-user-select-none
  transition-all
`;

const BetterRowContainer = twc.div`
  flex
  flex-col
  flex-grow
  w-full
  h-full
  justify-between
  items-stretch
`;

const TogglesSection = twc.div`
  flex
  flex-row
  flex-wrap
  relative
  h-full
  justify-evenly
  items-center
`;

const ButtonsSections = twc.div`
  flex
  max-w-full
  justify-evenly
  items-center
  flex-wrap
  mt-0
  px-2
`;

const ColorPickerButton = twc.div`
  h-[8vmax]
  w-[8vmax]
  relative
  max-h-12
  max-w-12
  rounded-full
  cursor-pointer
  overflow-hidden
`;

const SettingsContainer = twc.div<RotationDivProps>((props) => [
  'flex flex-wrap h-full w-full overflow-y-scroll',
  props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
    ? 'flex-col'
    : 'flex-row',
]);

type PlayerMenuProps = {
  player: Player;
  setShowPlayerMenu: (showPlayerMenu: boolean) => void;
  isShown: boolean;
};

const PlayerMenu = ({
  player,
  setShowPlayerMenu,
  isShown,
}: PlayerMenuProps) => {
  const settingsContainerRef = useRef<HTMLDivElement | null>(null);
  const resetGameDialogRef = useRef<HTMLDialogElement | null>(null);
  const endGameDialogRef = useRef<HTMLDialogElement | null>(null);

  const { isSide } = useSafeRotate({
    rotation: player.settings.rotation,
    containerRef: settingsContainerRef,
  });

  const {
    fullscreen,
    wakeLock,
    goToStart,
    settings,
    setPlaying,
    setRandomizingPlayer,
    saveCurrentGame,
    initialGameSettings,
    setPreStartCompleted,
  } = useGlobalSettings();

  const analytics = useAnalytics();

  const { updatePlayer, resetCurrentGame, players } = usePlayers();

  const handleColorChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const updatedPlayer = { ...player, color: event.target.value };
    updatePlayer(updatedPlayer);
  };

  const handleSettingsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { name, checked } = event.target;
    const updatedSettings = { ...player.settings, [name]: checked };
    const updatedPlayer = { ...player, settings: updatedSettings };
    updatePlayer(updatedPlayer);
  };

  const handleResetGame = () => {
    resetCurrentGame();
    setShowPlayerMenu(false);

    setPlaying(false);

    if (settings.preStartMode === PreStartMode.RandomKing) {
      setRandomizingPlayer(true);
      setPreStartCompleted(false);
    }

    analytics.trackEvent('reset_game');
  };

  const handleGoToStart = () => {
    saveCurrentGame({ players, initialGameSettings });
    goToStart();
    setRandomizingPlayer(true);
  };

  const toggleFullscreen = () => {
    if (fullscreen.isFullscreen) {
      fullscreen.disableFullscreen();
    } else {
      fullscreen.enableFullscreen();
    }
  };

  const buttonFontSize = isSide ? '1.5vmax' : '3vmin';
  const iconSize = isSide ? '6vmin' : '3vmax';
  const extraCountersSize = isSide ? '8vmin' : '4vmax';

  const calcRotation =
    player.settings.rotation === Rotation.Side
      ? `${player.settings.rotation - 180}deg`
      : player.settings.rotation === Rotation.SideFlipped
      ? `${player.settings.rotation - 180}deg`
      : '';

  return (
    <PlayerMenuWrapper
      //TODO: Fix hacky solution to rotation for SideFlipped
      style={{
        rotate:
          player.settings.rotation === Rotation.SideFlipped ? `180deg` : '',
        translate: isShown ? '' : player.isSide ? `-100%` : `0 -100%`,
      }}
    >
      <SettingsContainer
        $rotation={player.settings.rotation}
        style={{
          rotate: calcRotation,
        }}
        ref={settingsContainerRef}
      >
        <button
          onClick={() => {
            analytics.trackEvent('close_player_menu_button');
            setShowPlayerMenu(false);
          }}
          className="flex absolute top-0 right-2 z-10 bg-transparent items-center justify-center rounded-full border-solid border-primary-main border-2 p-[0.2rem]"
        >
          <Cross size={buttonFontSize} className="text-primary-main " />
        </button>

        <BetterRowContainer>
          <TogglesSection>
            <ColorPickerButton aria-label="Color picker">
              <input
                onChange={handleColorChange}
                type="color"
                className="size-[200%] absolute -left-2 -top-2"
                value={player.color}
                onClick={() => {
                  analytics.trackEvent('color_picker_opened', {
                    player: player.index,
                  });
                }}
              />
            </ColorPickerButton>
            {player.settings.useCommanderDamage && (
              <div>
                <Checkbox
                  name="usePartner"
                  checked={player.settings.usePartner}
                  icon={
                    <PartnerTax
                      size={extraCountersSize}
                      color="black"
                      stroke="white"
                      strokeWidth="30"
                    />
                  }
                  checkedIcon={
                    <PartnerTax
                      size={extraCountersSize}
                      color={player.color}
                      stroke="white"
                      strokeWidth="30"
                    />
                  }
                  onChange={(e) => {
                    analytics.trackEvent('toggle_partner', {
                      checked: e.target.checked,
                    });
                    handleSettingsChange(e);
                  }}
                  role="checkbox"
                  aria-checked={player.settings.usePartner}
                  aria-label="Partner"
                />
              </div>
            )}
            <div>
              <Checkbox
                name="usePoison"
                checked={player.settings.usePoison}
                icon={
                  <Poison
                    size={extraCountersSize}
                    color="black"
                    stroke="white"
                    strokeWidth="30"
                  />
                }
                checkedIcon={
                  <Poison
                    size={extraCountersSize}
                    color={player.color}
                    stroke="white"
                    strokeWidth="30"
                  />
                }
                onChange={(e) => {
                  analytics.trackEvent('toggle_poison', {
                    checked: e.target.checked,
                  });
                  handleSettingsChange(e);
                }}
                role="checkbox"
                aria-checked={player.settings.usePoison}
                aria-label="Poison"
              />
            </div>
            <div>
              <Checkbox
                name="useEnergy"
                checked={player.settings.useEnergy}
                icon={
                  <Energy
                    size={extraCountersSize}
                    color="black"
                    stroke="white"
                    strokeWidth="15"
                  />
                }
                checkedIcon={
                  <Energy
                    size={extraCountersSize}
                    color={player.color}
                    stroke="white"
                    strokeWidth="15"
                  />
                }
                onChange={(e) => {
                  analytics.trackEvent('toggle_energy', {
                    checked: e.target.checked,
                  });
                  handleSettingsChange(e);
                }}
                role="checkbox"
                aria-checked={player.settings.useEnergy}
                aria-label="Energy"
              />
            </div>
            <div>
              <Checkbox
                name="useExperience"
                checked={player.settings.useExperience}
                icon={
                  <Experience
                    size={extraCountersSize}
                    color="black"
                    stroke="white"
                    strokeWidth="15"
                  />
                }
                checkedIcon={
                  <Experience
                    size={extraCountersSize}
                    color={player.color}
                    stroke="white"
                    strokeWidth="15"
                  />
                }
                onChange={(e) => {
                  analytics.trackEvent('toggle_experience', {
                    checked: e.target.checked,
                  });
                  handleSettingsChange(e);
                }}
                role="checkbox"
                aria-checked={player.settings.useExperience}
                aria-label="Experience"
              />
            </div>
          </TogglesSection>
          <ButtonsSections>
            <button
              className="text-primary-main cursor-pointer webkit-user-select-none"
              onClick={() => endGameDialogRef.current?.show()}
              aria-label="Back to start"
            >
              <Exit size={iconSize} style={{ rotate: '180deg' }} />
            </button>
            <div
              data-fullscreen={document.fullscreenElement ? true : false}
              className="flex
                data-[fullscreen=true]:bg-secondary-dark rounded-lg border border-transparent
              data-[fullscreen=true]:border-primary-main"
            >
              <Checkbox
                name="fullscreen"
                checked={document.fullscreenElement ? true : false}
                icon={
                  <FullscreenOff
                    size={iconSize}
                    color={theme.palette.primary.main}
                  />
                }
                checkedIcon={<FullscreenOn size={iconSize} />}
                onChange={toggleFullscreen}
                role="checkbox"
                aria-checked={document.fullscreenElement ? true : false}
                aria-label="Fullscreen"
                style={{ padding: '4px' }}
              />
            </div>

            <button
              data-wake-lock-active={settings.keepAwake}
              style={{
                fontSize: buttonFontSize,
              }}
              className="text-primary-main px-1 webkit-user-select-none cursor-pointer 
              data-[wake-lock-active=true]:bg-secondary-dark rounded-lg border border-transparent
              data-[wake-lock-active=true]:border-primary-main
              "
              onClick={() => {
                wakeLock.toggleWakeLock();
              }}
              role="checkbox"
              aria-checked={settings.keepAwake}
              aria-label="Keep awake"
            >
              Keep Awake
            </button>

            <button
              style={{
                cursor: 'pointer',
                userSelect: 'none',
                fontSize: buttonFontSize,
                padding: '2px',
              }}
              className="text-primary-main"
              onClick={() => resetGameDialogRef.current?.show()}
              role="checkbox"
              aria-label="Reset Game"
            >
              <ResetGame size={iconSize} />
            </button>
          </ButtonsSections>
        </BetterRowContainer>

        <dialog
          ref={resetGameDialogRef}
          className="z-[999] size-full bg-background-settings overflow-y-scroll"
          onClick={() => resetGameDialogRef.current?.close()}
        >
          <div className="flex size-full items-center justify-center">
            <div className="flex flex-col justify-center p-4 gap-2 bg-background-default rounded-xl border-none">
              <h1
                className="text-center text-text-primary"
                style={{ fontSize: extraCountersSize }}
              >
                Reset Game?
              </h1>
              <div className="flex justify-evenly gap-2">
                <button
                  className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
                  style={{ fontSize: iconSize }}
                  onClick={() => resetGameDialogRef.current?.close()}
                >
                  No
                </button>
                <button
                  className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
                  onClick={() => {
                    handleResetGame();
                    resetGameDialogRef.current?.close();
                  }}
                  style={{ fontSize: iconSize }}
                >
                  Yes
                </button>
              </div>
            </div>
          </div>
        </dialog>

        <dialog
          ref={endGameDialogRef}
          className="z-[999] size-full bg-background-settings overflow-y-scroll"
          onClick={() => endGameDialogRef.current?.close()}
        >
          <div className="flex size-full items-center justify-center">
            <div className="flex flex-col justify-center p-4 gap-2 bg-background-default rounded-xl border-none">
              <h1
                className="text-center text-text-primary"
                style={{ fontSize: extraCountersSize }}
              >
                Go to start?
              </h1>
              <div
                style={{ fontSize: iconSize }}
                className="text-center text-text-primary"
              >
                (Game will be saved)
              </div>
              <div className="flex justify-evenly gap-2">
                <button
                  className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
                  style={{ fontSize: iconSize }}
                  onClick={() => endGameDialogRef.current?.close()}
                >
                  No
                </button>
                <button
                  className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
                  onClick={() => {
                    handleGoToStart();
                    endGameDialogRef.current?.close();
                  }}
                  style={{ fontSize: iconSize }}
                >
                  Yes
                </button>
              </div>
            </div>
          </div>
        </dialog>
      </SettingsContainer>
    </PlayerMenuWrapper>
  );
};

export default PlayerMenu;
