import { ContextEnvEnum, ContextSourceEnum } from '@spiffy-ai/commerce-api-client';
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { VariantInfo } from 'src/application/models';
import { UserIdentityContextType } from 'src/contexts/userIdentityContext/userIdentityContext';
import { v4 as uuid } from 'uuid';
import { contextSourceAtom, envAtom, orgIdAtom, orgShortNameAtom } from '../envive/enviveConfig';

import { variantInfoAtom } from './variant';

export interface AppDetails {
  orgId: string;
  orgShortName: string;
  chatId: string;
  userId: string;
  source: ContextSourceEnum;
  env: ContextEnvEnum;
  variantInfo: VariantInfo;
}

export {
  pageUserEventAtom,
  pageVariantInfoAtom,
  variantInfoAtom,
  hasParsedVariantInfoAtom,
  supportedEventAtom,
} from './variant';

// Internal storage for the user ID
// Caches the result from UserIdentityService
const internalUserIdAtom = atom<string | undefined>(undefined);

// Main user ID atom
// Reads from cache or calls UserIdentityService
export const userIdAtom = atom(
  get => {
    const cachedUserId = get(internalUserIdAtom);

    if (cachedUserId) {
      return cachedUserId;
    }

    throw new Error('UserId is referenced before it is set - call initializeUser() first');
  },
  (_, set, value: string) => {
    set(internalUserIdAtom, value);
  },
);

export const userIdentityAtom = atom<UserIdentityContextType | undefined>(undefined);

export const appSourceAtom = atom<ContextSourceEnum>(
  (get): ContextSourceEnum => get(contextSourceAtom) ?? ContextSourceEnum.App,
);
export const chatIdAtom = atomWithStorage<string>('v1-spiffy-chat-session-id', uuid(), undefined, {
  getOnInit: true,
});

export const appDetailsAtom = atom(
  (get): AppDetails => ({
    orgId: get(orgIdAtom) ?? '',
    // TODO: orgShortName should be available when this atom is created
    orgShortName: get(orgShortNameAtom) ?? 'spiffy-ai',
    chatId: get(chatIdAtom),
    userId: get(userIdAtom),
    source: get(appSourceAtom),
    env: get(envAtom) as ContextEnvEnum,
    variantInfo: get(variantInfoAtom),
  }),
);
