import Card from "../card/Card";
import './CardSlider.scss';

const CardSlider = D.declare( 'view.cmp.CardSlider', (cfg) => {
  let current = [],
    hash = {},
    items = [],
    cardWidth = 160,
    minPadding = 20,
    wrap,
    width,
    fullCardsCount,
    padding,
    updateSize = function() {
      width = dom.clientWidth;
      fullCardsCount = width/(cardWidth+minPadding)|0;
      padding = (width-fullCardsCount*cardWidth)/(fullCardsCount-1);
      wrap.style.width = (items.length*(padding+cardWidth)-padding)+'px';
    },
    update = function() {
      updateSize();
      updateVisibleDom();
    };


  tmpStore.sub('width', Store.debounce(function(w) {
    let firstItem = Math.round(dom.scrollLeft/(cardWidth+padding));
    console.log(firstItem);
    update();
    dom.scrollLeft = firstItem*(cardWidth+padding);
  }, 30));
  let waitTimeout = false;
  let tuning = false;
  let leftestItem = 0;
  let lastLeftestItem = 0;
  let tuneScrollPosition = function() {
    waitTimeout = false;
    tuning = true;
    let fromLeft = dom.scrollLeft;
    let firstItem = Math.round(fromLeft/(cardWidth+padding)-(lastLeftestItem>leftestItem?0.4:-0.4));
    let toLeft = Math.round(firstItem*(cardWidth+padding));
    let deltaMove = (toLeft - fromLeft)/Math.ceil(200/(1000/60));
    while(deltaMove>0 && deltaMove<1){
      deltaMove *= 2;
    }
    if(Math.abs(fromLeft+deltaMove - toLeft) > Math.abs(fromLeft-toLeft)){
      deltaMove = toLeft - fromLeft;
    }
    let tune = function() {
      if(Math.sign(toLeft-dom.scrollLeft) !== Math.sign(deltaMove)){
        return tuning = false;
      }
      if(Math.abs(dom.scrollLeft-toLeft) < Math.abs(deltaMove)){
        dom.scrollLeft = toLeft;
        return tuning = false;
      }else{
        dom.scrollLeft += deltaMove;
        requestAnimationFrame( tune );
      }
    };
    if(Math.abs(deltaMove)>0){
      requestAnimationFrame( tune );
    }else{
      tuning = false;
    }

  };
  let waitUntilDoNotTouchScroll = function() {
    if(tuning)
      return;

    lastLeftestItem = leftestItem;
    leftestItem = dom.scrollLeft/(cardWidth+padding);

    if(waitTimeout)
      clearTimeout(waitTimeout);
    waitTimeout = setTimeout(tuneScrollPosition,80);
  };


  let dom = <div class='cmp-CardSlider'>
    {wrap = <div class='slides-wrap'>{' '}</div>}
  </div>;

  let lastFrom, lastTo, last = false;
  let updateVisibleDom = function() {
    let from = Math.floor(dom.scrollLeft/(cardWidth+padding)-1),
        count = Math.ceil(dom.clientWidth/(cardWidth+padding)),
        to;
    to = from + count *2;
    from -=count;
    from = Math.max(0, from);
    to = Math.min(to, items.length);

//console.log({from, to, cardWidth, padding})
    for(let i = from; i< to; i++){
      if(!(i in hash)){
        hash[i] = {
          dom: (function(item, n) {
            return <div className="cards-list__item">
              <Card
                type={'product,info,other'.split( ',' )[ n % 3 ]}
                disabled={n % 5 === 0}
                seen={n % 4 === 0}
                title={item.name}
                image={item.image}
              />
            </div>
          })(items[i], i),
          inDOM: false,
          x: 0
        };
      }
    }
    if(last){
      for( let i = lastFrom; i < lastTo; i++ ){
        if(i < from || i >= to){
          if(hash[i].inDOM){
            hash[i].inDOM = false;
            wrap.removeChild(hash[i].dom);
          }
        }
      }
    }
    for(let i = from; i< to; i++){
      let x = i*(cardWidth+padding);
      if(hash[i].x !== x){
        hash[i].dom.style.left = (hash[i].x = x)+'px';
      }
      if(!hash[i].inDOM){
        wrap.appendChild(hash[i].dom);
        hash[i].inDOM = true;
      }
    }


    lastFrom = from;
    lastTo = to;
    last = true;

  };

  dom.addEventListener('scroll', Store.debounce(function() {
    requestAnimationFrame(updateVisibleDom);
    waitUntilDoNotTouchScroll();
  }, 1000/60));
  cfg.items(function(i) {
    items = i;
    //update();

    update();

  });

  return dom;
} );

export default CardSlider;
export { CardSlider };