import Vue from 'vue';
import upperFirst from 'lodash/upperFirst';
import camelCase from 'lodash/camelCase';
import { isString } from 'lodash';

const TAGS = ['article', 'section', 'div', 'span', 'a'];

export default class ComponentImporter {
  private static registeredComponents: Record<string, string> = {};

  private static getComponentCamelCaseName(compName: string): string {
    if (!compName || !isString(compName)) throw new Error('compName must be string');
    // Get the PascalCase version of the component name
    const parts = compName.split('/');
    return upperFirst(
      camelCase(
        parts[parts.length - 1]
          // Remove the file extension from the end
          .replace(/\.\w+$/, '')
      )
    );
  }

  private static getComponentTemplateName(
    compName: string,
    relativePath: string,
    camelCase = true
  ): string {
    const compCamelCaseName = camelCase
      ? ComponentImporter.getComponentCamelCaseName(compName)
      : compName;
    const parts = compName.split('/');
    parts[parts.length - 1] = compCamelCaseName;
    const fileName = parts.join('/');
    return `${relativePath || ''}${fileName}`.replace(/\//gi, '_');
  }

  public static registerComponent(
    compName: string,
    relativePath = 'components/',
    camelCase = true
  ): string | null {
    // console.log('🐶 [registerComponent]', compName);
    if (!compName || TAGS.includes(compName)) {
      // no need to register
      return null;
    }

    const componentTemplateName = this.getComponentTemplateName(
      compName,
      relativePath,
      camelCase
    );
    // console.warn('check is comp registered', this.$options, Vue.$options.components, compCamelCaseName);
    // if( Object.keys(Vue.$options.components).contains(componentTemplateName) ) {
    //   // loaded
    //   return;
    // }
    if (ComponentImporter.registeredComponents[componentTemplateName]) {
      // already registered
      return componentTemplateName;
    }
    ComponentImporter.registeredComponents[componentTemplateName] = compName;

    // Get the component config
    const compCamelCaseName = camelCase
      ? ComponentImporter.getComponentCamelCaseName(compName)
      : compName;

    const parts = compName.split('/');
    parts[parts.length - 1] = compCamelCaseName;
    const fileName = parts.join('/');
    const componentConfig = async () => {
      try {
        return await import('@/recruits/' + relativePath + fileName + '.vue');
      } catch (e) {
        try {
          return await import('@/recruits/' + relativePath + fileName + '/index.vue');
        } catch (e) {
          console.log(`failed import ${fileName}`, e);
        }
      }
    };
    Vue.component(componentTemplateName, componentConfig);

    return componentTemplateName;
  }
}
