import * as SecureStore from 'expo-secure-store';
import {
  ApiMode,
  AppConfig,
  CrmPresetId,
  CRM_PRESETS,
  DEFAULT_CONFIG,
  DEFAULT_INSTALL_CONFIG,
} from '../config/apiMode';

const TOKEN_KEY = 'immotech_auth_token';
const USER_KEY = 'immotech_user';
const CONFIG_MODE_KEY = 'immotech_api_mode';
const CONFIG_URL_KEY = 'immotech_api_base_url';
const CONFIG_PRESET_KEY = 'immotech_api_preset';
const CONFIG_LAN_HOST_KEY = 'immotech_api_lan_host';
const PROMOTEUR_CODE_KEY = 'immotech_promoteur_code';
const REMEMBER_LOGIN_KEY = 'immotech_remember_login';
const REMEMBERED_USER_KEY = 'immotech_remembered_username';
const REMEMBERED_PASSWORD_KEY = 'immotech_remembered_password';
const BIOMETRIC_LOGIN_KEY = 'immotech_biometric_login';
const AGENDA_SCOPE_KEY = 'immotech_agenda_scope';

export type RememberedLogin = {
  enabled: boolean;
  username: string;
  password: string;
};

export async function getToken(): Promise<string | null> {
  return SecureStore.getItemAsync(TOKEN_KEY);
}

/** Last agenda scope chosen (scope + targeted agent / agency), as raw JSON. */
export async function getStoredAgendaScope(): Promise<string | null> {
  return SecureStore.getItemAsync(AGENDA_SCOPE_KEY);
}

export async function setStoredAgendaScope(value: string): Promise<void> {
  await SecureStore.setItemAsync(AGENDA_SCOPE_KEY, value);
}

export async function setToken(token: string): Promise<void> {
  await SecureStore.setItemAsync(TOKEN_KEY, token);
}

export async function clearToken(): Promise<void> {
  await SecureStore.deleteItemAsync(TOKEN_KEY);
  await SecureStore.deleteItemAsync(USER_KEY);
  // Keep CRM URL (setAppConfig) + remembered login — logout must not reset the server.
}

export async function getRememberedLogin(): Promise<RememberedLogin> {
  const enabled = (await SecureStore.getItemAsync(REMEMBER_LOGIN_KEY)) === '1';
  const username = (await SecureStore.getItemAsync(REMEMBERED_USER_KEY)) ?? '';
  const password = (await SecureStore.getItemAsync(REMEMBERED_PASSWORD_KEY)) ?? '';
  return { enabled, username, password };
}

export async function setRememberedLogin(opts: {
  enabled: boolean;
  username?: string;
  password?: string;
}): Promise<void> {
  if (!opts.enabled) {
    await SecureStore.deleteItemAsync(REMEMBER_LOGIN_KEY);
    await SecureStore.deleteItemAsync(REMEMBERED_USER_KEY);
    await SecureStore.deleteItemAsync(REMEMBERED_PASSWORD_KEY);
    await setBiometricLoginEnabled(false);
    return;
  }
  await SecureStore.setItemAsync(REMEMBER_LOGIN_KEY, '1');
  const username = opts.username?.trim() ?? '';
  const password = opts.password ?? '';
  if (username) await SecureStore.setItemAsync(REMEMBERED_USER_KEY, username);
  if (password) await SecureStore.setItemAsync(REMEMBERED_PASSWORD_KEY, password);
}

/** Face ID / Touch ID unlock for saved session or remembered credentials. */
export async function isBiometricLoginEnabled(): Promise<boolean> {
  return (await SecureStore.getItemAsync(BIOMETRIC_LOGIN_KEY)) === '1';
}

export async function setBiometricLoginEnabled(enabled: boolean): Promise<void> {
  if (!enabled) {
    await SecureStore.deleteItemAsync(BIOMETRIC_LOGIN_KEY);
    return;
  }
  await SecureStore.setItemAsync(BIOMETRIC_LOGIN_KEY, '1');
}

export async function setStoredUser(user: object): Promise<void> {
  await SecureStore.setItemAsync(USER_KEY, JSON.stringify(user));
}

export async function getStoredUserRaw(): Promise<string | null> {
  return SecureStore.getItemAsync(USER_KEY);
}

export async function getStoredPromoteurCode(): Promise<string | null> {
  return SecureStore.getItemAsync(PROMOTEUR_CODE_KEY);
}

export async function setStoredPromoteurCode(code: string): Promise<void> {
  const normalized = code.trim().toUpperCase();
  if (!normalized) {
    await SecureStore.deleteItemAsync(PROMOTEUR_CODE_KEY);
    return;
  }
  await SecureStore.setItemAsync(PROMOTEUR_CODE_KEY, normalized);
}

export async function getAppConfig(): Promise<AppConfig> {
  const mode = (await SecureStore.getItemAsync(CONFIG_MODE_KEY)) as ApiMode | null;
  const url = await SecureStore.getItemAsync(CONFIG_URL_KEY);
  const presetRaw = await SecureStore.getItemAsync(CONFIG_PRESET_KEY);
  const lanHost = await SecureStore.getItemAsync(CONFIG_LAN_HOST_KEY);

  // No Settings saved yet → ma.immotech.app by default
  if (!mode && !url?.trim()) {
    return { ...DEFAULT_INSTALL_CONFIG };
  }

  const resolvedMode: ApiMode = mode === 'new' ? 'new' : 'legacy';
  const defaults = DEFAULT_CONFIG[resolvedMode];
  const baseUrl = (url?.trim() || defaults.baseUrl).replace(/\/$/, '');
  let preset = (presetRaw as CrmPresetId | null) ?? defaults.preset;

  if (preset && preset !== 'custom') {
    const known = CRM_PRESETS.find((p) => p.id === preset);
    if (!known) preset = 'custom';
  }

  // Prefer URL over stale preset id (e.g. saved immodev URL with legacy-ma id).
  const byUrl = CRM_PRESETS.find(
    (p) => p.baseUrl.replace(/\/$/, '') === baseUrl && p.mode === resolvedMode,
  );
  if (byUrl) preset = byUrl.id;

  return {
    mode: resolvedMode,
    baseUrl,
    preset: preset ?? undefined,
    lanHost: lanHost?.trim() || undefined,
  };
}

/** Write CRM URL / preset to SecureStore without clearing the session token. */
export async function writeAppConfig(config: AppConfig): Promise<void> {
  const nextUrl = config.baseUrl.replace(/\/$/, '');
  await SecureStore.setItemAsync(CONFIG_MODE_KEY, config.mode);
  await SecureStore.setItemAsync(CONFIG_URL_KEY, nextUrl);
  if (config.preset) {
    await SecureStore.setItemAsync(CONFIG_PRESET_KEY, config.preset);
  } else {
    await SecureStore.deleteItemAsync(CONFIG_PRESET_KEY);
  }
  if (config.lanHost?.trim()) {
    await SecureStore.setItemAsync(CONFIG_LAN_HOST_KEY, config.lanHost.trim());
  } else {
    await SecureStore.deleteItemAsync(CONFIG_LAN_HOST_KEY);
  }
}

/**
 * Persist the resolved CRM config used for this session (survives logout).
 * Call after a successful login so the login URL is never lost on disconnect.
 */
export async function persistLoginAppConfig(): Promise<AppConfig> {
  const config = await getAppConfig();
  await writeAppConfig(config);
  return config;
}

export async function setAppConfig(config: AppConfig): Promise<void> {
  const prev = await getAppConfig();
  const nextUrl = config.baseUrl.replace(/\/$/, '');
  const crmChanged = prev.mode !== config.mode || prev.baseUrl.replace(/\/$/, '') !== nextUrl;
  if (crmChanged) {
    // New CRM uses Bearer/Sanctum; legacy uses X-AUTH-TOKEN (tokenMobile). Never reuse across CRMs.
    await clearToken();
  }
  await writeAppConfig(config);
}

export async function clearAppConfig(): Promise<void> {
  await SecureStore.deleteItemAsync(CONFIG_MODE_KEY);
  await SecureStore.deleteItemAsync(CONFIG_URL_KEY);
  await SecureStore.deleteItemAsync(CONFIG_PRESET_KEY);
  await SecureStore.deleteItemAsync(CONFIG_LAN_HOST_KEY);
}
