/* eslint-disable no-console */
import type { OpenCVInstance } from './types';

let cvInstance: OpenCVInstance | null = null;
let isInitializing = false;
let initPromise: Promise<OpenCVInstance> | null = null;

export async function opencvInit(): Promise<OpenCVInstance> {
  if (cvInstance) {
    return cvInstance;
  }

  if (isInitializing) {
    return initPromise!;
  }

  isInitializing = true;
  initPromise = new Promise((resolve, reject) => {
    const __Module__ = {
      preRun: [],
      postRun: [],
      print: console.log,
      printErr: console.error,
      setStatus: console.log,
      onRuntimeInitialized: async () => {
        try {
          if (window.__cv__ instanceof Promise) {
            cvInstance = await window.__cv__;
          } else {
            cvInstance = window.__cv__;
          }
          resolve(cvInstance);
        } catch (error) {
          reject(error);
        }
      },
      totalDependencies: 0,
    };

    window.__Module__ = __Module__;
    window.onerror = () => {
      __Module__.setStatus(`Exception thrown, see JavaScript console`);
      __Module__.setStatus = (text: string) => {
        if (text) __Module__.printErr(`[post-exception status] ${text}`);
      };
    };

    const script1 = document.createElement('script');
    script1.src =
      'https://scplugins.oss-cn-shenzhen.aliyuncs.com/plugins/scloud/assets/qrcode/wechat_qrcode_files.js';
    script1.setAttribute('crossorigin', 'anonymous');
    script1.onerror = () => {
      reject(new Error('Failed to load wechat_qrcode_files.js'));
    };
    document.body.appendChild(script1);

    const script2 = document.createElement('script');
    script2.src =
      'https://scplugins.oss-cn-shenzhen.aliyuncs.com/plugins/scloud/assets/qrcode/opencv.js';
    script2.async = true;
    script2.setAttribute('crossorigin', 'anonymous');
    script2.type = 'application/javascript';
    script2.onerror = () => {
      reject(new Error('Failed to load OpenCV.js'));
    };
    document.body.appendChild(script2);
  });

  return initPromise;
}

declare global {
  interface Window {
    __Module__: any;
    __cv__: OpenCVInstance | Promise<OpenCVInstance>;
  }
}
