import { useState, useEffect, useRef } from 'react';
import styled from '@emotion/styled';
import noop from 'lodash/noop';

export interface CardSelectorProps {
  list?: Array<{ src: string; name: string }> | Array<(i: number) => React.ReactNode>;
  width?: number;
  height?: number;
  cardSpace?: number;
  onSelect?: (index: number) => void;
  defaultIndex?: number;
}

export default function CardSelector({
  list = [],
  width = 300,
  height = 400,
  cardSpace = 40,
  onSelect = noop,
  defaultIndex = 0,
}: CardSelectorProps) {
  const [selectedId, setSelectedId] = useState(0);
  const [translateX, setTranslateX] = useState(0);
  const outterCon = useRef<HTMLDivElement | null>(null);

  // 选择卡片
  const selectedItem = (i: number) => {
    if (i < 0 || i > list.length - 1) {
      return;
    }
    setSelectedId(i);

    if (outterCon.current) {
      // 外部容器大小
      const outerWidth = outterCon.current.clientWidth;

      setTranslateX(i * (width + cardSpace) - (outerWidth - width) / 2 + cardSpace * 0.5);
    }

    onSelect(i);
  };

  useEffect(() => {
    selectedItem(defaultIndex);

    outterCon.current?.addEventListener('touchmove', (e) => e.preventDefault(), { passive: false });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  let startX: number;

  const touchstart: React.TouchEventHandler<HTMLDivElement> = (e) => {
    const point = e.touches[0];
    startX = point.clientX;
  };

  const touchend: React.TouchEventHandler<HTMLDivElement> = (e) => {
    const point = e.changedTouches[0];
    const diffX = startX - point.clientX;

    if (Math.abs(diffX) > 60) {
      if (diffX > 0) {
        selectedItem(selectedId + 1);
      } else {
        selectedItem(selectedId - 1);
      }
    }
  };

  return (
    <Container ref={outterCon} onTouchStart={touchstart} onTouchEnd={touchend}>
      <div className="card-container" style={{ transform: `translate(${-translateX}px, 0)` }}>
        {list.map((e, i) => {
          if (e instanceof Function) {
            return (
              <div
                className={`card-item ${i === selectedId ? 'selected' : ''}`}
                style={{ width, height, margin: cardSpace / 2 }}
                // eslint-disable-next-line react/no-array-index-key
                key={i}
                onClick={() => selectedItem(i)}>
                {e(i)}
              </div>
            );
          }
          return (
            <div
              className={`card-item ${i === selectedId ? 'selected' : ''}`}
              style={{ width, height, margin: cardSpace / 2 }}
              // eslint-disable-next-line react/no-array-index-key
              key={i}
              onClick={() => selectedItem(i)}>
              <img src={e.src} alt={e.name} />
            </div>
          );
        })}
      </div>
    </Container>
  );
}

const Container = styled.div`
  overflow: hidden;
  mask-image: linear-gradient(to left, transparent, black 3%, black 97%, transparent);
  overflow: hidden;
  .card-container {
    display: flex;
    white-space: nowrap;
    width: max-content;
    transition: all ease 0.3s;
  }
  .card-item {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    flex-shrink: 0;
    cursor: pointer;
    img,
    svg {
      max-width: 100%;
      max-height: 100%;
      width: auto;
      height: auto;
      outline: #526ded solid 0;
      transition: all ease 0.2s;
      box-shadow: rgba(0, 0, 0, 0.2) 0 0 10px;
    }
    &.selected {
      cursor: default;
      img,
      svg {
        outline: #526ded solid 5px;
      }
    }
  }
`;
