import { Component, Element, h, Prop, State } from '@stencil/core';
function findStartNode(scrollTop, nodePositions, itemCount) {
  let startRange = 0;
  let endRange = itemCount - 1;
  while (endRange !== startRange) {
    // console.log(startRange, endRange);
    const middle = Math.floor((endRange - startRange) / 2 + startRange);
    if (nodePositions[middle] <= scrollTop &&
      nodePositions[middle + 1] > scrollTop) {
      // console.log("middle", middle);
      return middle;
    }
    if (middle === startRange) {
      // edge case - start and end range are consecutive
      // console.log("endRange", endRange);
      return endRange;
    }
    else {
      if (nodePositions[middle] <= scrollTop) {
        startRange = middle;
      }
      else {
        endRange = middle;
      }
    }
  }
  return itemCount;
}
function findEndNode(nodePositions, startNode, itemCount, height) {
  let endNode;
  for (endNode = startNode; endNode < itemCount; endNode++) {
    // console.log(nodePositions[endNode], nodePositions[startNode]);
    if (nodePositions[endNode] > nodePositions[startNode] + height) {
      // console.log(endNode);
      return endNode;
    }
  }
  return endNode;
}
export class VirtualScroll {
  constructor() {
    this.itemCount = 500;
    this.rowHeight = 50;
    this.renderAhead = 0;
    this.scrollTop = 0;
  }
  componentDidRender() {
    setTimeout(() => {
      this.height = this.el ? this.el.offsetHeight : 0;
    }, 100);
  }
  render() {
    const { height, itemCount, renderAhead, rowHeight, scrollTop } = this;
    // const viewportHeight = this.el ? this.el.offsetHeight : 0;
    // console.log('this.el ? this.el.offsetHeight : 0', this.el ? this.el.offsetHeight : 0);
    const getChildHeight = (_index) => rowHeight;
    const childPositions = () => {
      let results = [0];
      for (let i = 1; i < itemCount; i++) {
        results.push(results[i - 1] + getChildHeight(i - 1));
      }
      return results;
    };
    const totalHeight = childPositions()[itemCount - 1] + getChildHeight(itemCount - 1);
    console.log('scrollTop', scrollTop);
    const firstVisibleNode = () => findStartNode(scrollTop, childPositions(), itemCount);
    console.log('firstVisibleNode()', firstVisibleNode());
    const startNode = Math.max(0, firstVisibleNode() - renderAhead);
    console.log('startNode', startNode);
    const lastVisibleNode = () => findEndNode(childPositions(), firstVisibleNode(), itemCount, height);
    const endNode = Math.min(itemCount - 1, lastVisibleNode() + renderAhead);
    const visibleNodeCount = endNode - startNode + 1;
    const offsetY = childPositions()[startNode];
    console.log('visibleNodeCount', visibleNodeCount);
    const visibleChildren = () => new Array(visibleNodeCount)
      .fill(null)
      .map((_, index) => this.renderRow(index + startNode));
    // .map((_, index) => (
    //   <div key={index + startNode} style={{ border: '1px solid red', height: '50px', background: (index + startNode) % 5 === 0 && 'red' }}>
    //     {index + startNode}
    //   </div>
    // ));
    console.log('viewportHeight', height);
    console.log('totalHeight', totalHeight);
    // const onScroll = e => {
    //   if (animationFrame.current) {
    //     cancelAnimationFrame(animationFrame.current);
    //   }
    //   animationFrame.current = requestAnimationFrame(() => {
    //     setScrollTop(e.target.scrollTop);
    //   });
    // };
    return (h("div", { style: {
        height: `${800}px`,
        overflow: 'auto',
        flex: '1',
        display: 'block',
      }, onScroll: (e) => {
        console.log(e.target.scrollTop);
        this.scrollTop = e.target.scrollTop;
        // const st = e.target.scrollTop;
        // if (this.animationFrame) {
        //   console.log('cancelling animation');
        //   cancelAnimationFrame(this.animationFrame);
        // }
        // this.animationFrame = requestAnimationFrame(() => {
        //   console.log(e.target);
        //   console.log('setting scroll top', st);
        //   this.scrollTop = st;
        // });
      } },
      h("div", { style: {
          height: `${totalHeight}px`,
          overflow: 'hidden',
          willChange: 'transform',
          position: 'relative'
        } },
        h("div", { style: {
            transform: `translateY(${offsetY}px)`
          } }, visibleChildren()))));
  }
  static get is() { return "dvn-virtual-scroll"; }
  static get originalStyleUrls() { return {
    "$": ["dvn-list-view-table.css"]
  }; }
  static get styleUrls() { return {
    "$": ["dvn-list-view-table.css"]
  }; }
  static get properties() { return {
    "itemCount": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "item-count",
      "reflect": false,
      "defaultValue": "500"
    },
    "rowHeight": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "row-height",
      "reflect": false,
      "defaultValue": "50"
    },
    "renderAhead": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "render-ahead",
      "reflect": false,
      "defaultValue": "0"
    },
    "renderRow": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "(index: number) => HTMLElement",
        "resolved": "(index: number) => HTMLElement",
        "references": {
          "HTMLElement": {
            "location": "global"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      }
    }
  }; }
  static get states() { return {
    "height": {},
    "scrollTop": {}
  }; }
  static get elementRef() { return "el"; }
}
