import { SwcHTMLBaseElementBase } from '../elements/base/SwcHTMLBaseElementBase';
import {elementDefine} from '../decorators/elementDefine';
import {SimpleApplication} from '@dooboostore/simple-boot/SimpleApplication';
import {SwcAppInterface, SwcConfigType, SwcAttributeConfigType} from '../elements/SwcAppInterface';
import {PathRouter} from '@dooboostore/core-web/routers/PathRouter';
import {HashRouter} from '@dooboostore/core-web/routers/HashRouter';
import {SimOption} from '@dooboostore/simple-boot/SimOption';
import {ConstructorType} from '@dooboostore/core/types';
import {Router, RouterEventType} from '@dooboostore/core-web/routers/Router';
import {Subscription} from "@dooboostore/core/message/Subscription";

@elementDefine({ name: 'swc-app-base', extends: 'base' })
export class SwcAppBase extends SwcHTMLBaseElementBase implements SwcAppInterface {
  public simpleApplication?: SimpleApplication;
  protected _router?: PathRouter | HashRouter;
  // protected _config?: SwcConfigType;
  private _isInitialized = false;
  private routerSubscription?: Subscription;

  constructor() {
    super();
  }


  async connectedCallback() {
    if (this._isInitialized) return;
    this._isInitialized = true;

    // Push to the end of the event loop to ensure global scripts are evaluated
    await new Promise(resolve => setTimeout(resolve, 0));

    const applicationConfigStr = this.getAttribute('swc-get-application-config');
    if (applicationConfigStr) {
      try {
        const userConfig: SwcAttributeConfigType = new Function(`return ${applicationConfigStr}`).apply(this);
        if (userConfig) {
          const _config = {
            routeType: 'path',
            window: window,
            ...userConfig
          };

          this._router = _config.routeType === 'path' ? new PathRouter({window: _config.window}) : new HashRouter({window: _config.window});
          this.routerSubscription = this._router.observable.subscribe((route: RouterEventType) => {
            // console.log('--------routing', route)
            if (route.triggerPoint === 'end') {
              this.routingProcess(route.path);
            }
          })
          const option = new SimOption({
            excludeProxys: [Node],
            rootRouter: _config.rootRouter
          });

          this.simpleApplication = new SimpleApplication(option);


          const otherInstanceSim = new Map<ConstructorType<any> | Function, any>();
          if (this._router) {
            otherInstanceSim.set(Router, this._router);
          }
          this.simpleApplication.run(otherInstanceSim);
          const data = this.simpleApplication.sim(_config.rootRouter)
          if (data instanceof Node && !this.contains(data)) {
            this.replaceChildren(data);
          }
          // console.log('--->', _config.path)
          if (_config.path) {
            await this._router?.go(_config.path);
          }
        }
      } catch (e) {
        console.error('[SWC-APP] Failed to execute swc-get-application-config script:', e);
      }
    }
  }

  disconnectedCallback() {
    this.routerSubscription?.unsubscribe();
  }

  async routing(path: string) {
    await this._router?.go(path);
  }

  private async routingProcess(path: string) {
    await this.simpleApplication?.routing(path);
  }
}
