// [DEF:environmentContext:Store]
// @TIER: STANDARD
// @PURPOSE: Global selected environment context for navigation and safety cues.
// @LAYER: UI-State

import { derived, get, writable } from "svelte/store";
import { browser } from "$app/environment";
import { api } from "$lib/api.js";

const INITIAL_STATE = {
  environments: [],
  selectedEnvId: "",
  isLoading: false,
  isLoaded: false,
  error: null,
};

const SELECTED_ENV_KEY = "selected_env_id";
const contextStore = writable(INITIAL_STATE);

function getStoredSelectedEnvId() {
  if (!browser) return "";
  return localStorage.getItem(SELECTED_ENV_KEY) || "";
}

function persistSelectedEnvId(envId) {
  if (!browser) return;
  if (!envId) {
    localStorage.removeItem(SELECTED_ENV_KEY);
    return;
  }
  localStorage.setItem(SELECTED_ENV_KEY, envId);
}

function hasAuthToken() {
  if (!browser) return false;
  return Boolean(localStorage.getItem("auth_token"));
}

function resolveSelectedEnvId(environments, preferredEnvId) {
  if (!Array.isArray(environments) || environments.length === 0) return "";
  if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) {
    return preferredEnvId;
  }
  const stored = getStoredSelectedEnvId();
  if (stored && environments.some((env) => env.id === stored)) {
    return stored;
  }
  return environments[0].id;
}

function applySelectedEnvId(selectedEnvId) {
  contextStore.update((state) => {
    const exists = state.environments.some((env) => env.id === selectedEnvId);
    const nextSelectedEnvId = exists ? selectedEnvId : "";
    persistSelectedEnvId(nextSelectedEnvId);
    return { ...state, selectedEnvId: nextSelectedEnvId };
  });
}

async function refreshEnvironmentContext(preferredEnvId = "") {
  if (!hasAuthToken()) {
    contextStore.update((state) => ({
      ...state,
      isLoading: false,
      isLoaded: false,
      error: null,
    }));
    return;
  }

  contextStore.update((state) => ({ ...state, isLoading: true, error: null }));
  try {
    const environments = await api.getEnvironmentsList();
    const current = get(contextStore).selectedEnvId;
    const selectedEnvId = resolveSelectedEnvId(
      environments,
      preferredEnvId || current,
    );
    persistSelectedEnvId(selectedEnvId);
    contextStore.update((state) => ({
      ...state,
      environments,
      selectedEnvId,
      isLoading: false,
      isLoaded: true,
      error: null,
    }));
  } catch (error) {
    if (error?.status === 401) {
      contextStore.update((state) => ({
        ...state,
        isLoading: false,
        isLoaded: false,
        error: null,
      }));
      return;
    }
    console.error(
      "[environmentContext][Coherence:Failed] Failed to refresh environments",
      error,
    );
    contextStore.update((state) => ({
      ...state,
      environments: [],
      selectedEnvId: "",
      isLoading: false,
      isLoaded: true,
      error: error?.message || "Failed to load environments",
    }));
  }
}

async function initializeEnvironmentContext() {
  const state = get(contextStore);
  if (state.isLoading || state.isLoaded) return;
  await refreshEnvironmentContext();
}

export const environmentContextStore = {
  subscribe: contextStore.subscribe,
};

export function setSelectedEnvironment(envId) {
  applySelectedEnvId(envId);
}

export { refreshEnvironmentContext, initializeEnvironmentContext };

export const selectedEnvironmentStore = derived(
  environmentContextStore,
  ($context) =>
    $context.environments.find((env) => env.id === $context.selectedEnvId) ||
    null,
);

export const isProductionContextStore = derived(
  selectedEnvironmentStore,
  ($selectedEnvironment) =>
    String($selectedEnvironment?.stage || "").toUpperCase() === "PROD" ||
    Boolean($selectedEnvironment?.is_production),
);
// [/DEF:environmentContext:Store]
