import {
  detectActiveProfile,
  getFallbackGlyphs,
  resolveGlyphsForProfile,
  watchGamepadProfile,
} from "./gamepadProfile.js";
import { createPasskeyController } from "./passkey.js";
import { loadExistingUser } from "./users.js";

const FALLBACK_THEME = {
  colors: {
    bg: "#0b1020",
    panel: "#141c33",
    panelAlt: "#1b2747",
    text: "#eef4ff",
    muted: "#9eb1d3",
    accent: "#50d6ff",
    danger: "#ff6b88",
    success: "#7dff9e",
    focus: "#50d6ff",
    overlay: "rgba(5, 8, 18, 0.78)",
  },
  spacing: {
    xs: 6,
    sm: 10,
    md: 16,
    lg: 24,
    xl: 36,
  },
  radius: {
    sm: 10,
    md: 16,
    lg: 22,
  },
  typography: {
    body: 18,
    title: 24,
    display: 34,
  },
};

export const createAppState = () => {
  const passkey = createPasskeyController();
  const state = {
    passkey,
    locked: true,
    activeView: "lock",
    user: null,
    profileName: "Nebula User",
    userSetupRequired: true,
    nebula: {
      coreReady: false,
      source: "local-fallback",
      navigation: null,
      input: null,
      glyphs: null,
      theme: null,
      ui: null,
    },
    theme: FALLBACK_THEME,
    controllerProfile: "generic",
    glyphs: getFallbackGlyphs("generic"),
    settingsCategory: "system",
    settingsValues: {
      network: true,
      audio: true,
      display: false,
      storage: true,
      system: false,
    },
    passkeySetupRequired: !passkey.hasPasskey(),
  };

  state.refreshControllerGlyphs = (profile = detectActiveProfile()) => {
    state.controllerProfile = profile;
    state.glyphs = resolveGlyphsForProfile(profile, state.nebula.glyphs);
    window.dispatchEvent(
      new CustomEvent("nebula-controller-profile", {
        detail: { profile },
      }),
    );
  };

  state.startGamepadProfileWatcher = () => {
    if (state.stopGamepadProfileWatcher) {
      state.stopGamepadProfileWatcher();
    }
    state.stopGamepadProfileWatcher = watchGamepadProfile((profile) => {
      state.refreshControllerGlyphs(profile);
    });
  };

  const applyThemeToDocument = () => {
    const root = document.documentElement;
    const { colors, spacing, radius, typography } = state.theme;

    Object.entries(colors).forEach(([key, value]) => root.style.setProperty(`--nebula-color-${key}`, value));
    Object.entries(spacing).forEach(([key, value]) => root.style.setProperty(`--nebula-spacing-${key}`, `${value}px`));
    Object.entries(radius).forEach(([key, value]) => root.style.setProperty(`--nebula-radius-${key}`, `${value}px`));
    Object.entries(typography).forEach(([key, value]) => root.style.setProperty(`--nebula-type-${key}`, `${value}px`));
  };

  const initializeNebulaCore = async () => {
    try {
      const [input, navigation, glyphs, theme, ui] = await Promise.all([
        import("@nebulaproject/core/input"),
        import("@nebulaproject/core/navigation"),
        import("@nebulaproject/core/glyphs"),
        import("@nebulaproject/core/theme"),
        import("@nebulaproject/core/ui"),
      ]);

      state.nebula = {
        coreReady: true,
        source: "@nebulaproject/core",
        input,
        navigation,
        glyphs,
        theme,
        ui,
      };

      state.theme = typeof theme.createTheme === "function" ? theme.createTheme({}) : FALLBACK_THEME;

      state.refreshControllerGlyphs(detectActiveProfile());
    } catch (_error) {
      state.nebula = {
        ...state.nebula,
        coreReady: false,
        source: "local-fallback",
      };
      state.theme = FALLBACK_THEME;
      state.refreshControllerGlyphs("generic");
    }

    applyThemeToDocument();
  };

  const initializeUser = async () => {
    const user = await loadExistingUser();
    state.user = user;
    state.userSetupRequired = !user;
    state.profileName = user?.name ?? "New User";
  };

  state.initializeNebulaCore = initializeNebulaCore;
  state.initializeUser = initializeUser;
  return state;
};
