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

import type { ObjstViewOverview } from './objst-view-overview.js';
import type { ObjstViewBuckets } from './objst-view-buckets.js';
import type { ObjstViewObjects } from './objst-view-objects.js';
import type { ObjstViewPolicies } from './objst-view-policies.js';
import type { ObjstViewConfig } from './objst-view-config.js';
import type { ObjstViewCredentials } from './objst-view-credentials.js';

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

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

  private viewTabs = [
    { name: 'Overview', iconName: 'lucide:layoutDashboard', element: (async () => (await import('./objst-view-overview.js')).ObjstViewOverview)() },
    { name: 'Buckets', iconName: 'lucide:database', element: (async () => (await import('./objst-view-buckets.js')).ObjstViewBuckets)() },
    { name: 'Browser', iconName: 'lucide:folderOpen', element: (async () => (await import('./objst-view-objects.js')).ObjstViewObjects)() },
    { name: 'Policies', iconName: 'lucide:shield', element: (async () => (await import('./objst-view-policies.js')).ObjstViewPolicies)() },
    { name: 'Config', iconName: 'lucide:settings', element: (async () => (await import('./objst-view-config.js')).ObjstViewConfig)() },
    { name: 'Access Keys', iconName: 'lucide:key', element: (async () => (await import('./objst-view-credentials.js')).ObjstViewCredentials)() },
  ];

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

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

    const loginSubscription = appstate.loginStatePart
      .select((stateArg) => stateArg)
      .subscribe((loginState) => {
        this.loginState = loginState;
        if (loginState.isLoggedIn) {
          appstate.serverStatePart.dispatchAction(appstate.fetchServerStatusAction, 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="ObjectStorage">
          <dees-simple-appdash
            name="ObjectStorage"
            .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,
        iconName: tab.iconName,
        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();
        appRouter.navigateToView(viewName);
      });
      appDash.addEventListener('logout', async () => {
        await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
      });
    }

    // Load the initial view on the appdash now that tabs are resolved
    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()) {
        try {
          const typedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
            interfaces.requests.IReq_GetServerStatus
          >('/typedrequest', 'getServerStatus');
          const response = await typedRequest.fire({ identity: loginState.identity });
          appstate.serverStatePart.setState({
            status: response.status,
            connectionInfo: response.connectionInfo,
          });
          this.loginState = loginState;
          if (simpleLogin) {
            await simpleLogin.switchToSlottedContent();
          }
        } catch (err) {
          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.serverStatePart.dispatchAction(appstate.fetchServerStatusAction, 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;
    appDash.loadView(targetTab);
  }
}
