import {
  getItemTextureKeyPath,
  IItem,
  IItemContainer,
  IRawSpell,
  IShortcut,
  ShortcutType,
} from '@rpg-engine/shared';
import React from 'react';
import styled from 'styled-components';
import { uiColors } from '../../constants/uiColors';
import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
import { SingleShortcut } from '../Shortcuts/SingleShortcut';
import { useShortcutCooldown } from '../Shortcuts/useShortcutCooldown';

export type CircularControllerProps = {
  onActionClick: () => void;
  onCancelClick: () => void;
  onShortcutClick: (index: number) => void;
  mana: number;
  shortcuts: IShortcut[];
  inventory?: IItemContainer | null;
  atlasIMG: any;
  atlasJSON: any;
  spellCooldowns?: Record<string, number>;
};

export const CircularController: React.FC<CircularControllerProps> = ({
  onActionClick,
  onCancelClick,
  onShortcutClick,
  mana,
  shortcuts,
  inventory,
  atlasIMG,
  atlasJSON,
  spellCooldowns,
}) => {
  const { handleShortcutCast, shortcutCooldown } = useShortcutCooldown(
    onShortcutClick
  );

  const onTouchStart = (e: React.TouchEvent<HTMLButtonElement>) => {
    const target = e.target as HTMLButtonElement;
    target?.classList.add('active');
  };

  const onTouchEnd = (
    action: () => void,
    e: React.TouchEvent<HTMLButtonElement>
  ) => {
    const target = e.target as HTMLButtonElement;
    setTimeout(() => {
      target?.classList.remove('active');
    }, 100);
    action();
  };

  const renderShortcut = (i: number) => {
    const buildClassName = (classBase: string, isOnCooldown: boolean) => {
      return `${classBase} ${isOnCooldown ? 'onCooldown' : ''}`;
    };

    let variant = '';

    if (i === 0) variant = 'top';
    else if (i >= 3) variant = `bottom-${i - 3}`;

    const onShortcutClickBinded =
      shortcuts[i]?.type !== ShortcutType.None
        ? handleShortcutCast.bind(null, i)
        : () => {};

    const isOnShortcutCooldown = shortcutCooldown > 0;

    if (shortcuts[i]?.type === ShortcutType.Item) {
      const payload = shortcuts[i]?.payload as IItem | undefined;

      let itemsFromEquipment: (IItem | undefined | null)[] = [];

      if (inventory) {
        Object.keys(inventory.slots).forEach(i => {
          const index = parseInt(i);

          if (inventory.slots[index]?.key === payload?.key) {
            itemsFromEquipment.push(inventory.slots[index]);
          }
        });
      }

      const totalQty = itemsFromEquipment.reduce(
        (acc, item) => acc + (item?.stackQty || 1),
        0
      );

      return (
        <StyledShortcut
          key={i}
          onTouchStart={onTouchStart}
          onTouchEnd={onTouchEnd.bind(null, onShortcutClickBinded)}
          disabled={false}
          className={variant}
        >
          {isOnShortcutCooldown && (
            <span className="cooldown">{shortcutCooldown.toFixed(1)}</span>
          )}
          {payload && (
            <SpriteFromAtlas
              atlasIMG={atlasIMG}
              atlasJSON={atlasJSON}
              spriteKey={getItemTextureKeyPath(
                {
                  key: payload.texturePath,
                  texturePath: payload.texturePath,
                  stackQty: payload.stackQty || 1,
                  isStackable: payload.isStackable,
                },
                atlasJSON
              )}
              width={32}
              height={32}
              imgScale={1.4}
              imgStyle={{ left: '4px' }}
              containerStyle={{ pointerEvents: 'none' }}
            />
          )}
          <span className={buildClassName('qty', isOnShortcutCooldown)}>
            {totalQty}
          </span>
        </StyledShortcut>
      );
    }

    const payload = shortcuts[i]?.payload as IRawSpell | undefined;

    const spellCooldown = !payload
      ? 0
      : spellCooldowns?.[payload.magicWords.replaceAll(' ', '_')] ??
        shortcutCooldown;
    const cooldown =
      spellCooldown > shortcutCooldown ? spellCooldown : shortcutCooldown;
    const isOnCooldown = cooldown > 0 && !!payload;

    const CONTAINER_STYLE = { width: '32px', height: '32px' };
    const IMAGE_SCALE = 1.5;

    return (
      <StyledShortcut
        key={i}
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd.bind(null, onShortcutClickBinded)}
        disabled={mana < (payload?.manaCost ?? 0)}
        className={variant}
      >
        {isOnCooldown && (
          <span className="cooldown">
            {cooldown.toFixed(cooldown < 10 ? 1 : 0)}
          </span>
        )}
        <span className={buildClassName('mana', isOnCooldown)}>
          {payload && payload.manaCost}
        </span>
        <span className="magicWords">
          {payload?.texturePath ? (
            <SpriteFromAtlas
              atlasIMG={payload.atlasIMG}
              atlasJSON={payload.atlasJSON}
              spriteKey={payload.texturePath}
              imgScale={IMAGE_SCALE}
              containerStyle={CONTAINER_STYLE}
              centered={true}
              borderRadius="50%"
            />
          ) : (
            payload?.magicWords.split(' ').map(word => word[0])
          )}
        </span>
      </StyledShortcut>
    );
  };

  return (
    <ButtonsContainer>
      <ShortcutsContainer>
        {Array.from({ length: 12 }).map((_, i) => renderShortcut(i))}
      </ShortcutsContainer>
      <Button
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd.bind(null, onActionClick)}
      >
        <div className="rpgui-icon sword" />
      </Button>

      <CancelButton
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd.bind(null, onCancelClick)}
      >
        <span>X</span>
      </CancelButton>
    </ButtonsContainer>
  );
};

const Button = styled.button`
  width: 4.3rem;
  height: 4.3rem;
  background-color: ${uiColors.lightGray};
  border: 2px solid ${uiColors.darkGray};
  border-radius: 50%;
  text-transform: uppercase;
  font-size: 0.7rem;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: all 0.1s;
  margin-top: -3rem;
  top: -144px;

  &.active {
    background-color: ${uiColors.gray};
    border-color: ${uiColors.yellow};
  }

  .sword {
    transform: rotate(-45deg);
    height: 2.5rem;
    width: 1.9rem;
    pointer-events: none;
  }
`;

const CancelButton = styled(Button)`
  width: 3rem;
  height: 3rem;
  font-size: 0.8rem;
  position: relative;
  left: 2.6rem;

  span {
    margin-top: 4px;
    margin-left: 2px;
    pointer-events: none;
  }
`;

const ButtonsContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;

  scale: 0.9;
`;

const ShortcutsContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-direction: column;
  margin-top: 3rem;

  .top {
    transform: translate(93%, 25%);
  }

  .bottom-0 {
    transform: translate(93%, -25%);
  }

  .bottom-1 {
    transform: translate(320%, calc(-4.5rem));
  }

  .bottom-2 {
    transform: translate(-13.5%, calc(-5.6rem - 25%));
  }

  .bottom-3 {
    transform: translate(318%, calc(-15.8rem - 25%));
  }

  .bottom-4 {
    transform: translate(-15%, calc(-20.2rem - 25%));
  }
  .bottom-5 {
    transform: translate(210%, calc(-15rem - 25%));
  }

  .bottom-6 {
    transform: translate(210%, calc(-25.7rem - 25%));
  }

  .bottom-7 {
    transform: translate(304%, calc(-24.9rem - 25%));
  }

  .bottom-8 {
    transform: translate(-101%, calc(-27.7rem - 25%));
  }
`;

const StyledShortcut = styled(SingleShortcut)`
  width: 2.5rem;
  height: 2.5rem;
  transition: all 0.1s;

  .mana,
  .qty {
    font-size: 0.5rem;
  }

  &:hover,
  &:focus,
  &:active {
    background-color: ${uiColors.lightGray};
  }

  &.active {
    background-color: ${uiColors.gray};
    border-color: ${uiColors.yellow};
  }
`;
