import { defineStore } from "pinia";
import type { AuthSessionResponse } from "../../contractsAuth";
import type { PlayerIdentitySummary } from "../../contractsIdentity";
import { clearAuthSession, getAuthSession, setAuthSession, subscribeToAuthSession } from "../../authSession";
import {
  clearEffectivePlayerIdentityId,
  getEffectivePlayerIdentityId,
  setEffectivePlayerIdentityId,
  subscribeToEffectivePlayerIdentity,
} from "../../effectiveIdentitySession";

export const useAuthStore = defineStore("auth", {
  state: () => ({
    session: getAuthSession() as AuthSessionResponse | null,
    effectivePlayerId: getEffectivePlayerIdentityId() as string | null,
    availablePlayerIdentities: [] as PlayerIdentitySummary[],
    busy: false,
    initialized: false,
  }),
  getters: {
    isAuthenticated: (state) => state.session != null,
    email: (state) => state.session?.email ?? null,
    roles: (state) => state.session?.roles ?? [],
    canAccessGm: (state) => (state.session?.roles ?? []).some((role) => role === "gm" || role === "admin"),
    accessToken: (state) => state.session?.accessToken ?? null,
    isActingAsAlternateIdentity: (state) => state.effectivePlayerId != null && state.effectivePlayerId !== state.session?.userId,
    activePlayerId: (state) => state.effectivePlayerId ?? state.session?.userId ?? null,
  },
  actions: {
    setSession(session: AuthSessionResponse | null) {
      this.session = session;
      setAuthSession(session);
      if (!session || !(session.roles ?? []).some((role) => role === "gm" || role === "admin")) {
        this.effectivePlayerId = null;
        clearEffectivePlayerIdentityId();
      }
    },
    clearSession() {
      this.session = null;
      this.effectivePlayerId = null;
      this.availablePlayerIdentities = [];
      clearAuthSession();
      clearEffectivePlayerIdentityId();
    },
    setBusy(busy: boolean) {
      this.busy = busy;
    },
    setEffectivePlayerId(playerId: string | null) {
      this.effectivePlayerId = playerId && playerId.trim().length > 0 ? playerId.trim() : null;
      setEffectivePlayerIdentityId(this.effectivePlayerId);
    },
    setAvailablePlayerIdentities(identities: PlayerIdentitySummary[]) {
      this.availablePlayerIdentities = identities;
    },
    initialize() {
      if (this.initialized) {
        return;
      }

      this.initialized = true;
      subscribeToAuthSession((session) => {
        this.session = session as AuthSessionResponse | null;
      });
      subscribeToEffectivePlayerIdentity((playerId) => {
        this.effectivePlayerId = playerId;
      });
    },
  },
});
