import { IItem } from '@rpg-engine/shared';
import React from 'react';
import styled from 'styled-components';
import { uiColors } from '../../../constants/uiColors';
import { uiFonts } from '../../../constants/uiFonts';
import { SpriteFromAtlas } from '../../shared/SpriteFromAtlas';
import { ErrorBoundary } from '../Inventory/ErrorBoundary';
import { EquipmentSlotSpriteByType } from '../Inventory/ItemSlot';
import { rarityColor } from '../Inventory/ItemSlotRarity';

interface IItemInfoProps {
  item: IItem;
  itemToCompare?: IItem;
  atlasIMG: any;
  atlasJSON: any;
}

interface IItemStat {
  key: keyof IItem;
  label?: string;
  higherIsWorse?: boolean;
}

const statisticsToDisplay: IItemStat[] = [
  { key: 'attack' },
  { key: 'defense' },
  { key: 'maxRange', label: 'Range' },
  { key: 'weight', higherIsWorse: true },
];

export const ItemInfo: React.FC<IItemInfoProps> = ({
  item,
  itemToCompare,
  atlasIMG,
  atlasJSON,
}) => {
  const renderStatistics = () => {
    const statistics: React.ReactNode[] = [];

    for (const stat of statisticsToDisplay) {
      const itemStatistic = item[stat.key];

      if (itemStatistic) {
        const label =
          stat.label || stat.key[0].toUpperCase() + stat.key.slice(1);

        const isItemToCompare = !!itemToCompare;

        const isOnlyInOneItem = isItemToCompare && !itemToCompare?.[stat.key];
        const statDiff =
          parseInt(itemStatistic.toString()) -
          parseInt(itemToCompare?.[stat.key]?.toString() ?? '0');

        const isDifference = isItemToCompare && statDiff !== 0;
        const isBetter =
          (statDiff > 0 && !stat.higherIsWorse) ||
          (statDiff < 0 && stat.higherIsWorse);

        statistics.push(
          <Statistic key={stat.key} className={isOnlyInOneItem ? 'better' : ''}>
            <div className="label">{label}:</div>
            <div
              className={`value ${
                isDifference ? (isBetter ? 'better' : 'worse') : ''
              }`}
            >
              {`${itemStatistic.toString()} ${
                isDifference ? `(${statDiff > 0 ? '+' : ''}${statDiff})` : ''
              }`}
            </div>
          </Statistic>
        );
      }
    }

    return statistics;
  };

  const renderMissingStatistic = () => {
    const statistics: React.ReactNode[] = [];

    for (const stat of statisticsToDisplay) {
      const itemToCompareStatistic = itemToCompare?.[stat.key];

      if (itemToCompareStatistic && !item[stat.key]) {
        const label =
          stat.label || stat.key[0].toUpperCase() + stat.key.slice(1);

        statistics.push(
          <Statistic key={stat.key} className="worse">
            <div className="label">{label}:</div>
            <div className="value worse">
              {itemToCompareStatistic.toString()}
            </div>
          </Statistic>
        );
      }
    }

    return statistics;
  };

  const renderEntityEffects = () => {
    if (!item.entityEffects || !item.entityEffectChance) return null;

    return item.entityEffects.map((effect, index) => (
      <Statistic key={index} $isSpecial>
        {effect[0].toUpperCase() + effect.slice(1)} ({item.entityEffectChance}%)
      </Statistic>
    ));
  };

  const renderAvaibleSlots = () => {
    if (!item.allowedEquipSlotType) return null;

    return item.allowedEquipSlotType.map((slotType, index) => (
      <ErrorBoundary key={index}>
        <SpriteFromAtlas
          atlasIMG={atlasIMG}
          atlasJSON={atlasJSON}
          spriteKey={EquipmentSlotSpriteByType[slotType]}
          imgScale={2}
          grayScale={true}
          opacity={0.4}
          containerStyle={{ width: '32px', height: '32px' }}
        />
      </ErrorBoundary>
    ));
  };

  const skillName = item.minRequirements?.skill?.name;

  return (
    <Container item={item}>
      <Header>
        <div>
          <Title>{item.name}</Title>
          {item.rarity !== 'Common' && (
            <Rarity item={item}>{item.rarity}</Rarity>
          )}
          <Type>{item.subType}</Type>
        </div>
        <AllowedSlots>{renderAvaibleSlots()}</AllowedSlots>
      </Header>

      {item.minRequirements && (
        <LevelRequirement>
          <div className="title">Requirements:</div>
          <div>- Level: {item.minRequirements?.level}</div>
          {skillName && (
            <div>
              - {skillName.charAt(0).toUpperCase() + skillName.slice(1)}:{' '}
              {item.minRequirements?.skill?.level}
            </div>
          )}
        </LevelRequirement>
      )}

      {renderStatistics()}
      {renderEntityEffects()}
      {item.usableEffectDescription && (
        <Statistic $isSpecial>{item.usableEffectDescription}</Statistic>
      )}
      {item.equippedBuffDescription && (
        <Statistic $isSpecial>{item.equippedBuffDescription}</Statistic>
      )}
      {item.isTwoHanded && <Statistic $isSpecial>Two handed</Statistic>}

      <Description>{item.description}</Description>

      {item.maxStackSize && item.maxStackSize !== 1 && (
        <StackInfo>
          x{Math.round((item.stackQty ?? 1) * 100) / 100}({item.maxStackSize})
        </StackInfo>
      )}

      {renderMissingStatistic().length > 0 && (
        <MissingStatistics>
          <Statistic>Equipped Diff</Statistic>
          {itemToCompare && renderMissingStatistic()}
        </MissingStatistics>
      )}
    </Container>
  );
};

const Container = styled.div<{ item: IItem }>`
  color: white;
  background-color: #222;
  border-radius: 5px;
  padding: 0.5rem;
  font-size: ${uiFonts.size.small};
  border: 3px solid ${({ item }) => rarityColor(item) ?? uiColors.lightGray};
  box-shadow: ${({ item }) => `0 0 5px 2px ${rarityColor(item)}`};
  height: max-content;
  width: 18rem;
  position: relative;

  @media (max-width: 640px) {
    width: 80vw;
  }
`;

const Title = styled.div`
  font-size: ${uiFonts.size.medium};
  font-weight: bold;
  margin-bottom: 0.5rem;
  display: flex;
  align-items: center;
  margin: 0;
`;

const Rarity = styled.div<{ item: IItem }>`
  font-size: ${uiFonts.size.small};
  font-weight: normal;
  margin-top: 0.2rem;
  color: ${({ item }) => rarityColor(item)};
  filter: brightness(1.5);
`;

const Type = styled.div`
  font-size: ${uiFonts.size.small};
  margin-top: 0.2rem;
  color: ${uiColors.lightGray};
`;

const LevelRequirement = styled.div`
  font-size: ${uiFonts.size.small};
  margin-top: 0.2rem;
  margin-bottom: 1rem;
  color: ${uiColors.orange};

  .title {
    margin-bottom: 4px;
  }

  div {
    margin-bottom: 2px;
  }
`;

const Statistic = styled.div<{ $isSpecial?: boolean }>`
  margin-bottom: 0.4rem;
  width: 100%;
  color: ${({ $isSpecial }) => ($isSpecial ? uiColors.darkYellow : 'inherit')};

  .label {
    display: inline-block;
    margin-right: 0.5rem;
    color: inherit;
  }

  .value {
    display: inline-block;
    color: inherit;
  }

  &.better,
  .better {
    color: ${uiColors.lightGreen};
  }

  &.worse,
  .worse {
    color: ${uiColors.cardinal};
  }
`;

const Description = styled.div`
  margin-top: 1.5rem;
  font-size: ${uiFonts.size.small};
  color: ${uiColors.lightGray};
  font-style: italic;
`;

const Header = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
`;

const AllowedSlots = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-left: auto;
  align-self: flex-start;
`;

const StackInfo = styled.div`
  width: 100%;
  text-align: right;
  font-size: ${uiFonts.size.small};
  color: ${uiColors.orange};
  margin-top: 1rem;
`;

const MissingStatistics = styled.div`
  margin-top: 1rem;
  color: ${uiColors.cardinal};
`;
