import "core-js/modules/es.array.reduce.js";
import { matrix, multiply, flatten, identity } from 'mathjs'; // 小孔成像纠正 矩阵

const pinhole = matrix([[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);

function distance(...arr) {
  return Math.sqrt(arr.reduce((t, v) => t += v ** 2, 0));
}

function transform(e, boo) {
  var _ev, _ev2;

  let ev;
  let el;

  if (e.currentTarget) {
    ev = e;
    el = ev.currentTarget;
  } else {
    el = e;
  }

  let offsetX = ((_ev = ev) === null || _ev === void 0 ? void 0 : _ev.offsetX) || 0;
  let offsetY = ((_ev2 = ev) === null || _ev2 === void 0 ? void 0 : _ev2.offsetY) || 0;
  let w = el.offsetWidth,
      w2 = w / 2;
  let h = el.offsetHeight,
      h2 = h / 2;
  const radius = distance(w2, h2);
  const ratio = distance(offsetX - w2, offsetY - h2) / radius;
  let rotateX = -2 * (offsetY - h2) / h2,
      rotateY = 2 * (offsetX - w2) / w2;
  let thetX = rotateX * (Math.PI / 180),
      thetY = rotateY * (Math.PI / 180); // y旋转矩阵

  const rotationYT = matrix([[Math.cos(thetY), 0, -Math.sin(thetY), 0], [0, 1, 0, 0], [Math.sin(thetY), 0, Math.cos(thetY), 0], [0, 0, 0, 1]]); // x旋转矩阵

  const rotationXT = matrix([[1, 0, 0, 0], [0, Math.cos(thetX), Math.sin(thetX), 0], [0, -Math.sin(thetX), Math.cos(thetX), 0], [0, 0, 0, 1]]); // 矩阵变换的原点

  const ox = w2,
        oy = h2,
        oz = boo ? w2 + radius * 0.02 * (1 - ratio) : w2;
  const transOT = matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [-ox, -oy, -oz, 1]]);
  const transCenterT = matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [ox, oy, oz, 1]]);
  let n = -w / 2;
  let f = -w * 1000;
  let r = 1;
  let l = -1;
  let t = 1;
  let b = -1;
  let m00 = 2 * n / (r - l);
  let m11 = 2 * n / (t - b);
  let m22 = (n + f) / (n - f);
  let m23 = 2 * f * n / (n - f); // 透视矩阵

  const aperspectT = matrix([[m00, 0, 0, 0], [0, m11, 0, 0], [0, 0, m22, -1], [0, 0, m23, 0]]);
  let result = identity(4);

  if (boo) {
    const ox = w - offsetX,
          oy = h - offsetY,
          oz = 0;
    const transOT = matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [-ox, -oy, -oz, 1]]);
    const transCenterT = matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [ox, oy, oz, 1]]);
    result = multiply(result, transOT); //

    result = multiply(result, rotationYT); // x 旋转

    result = multiply(result, rotationXT); // y 旋转
    //

    result = multiply(result, transCenterT);
  } //把图像移动至原点(0, 0),方便计算


  result = multiply(result, transOT); //透视

  result = multiply(result, aperspectT); //小孔成像纠正

  result = multiply(result, pinhole); //还原至画布中央

  result = multiply(result, transCenterT); // @ts-ignore

  let mStr = flatten(result)._data.join(',');

  el.style.transform = `matrix3d(${mStr}) `;
  el.style.transformOrigin = `0 0`;
}

function addEventListener(el, mousedown, mouseup) {
  const _up = e => {
    mouseup(e);
    window.removeEventListener('mouseup', _up);
  };

  const _down = e => {
    mousedown(e);
    window.addEventListener('mouseup', _up);
  };

  el.addEventListener('mousedown', _down);
}

const name = 'sunken';
const directive = {
  mounted(el) {
    el.style.transition = `unset`;
    transform(el);
    void el.offsetWidth;
    el.style.transition = `transform .1s`;
    addEventListener(el, e => {
      transform(e, true);
    }, e => {
      transform(el);
    });
  }

};
export const directives = {
  [name]: directive
};
const Sunken = {};

Sunken.install = app => {
  app.directive(name, directive);
};

export default Sunken;