import * as plugins from '../plugins.js';
import * as appstate from '../appstate.js';
import * as interfaces from '../../ts_interfaces/index.js';
import {
  DeesElement,
  customElement,
  html,
  state,
  css,
  cssManager,
  type TemplateResult,
} from '@design.estate/dees-element';

import type { ObViewDashboard } from './ob-view-dashboard.js';
import type { ObViewServices } from './ob-view-services.js';
import type { ObViewNetwork } from './ob-view-network.js';
import type { ObViewRegistries } from './ob-view-registries.js';
import type { ObViewTokens } from './ob-view-tokens.js';
import type { ObViewSettings } from './ob-view-settings.js';

@customElement('ob-app-shell')
export class ObAppShell extends DeesElement {
  @state()
  accessor loginState: appstate.ILoginState = { identity: null, isLoggedIn: false };

  @state()
  accessor uiState: appstate.IUiState = {
    activeView: 'dashboard',
    autoRefresh: true,
    refreshInterval: 30000,
  };

  @state()
  accessor loginLoading: boolean = false;

  @state()
  accessor loginError: string = '';

  private viewTabs = [
    { name: 'Dashboard', element: (async () => (await import('./ob-view-dashboard.js')).ObViewDashboard)() },
    { name: 'Services', element: (async () => (await import('./ob-view-services.js')).ObViewServices)() },
    { name: 'Network', element: (async () => (await import('./ob-view-network.js')).ObViewNetwork)() },
    { name: 'Registries', element: (async () => (await import('./ob-view-registries.js')).ObViewRegistries)() },
    { name: 'Tokens', element: (async () => (await import('./ob-view-tokens.js')).ObViewTokens)() },
    { name: 'Settings', element: (async () => (await import('./ob-view-settings.js')).ObViewSettings)() },
  ];

  private resolvedViewTabs: Array<{ name: string; element: any }> = [];

  constructor() {
    super();
    document.title = 'Onebox';

    const loginSubscription = appstate.loginStatePart
      .select((stateArg) => stateArg)
      .subscribe((loginState) => {
        this.loginState = loginState;
        if (loginState.isLoggedIn) {
          appstate.systemStatePart.dispatchAction(appstate.fetchSystemStatusAction, null);
        }
      });
    this.rxSubscriptions.push(loginSubscription);

    const uiSubscription = appstate.uiStatePart
      .select((stateArg) => stateArg)
      .subscribe((uiState) => {
        this.uiState = uiState;
        this.syncAppdashView(uiState.activeView);
      });
    this.rxSubscriptions.push(uiSubscription);
  }

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        display: block;
        width: 100%;
        height: 100%;
      }
      .maincontainer {
        width: 100%;
        height: 100vh;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <div class="maincontainer">
        <dees-simple-login name="Onebox">
          <dees-simple-appdash
            name="Onebox"
            .viewTabs=${this.resolvedViewTabs}
          >
          </dees-simple-appdash>
        </dees-simple-login>
      </div>
    `;
  }

  public async firstUpdated() {
    // Resolve async view tab imports
    this.resolvedViewTabs = await Promise.all(
      this.viewTabs.map(async (tab) => ({
        name: tab.name,
        element: await tab.element,
      })),
    );
    this.requestUpdate();
    await this.updateComplete;

    const simpleLogin = this.shadowRoot!.querySelector('dees-simple-login') as any;
    if (simpleLogin) {
      simpleLogin.addEventListener('login', (e: CustomEvent) => {
        this.login(e.detail.data.username, e.detail.data.password);
      });
    }

    const appDash = this.shadowRoot!.querySelector('dees-simple-appdash') as any;
    if (appDash) {
      appDash.addEventListener('view-select', (e: CustomEvent) => {
        const viewName = e.detail.view.name.toLowerCase();
        appstate.uiStatePart.dispatchAction(appstate.setActiveViewAction, { view: viewName });
      });
      appDash.addEventListener('logout', async () => {
        await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
      });
    }

    // Load the initial view on the appdash now that tabs are resolved
    // (appdash's own firstUpdated already fired when viewTabs was still empty)
    if (appDash && this.resolvedViewTabs.length > 0) {
      const initialView = this.resolvedViewTabs.find(
        (t) => t.name.toLowerCase() === this.uiState.activeView,
      ) || this.resolvedViewTabs[0];
      await appDash.loadView(initialView);
    }

    // Check for stored session (persistent login state)
    const loginState = appstate.loginStatePart.getState();
    if (loginState.identity?.jwt) {
      if (loginState.identity.expiresAt > Date.now()) {
        // Validate token with server before switching to dashboard
        // (server may have restarted with a new JWT secret)
        try {
          const typedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
            interfaces.requests.IReq_GetSystemStatus
          >('/typedrequest', 'getSystemStatus');
          const response = await typedRequest.fire({ identity: loginState.identity });
          // Token is valid - switch to dashboard
          appstate.systemStatePart.setState({ status: response.status });
          this.loginState = loginState;
          if (simpleLogin) {
            await simpleLogin.switchToSlottedContent();
          }
        } catch (err) {
          // Token rejected by server - clear session
          console.warn('Stored session invalid, returning to login:', err);
          await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
        }
      } else {
        await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
      }
    }
  }

  private async login(username: string, password: string) {
    const domtools = await this.domtoolsPromise;
    const simpleLogin = this.shadowRoot!.querySelector('dees-simple-login') as any;
    const form = simpleLogin?.shadowRoot?.querySelector('dees-form') as any;

    if (form) {
      form.setStatus('pending', 'Logging in...');
    }

    const newState = await appstate.loginStatePart.dispatchAction(appstate.loginAction, {
      username,
      password,
    });

    if (newState.identity) {
      if (form) {
        form.setStatus('success', 'Logged in!');
      }
      if (simpleLogin) {
        await simpleLogin.switchToSlottedContent();
      }
      await appstate.systemStatePart.dispatchAction(appstate.fetchSystemStatusAction, null);
    } else {
      if (form) {
        form.setStatus('error', 'Login failed!');
        await domtools.convenience.smartdelay.delayFor(2000);
        form.reset();
      }
    }
  }

  private syncAppdashView(viewName: string): void {
    const appDash = this.shadowRoot?.querySelector('dees-simple-appdash') as any;
    if (!appDash || this.resolvedViewTabs.length === 0) return;
    const targetTab = this.resolvedViewTabs.find((t) => t.name.toLowerCase() === viewName);
    if (!targetTab) return;
    // Use appdash's own loadView method for proper view management
    appDash.loadView(targetTab);
  }
}
