import {
  ICraftableItem,
  IEquipmentSet,
  IItemContainer,
  ISkill,
  ItemSubType,
} from '@rpg-engine/shared';
import React, { useEffect, useState } from 'react';
import {
  FaBoxOpen,
  FaChevronLeft,
  FaChevronRight,
  FaSearch,
  FaThumbtack,
} from 'react-icons/fa';
import styled from 'styled-components';
import { uiColors } from '../../constants/uiColors';
import { useLocalStorage } from '../../hooks/useLocalStorage';
import { Button, ButtonTypes } from '../Button';
import { DraggableContainer } from '../DraggableContainer';
import { Dropdown, IOptionsProps } from '../Dropdown';
import { RPGUIContainerTypes } from '../RPGUI/RPGUIContainer';
import { CraftingRecipe } from './CraftingRecipe';
import { useResponsiveSize } from './hooks/useResponsiveSize';
import { calculateMaxCraftable } from './utils/calculateMaxCraftable';

const MOBILE_WIDTH = '500px';
const ITEMS_PER_PAGE = 8;

export interface IItemCraftSelectorProps {
  atlasJSON: any;
  atlasIMG: any;
  onClose: () => void;
  onSelect: (value: string) => void;
  onCraftItem: (value: string | undefined, maxCraftable: number) => void;
  craftablesItems: ICraftableItem[];
  equipmentSet?: IEquipmentSet | null;
  inventory?: IItemContainer | null;
  scale?: number;
  skills?: ISkill | null;
  savedSelectedType?: string;
}

export interface ShowMessage {
  show: boolean;
  index: number;
}

export const CraftBook: React.FC<IItemCraftSelectorProps> = ({
  atlasIMG,
  atlasJSON,
  onClose,
  onSelect,
  onCraftItem,
  craftablesItems,
  equipmentSet,
  scale,
  inventory,
  skills,
  savedSelectedType,
}) => {
  const [craftItemKey, setCraftItemKey] = useState<string>();
  const [selectedType, setSelectedType] = useState<string>(
    savedSelectedType ?? Object.keys(ItemSubType)[0]
  );
  const size = useResponsiveSize(scale);
  const [searchTerm, setSearchTerm] = useState('');
  const [isSearchVisible, setIsSearchVisible] = useState(false);
  const [isCraftingDisabled, setIsCraftingDisabled] = useState(false);
  const [pinnedItems, setPinnedItems] = useLocalStorage<string[]>(
    'pinnedCraftItems',
    []
  );
  const [currentPage, setCurrentPage] = useState(1);
  const [items, setItems] = useState<ICraftableItem[]>(craftablesItems);

  useEffect(() => {
    setItems(craftablesItems);
  }, [craftablesItems]);

  const togglePinItem = (itemKey: string) => {
    setPinnedItems(current =>
      current.includes(itemKey)
        ? current.filter(key => key !== itemKey)
        : [...current, itemKey]
    );
  };

  const categoryOptions: IOptionsProps[] = [
    { id: 0, value: 'Suggested', option: 'Suggested' },
    ...(pinnedItems.length > 0
      ? [{ id: 1, value: 'Pinned', option: 'Pinned' }]
      : []),
    ...Object.keys(ItemSubType)
      .filter(type => type !== 'DeadBody')
      .map((type, index) => ({
        id: index + (pinnedItems.length > 0 ? 2 : 1),
        value: type,
        option:
          type === 'CraftingResources' || type === 'CraftingResource'
            ? 'Resources'
            : type,
      })),
  ].sort((a, b) => {
    if (a.value === 'Suggested') return -1;
    if (b.value === 'Suggested') return 1;
    if (a.value === 'Pinned') return -1;
    if (b.value === 'Pinned') return 1;
    return a.value.localeCompare(b.value);
  });

  const filteredCraftableItems = items?.filter(item => {
    const matchesSearch = item.name
      .toLowerCase()
      .includes(searchTerm.toLowerCase());
    const matchesCategory =
      selectedType === 'Suggested' ||
      (selectedType === 'Pinned'
        ? pinnedItems.includes(item.key)
        : item.subType === selectedType);
    return matchesSearch && matchesCategory;
  });

  const sortedItems = [...(filteredCraftableItems || [])].sort((a, b) => {
    const aIsPinned = pinnedItems.includes(a.key);
    const bIsPinned = pinnedItems.includes(b.key);
    if (aIsPinned && !bIsPinned) return -1;
    if (!aIsPinned && bIsPinned) return 1;
    return 0;
  });

  const totalPages = Math.ceil(sortedItems.length / ITEMS_PER_PAGE);
  const paginatedItems = sortedItems.slice(
    (currentPage - 1) * ITEMS_PER_PAGE,
    currentPage * ITEMS_PER_PAGE
  );

  useEffect(() => {
    setCurrentPage(1);
  }, [selectedType, searchTerm]);

  if (!size) return null;

  return (
    <DraggableContainer
      type={RPGUIContainerTypes.Framed}
      width={size.width}
      height={size.height}
      cancelDrag=".inputRadioCraftBook"
      onCloseButton={onClose}
      scale={scale}
    >
      <Wrapper>
        <HeaderContainer>
          <Title>Craftbook</Title>
          <HeaderControls>
            <DropdownWrapper>
              <Dropdown
                options={categoryOptions}
                onChange={value => {
                  setSelectedType(value);
                  onSelect(value);
                }}
                width="200px"
              />
            </DropdownWrapper>
            <SearchButton onClick={() => setIsSearchVisible(!isSearchVisible)}>
              <FaSearch size={16} />
            </SearchButton>
          </HeaderControls>
        </HeaderContainer>

        {isSearchVisible && (
          <SearchContainer>
            <input
              type="text"
              className="rpgui-input"
              placeholder="Search items..."
              value={searchTerm}
              onChange={e => setSearchTerm(e.target.value)}
              autoFocus
            />
          </SearchContainer>
        )}

        <ContentContainer>
          {paginatedItems.length > 0 ? (
            <RadioInputScroller className="inputRadioCraftBook">
              {paginatedItems?.map(item => (
                <CraftingRecipeWrapper
                  key={item.key}
                  isSelected={pinnedItems.includes(item.key)}
                >
                  <PinButton
                    onClick={e => {
                      e.stopPropagation();
                      togglePinItem(item.key);
                    }}
                    isPinned={pinnedItems.includes(item.key)}
                  >
                    <FaThumbtack size={14} />
                  </PinButton>
                  <CraftingRecipe
                    atlasIMG={atlasIMG}
                    atlasJSON={atlasJSON}
                    equipmentSet={equipmentSet}
                    recipe={item}
                    scale={scale}
                    handleRecipeSelect={setCraftItemKey.bind(null, item.key)}
                    selectedCraftItemKey={craftItemKey}
                    inventory={inventory}
                    skills={skills}
                  />
                </CraftingRecipeWrapper>
              ))}
            </RadioInputScroller>
          ) : (
            <EmptyState>
              <FaBoxOpen size={48} />
              <p>No craftable items found</p>
            </EmptyState>
          )}
        </ContentContainer>

        {totalPages > 1 && (
          <PaginationContainer>
            <PaginationButton
              onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
              disabled={currentPage === 1}
            >
              <FaChevronLeft size={12} />
            </PaginationButton>
            <PageInfo>
              Page {currentPage} of {totalPages}
            </PageInfo>
            <PaginationButton
              onClick={() =>
                setCurrentPage(prev => Math.min(totalPages, prev + 1))
              }
              disabled={currentPage === totalPages}
            >
              <FaChevronRight size={12} />
            </PaginationButton>
          </PaginationContainer>
        )}

        <Footer>
          <Button buttonType={ButtonTypes.RPGUIButton} onPointerDown={onClose}>
            Close
          </Button>
          <Button
            disabled={!craftItemKey || isCraftingDisabled}
            buttonType={ButtonTypes.RPGUIButton}
            onPointerDown={() => {
              if (!craftItemKey || isCraftingDisabled) return;

              const selectedItem = craftablesItems.find(
                item => item.key === craftItemKey
              );
              const maxCraftable = calculateMaxCraftable(
                selectedItem,
                inventory
              );

              onCraftItem(craftItemKey, maxCraftable);
              setIsCraftingDisabled(true);

              setTimeout(() => {
                setIsCraftingDisabled(false);
              }, 2000);
            }}
          >
            Craft
          </Button>
        </Footer>
      </Wrapper>
    </DraggableContainer>
  );
};

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;

  & > * {
    box-sizing: border-box;
  }
`;

const HeaderContainer = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 16px 16px 0;
`;

const Title = styled.h1`
  font-size: 1.2rem;
  color: ${uiColors.yellow} !important;
  margin: 0;
  text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);
`;

const HeaderControls = styled.div`
  display: flex;
  align-items: center;
  gap: 16px;
  position: relative;
  left: -2rem;
`;

const DropdownWrapper = styled.div`
  width: 200px;
`;

const SearchButton = styled.button`
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  width: 32px;
  height: 32px;
  color: ${uiColors.yellow};
  opacity: 0.8;
  transition: opacity 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;

  &:hover {
    opacity: 1;
  }
`;

const SearchContainer = styled.div`
  padding: 0 16px;
  margin-top: 16px;

  input {
    width: 100%;
    font-size: 0.8rem;
    padding: 8px 12px;
    background-color: rgba(0, 0, 0, 0.3);
    border: none;
    color: white;
    border-radius: 4px;

    &::placeholder {
      color: rgba(255, 255, 255, 0.5);
    }

    &:focus {
      outline: none;
      background-color: rgba(0, 0, 0, 0.4);
    }
  }
`;

const ContentContainer = styled.div`
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 16px;
  padding-right: 0;
  padding-bottom: 0;
  width: 100%;
  position: relative;
  min-height: 250px;
  overflow: hidden;
`;

const RadioInputScroller = styled.div`
  height: 100%;
  min-height: 300px;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 8px 16px;
  padding-right: 24px;
  width: 100%;
  box-sizing: border-box;

  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-content: start;

  @media (max-width: ${MOBILE_WIDTH}) {
    grid-template-columns: 1fr;
  }
`;

const CraftingRecipeWrapper = styled.div<{ isSelected: boolean }>`
  position: relative;
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  transition: background-color 0.2s;

  &:hover {
    background: rgba(0, 0, 0, 0.4);
  }

  ${props =>
    props.isSelected &&
    `
    background: rgba(255, 215, 0, 0.1);
  `}
`;

const PinButton = styled.button<{ isPinned: boolean }>`
  position: absolute;
  top: 8px;
  right: 8px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  color: ${props => (props.isPinned ? uiColors.yellow : uiColors.lightGray)};
  opacity: ${props => (props.isPinned ? 1 : 0.6)};
  transition: all 0.2s;
  z-index: 2;

  &:hover {
    opacity: 1;
    color: ${uiColors.yellow};
  }
`;

const Footer = styled.div`
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  padding: 8px;

  button {
    min-width: 100px;
  }

  @media (max-width: ${MOBILE_WIDTH}) {
    justify-content: center;
  }
`;

const PaginationContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 8px;
  margin-top: 8px;
  border-top: 1px solid ${uiColors.darkGray};
`;

const PaginationButton = styled.button<{ disabled?: boolean }>`
  background: none;
  border: none;
  color: ${props => (props.disabled ? uiColors.darkGray : uiColors.yellow)};
  cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
  opacity: ${props => (props.disabled ? 0.5 : 0.8)};
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s;

  &:hover:not(:disabled) {
    opacity: 1;
  }
`;

const PageInfo = styled.div`
  color: ${uiColors.lightGray};
  font-size: 0.8rem;
  font-family: 'Press Start 2P', cursive;
`;

const EmptyState = styled.div`
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: ${uiColors.lightGray};
  width: 100%;
  padding: 2rem;

  svg {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.7;
  }

  p {
    font-family: 'Press Start 2P', cursive;
    font-size: 0.9rem;
    margin: 0;
  }
`;
