import React, { useCallback, useContext, useEffect, useState } from 'react';
import classnames from 'classnames';
import { Texture } from 'fabric-texture';
import { Code, CodePreview, TextSwitch } from 'docs/components';
import { DocsContext } from 'docs/docs';
import styles from './style.less';

const UseWorker = () => {
  const { placeholder } = useContext(DocsContext);

  const [preview, setPreview] = useState<string>();
  const [method, setMethod] = useState<'canvas' | 'webgl'>('canvas');
  const [duration, setDuration] = useState<number>();

  const render = useCallback(async () => {
    if (!placeholder) return;
    const { naturalWidth, naturalHeight } = placeholder;

    const canvas = document.createElement('canvas');
    canvas.width = naturalWidth;
    canvas.height = naturalHeight;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    ctx.drawImage(placeholder, 0, 0);

    const texture = new Texture(canvas);

    texture
      .setSplitUnit(0.01)
      .setInputLimitSize({ width: 3000 })
      .setBoundCoords(0, 0, 'top', [
        { x: 0, y: 0 },
        { x: naturalWidth / 3, y: naturalHeight * 0.2 },
        { x: naturalWidth * (2 / 3), y: naturalHeight * 0.2 },
        { x: naturalWidth, y: 0 },
      ])
      .setBoundCoords(0, 0, 'bottom', [
        { x: 0, y: naturalHeight },
        { x: naturalWidth / 3, y: naturalHeight * 0.8 },
        { x: naturalWidth * (2 / 3), y: naturalHeight * 0.8 },
        { x: naturalWidth, y: naturalHeight },
      ]);

    if (method === 'canvas') texture.useCanvasRender();
    if (method === 'webgl') texture.useWebGLRender();

    const start = performance.now();
    const result = await texture.createWithWorker();
    const end = performance.now();

    setPreview(result.toDataURL());
    setDuration(end - start);
  }, [placeholder, method]);

  useEffect(() => {
    render();
  }, [render]);

  return (
    <div className={styles.demo}>
      {placeholder && preview && (
        <CodePreview className={styles.preview} src={preview}>
          {duration && <div className={styles.duration}>合成耗时：{Math.ceil(duration)}ms</div>}
        </CodePreview>
      )}
      <Code
        className={styles.code}
        link="sections/more-configuration/codes/use-worker.ts"
      >
        {(key) => {
          switch (key) {
            case 'canvas-render':
              return (
                <p
                  className={classnames(styles.method, { [styles.option]: method === 'webgl' })}
                  onClick={() => setMethod('canvas')}
                >
                  <span className={styles.text}>.useCanvasRender()</span>
                </p>
              );
            case 'webgl-render':
              return (
                <p
                  className={classnames(styles.method, { [styles.option]: method === 'canvas' })}
                  onClick={() => setMethod('webgl')}
                >
                  <span className={styles.text}>.useWebGLRender()</span>
                </p>
              );
          }
        }}
      </Code>
    </div>
  );
};

export default UseWorker;
