// import item from "@/pages/website/routes/list/item";
import ListModule from "..";
import { ShowItem, ColDataType } from "../objects/item";

const cols: ColDataType[] = []; //{offset, items:[], halfOffset: 0, dragging: false}

let CanvasWidth = 0;
let CanvasHeight = 0;
const textH = 0;
let paddingOffset = 0;
let totalSizeCount = 0; //每行或每列的数量
let itemOffset = 0;

let ctx: CanvasRenderingContext2D | null;
let scale = 1;
function listDraw(this: ListModule, col: ColDataType, row: number, ctx: any) {
  const scrollType = this.store.scrollType;
  let x = 0,
    y = 0;
  const offseStep = itemOffset + paddingOffset;

  if (scrollType == "vertical") {
    x = row > 0 ? Math.floor(row * offseStep) + paddingOffset : paddingOffset;
    y = col.offset + CanvasHeight;
  }
  if (scrollType == "horizontal") {
    x = col.offset + CanvasWidth;
    y = row > 0 ? Math.floor(row * offseStep) + paddingOffset : paddingOffset;
  }

  const items = col.items;
  const total = items.length;

  for (let k = 0; k < total; k++) {
    //绘制
    const item = items[k];

    if (scrollType == "vertical") {
      y -= item.offsetY; //从下往上绘制
      if (y > CanvasHeight || y < -item.offsetY) continue; //超出部分，不进行绘制提交
      ctx.drawImage(
        item.img,
        0,
        0,
        item.w,
        item.h,
        Math.floor(x),
        Math.floor(y),
        Math.floor(itemOffset),
        Math.floor(item.offsetY - textH - paddingOffset)
      );
    }
    if (scrollType == "horizontal") {
      x -= item.offsetX;
      if (x > CanvasWidth || x < -item.offsetX) continue;
      ctx.drawImage(
        item.img,
        0,
        0,
        item.w,
        item.h,
        Math.floor(x),
        Math.floor(y),
        Math.floor(item.offsetX - textH - paddingOffset),
        Math.floor(itemOffset)
      );
    }

    // let text =
    //   item.name.length > 20
    //     ? item.name.substring(0, 19) + "..."
    //     : item.name;
    // ctx.fillText(text, x, Math.round(y + item.offsetY - textH * 1.2));
  }
}
export default ListModule.action({
  async initListCanvasDatas(wWidth: number, wHeight: number) {
    const totalRow = this.store.totalRow;
    const scrollType = this.store.scrollType;
    const items = await this.actions.loadData(wWidth, wHeight);
    scale = Math.max(devicePixelRatio, 2);

    // textH = 24 * scale;
    CanvasWidth = wWidth * scale;
    CanvasHeight = wHeight * scale;
    paddingOffset = 12 * scale;
    totalSizeCount = Math.ceil(items.length / totalRow) * 2;

    if (scrollType == "vertical") {
      this.actions.initVerticalList(items);
    }
    if (scrollType == "horizontal") {
      this.actions.initHorizontalList(items);
    }
  },
  initVerticalList(items) {
    const totalRow = this.store.totalRow;
    itemOffset = (CanvasWidth - paddingOffset * (totalRow + 1)) / totalRow;
    for (let i = 0; i < totalRow; i++) {
      const off = i * totalSizeCount;
      const arr: ShowItem[] = [];
      for (let k = 0; k < totalSizeCount; k++) {
        arr.push(items[(off + k) % items.length]);
      }
      this.actions.shuffleSelf(arr, totalSizeCount);
      //计算总高度
      let halfOffset = 0;
      arr.forEach((item) => {
        const h = ((item.h * 1.0) / item.w) * itemOffset;
        item.offsetY = h + textH + paddingOffset; //y step;
        halfOffset += item.offsetY;
      });

      const colData = {
        items: [...arr, ...arr],
        offset: 0,
        halfOffset: halfOffset,
        dragging: false,
        speed: i % 2 == 0 ? 1 : 2,
      };
      cols.push(colData);
    }
  },
  initHorizontalList(items) {
    const totalRow = this.store.totalRow;
    itemOffset = (CanvasHeight - paddingOffset * (totalRow + 1)) / totalRow;
    for (let i = 0; i < totalRow; i++) {
      const off = i * totalSizeCount;
      const arr: ShowItem[] = [];
      for (let k = 0; k < totalSizeCount; k++) {
        arr.push(items[(off + k) % items.length]);
      }
      this.actions.shuffleSelf(arr, totalSizeCount);

      //计算总高度
      let halfOffset = 0;
      arr.forEach((item) => {
        const w = ((item.w * 1.0) / item.h) * itemOffset;
        item.offsetX = w + textH + paddingOffset; //y step;
        halfOffset += item.offsetX;
      });

      const colData = {
        items: [...arr, ...arr],
        offset: 0,
        halfOffset: halfOffset,
        dragging: false,
        speed: i % 2 == 0 ? 1 : 2,
      };
      cols.push(colData);
    }
  },
  async startListRunning(canvas: HTMLCanvasElement) {
    this.actions.initDragEvents(canvas);
    canvas.width = CanvasWidth;
    canvas.height = CanvasHeight;

    ctx = canvas.getContext("2d");

    const cache = document.createElement("canvas");
    cache.width = CanvasWidth;
    cache.height = CanvasHeight;
    const cacheCtx = cache.getContext("2d");
    if (!cacheCtx) {
      return;
    }
    cacheCtx.font = "24px sans-serif";
    cacheCtx.fillStyle = "#FFFFFF";
    cacheCtx.textBaseline = "top";

    let loopId = 0;

    let n = cols.length;
    let i = 0;
    let lastTime = Date.now();
    let dtaTime = 0;
    const loop = () => {
      dtaTime = Date.now() - lastTime;
      lastTime = Date.now();
      n = cols.length;
      while (n--) {
        const item = cols[n];
        if (!item.dragging) {
          //没有拖拽进行累积
          item.offset = Math.floor(item.offset + item.speed);
        }
        //   console.log(item.offset);
        if (item.offset >= item.halfOffset) item.offset -= item.halfOffset;
        if (item.offset < 0) item.offset += item.halfOffset;
      }
      cacheCtx?.clearRect(0, 0, CanvasWidth, CanvasHeight);
      n = cols.length;
      for (i = 0; i < n; i++) {
        listDraw.call(this, cols[i], i, cacheCtx);
      }
      ctx?.clearRect(0, 0, CanvasWidth, CanvasHeight);
      ctx?.drawImage(cache, 0, 0);
      loopId = requestAnimationFrame(loop);
    };
    loop();
  },

  initDragEvents(canvas: HTMLCanvasElement) {
    let down = false;
    let downIndex = -1;
    let downY = 0;
    let downX = 0;

    let initOffset = 0;
    let downTime = 0;
    let moving = false;
    const fingers: { [name: number]: any } = {};
    const scrollType = this.store.scrollType;

    const onMouseDown = (e: MouseEvent) => {
      const x = e.clientX * scale;
      const y = e.clientY * scale;
      downY = e.clientY * scale;
      downX = e.clientX * scale;
      down = true;
      downIndex =
        scrollType == "vertical"
          ? Math.floor(x / (itemOffset + paddingOffset))
          : Math.floor(y / (itemOffset + paddingOffset));

      cols[downIndex].dragging = true;
      initOffset = cols[downIndex].offset;
      downTime = Date.now();
    };

    const onMouseMove = (e: MouseEvent) => {
      if (!down || downIndex < 0) return;
      moving = true;

      console.log("move");
      let dtaOffset = 0;
      if (scrollType == "vertical") {
        dtaOffset = e.clientY * scale - dtaOffset;
      }
      if (scrollType == "horizontal") {
        dtaOffset = e.clientX * scale - dtaOffset;
      }

      cols[downIndex].offset = initOffset + dtaOffset;
    };
    const onMouseUp = (e: MouseEvent) => {
      console.log("up");
      down = false;
      if (downIndex >= 0) {
        cols[downIndex].dragging = false;
        const dtaTime = Date.now() - downTime;
        if (dtaTime < 200 && !moving) {
          const col = cols[downIndex];
          let offset = col.offset;
          if (offset >= col.halfOffset) offset -= col.halfOffset;
          if (offset < 0) offset += col.halfOffset;

          const n = col.items.length;
          let z =
            scrollType == "vertical"
              ? offset + CanvasHeight
              : offset + CanvasWidth;
          for (let k = 0; k < n; k++) {
            const item = col.items[k];
            if (scrollType == "vertical") {
              z -= item.offsetY;
              if (downY > z && downY < z + item.offsetY) {
                console.log("click->", item.name);
                this.actions.popDialog(e, item);
                break;
              }
            }
            if (scrollType == "horizontal") {
              z -= item.offsetX;
              if (downX > z && downX < z + item.offsetX) {
                console.log("click->", item.name);
                this.actions.popDialog(e, item);
                break;
              }
            }
          }
        }
      }
      downIndex = -1;
      moving = false;
    };
    const onTouchstart = (e: TouchEvent) => {
      const touches = e.touches;
      for (let i = 0; i < touches.length; i++) {
        const touch = touches[i];
        if (fingers[touch.identifier]) {
          continue;
        }
        const x = touch.clientX * scale;
        const y = touch.clientY * scale;
        const downIndex =
          scrollType == "vertical"
            ? Math.floor(x / (itemOffset + paddingOffset))
            : Math.floor(y / (itemOffset + paddingOffset));
        cols[downIndex].dragging = true;
        const offset = cols[downIndex].offset;
        fingers[touch.identifier] = {
          identifier: touch.identifier,
          downY: y,
          downX: x,
          downIndex: downIndex,
          offset: offset,
          downTime: Date.now(),
        };
      }
    };
    const onTouchMove = (e: TouchEvent) => {
      const touches = e.changedTouches;
      for (let i = 0; i < touches.length; i++) {
        const touch = touches[i];
        const finger = fingers[touch.identifier];
        if (!finger) {
          continue;
        }
        finger.moving = true;
        let dtaOffset = 0;
        if (scrollType == "vertical") {
          dtaOffset = touch.clientY * scale - finger.downY;
        }
        if (scrollType == "horizontal") {
          dtaOffset = touch.clientX * scale - finger.downY;
        }
        cols[finger.downIndex].offset = finger.offset + dtaOffset;
      }
    };

    const onTouchEnd = (e: TouchEvent) => {
      const touches = e.changedTouches;
      for (let i = 0; i < touches.length; i++) {
        const touch = touches[i];
        const finger = fingers[touch.identifier];

        if (!finger) {
          continue;
        }

        cols[finger.downIndex].dragging = false;
        const dtaTime = Date.now() - finger.downTime;
        if (dtaTime < 200 && !finger.moving) {
          const col = cols[finger.downIndex];
          let offset = col.offset;
          if (offset >= col.halfOffset) offset -= col.halfOffset;
          if (offset < 0) offset += col.halfOffset;
          const n = col.items.length;
          let z =
            scrollType == "vertical"
              ? offset + CanvasHeight
              : offset + CanvasWidth;
          for (let k = 0; k < n; k++) {
            const item = col.items[k];

            if (scrollType == "vertical") {
              z -= item.offsetY;
              if (finger.downY > z && finger.downY < z + item.offsetY) {
                this.actions.popDialog(touch, item);
                break;
              }
            }
            if (scrollType == "horizontal") {
              z -= item.offsetX;
              if (finger.downX > z && finger.downX < z + item.offsetX) {
                this.actions.popDialog(touch, item);
                break;
              }
            }
          }
        }
        delete fingers[touch.identifier];
      }
    };

    canvas.addEventListener("mousedown", onMouseDown, false);
    canvas.addEventListener("mousemove", onMouseMove, false);
    document.addEventListener("mouseup", onMouseUp, false);

    canvas.addEventListener("touchstart", onTouchstart, false);
    canvas.addEventListener("touchmove", onTouchMove, false);
    document.addEventListener("touchend", onTouchEnd, false);
  },
});
