import { db } from '../db/db_index';
import { keyValStore } from '../db/schema';
import redisClient from './redis-client';
import { CONST_KEYS, CONST_KEYS_ARRAY, type ConstKey } from './const-keys';

const CONST_REDIS_PREFIX = 'const:';

export const computeConstants = async (): Promise<void> => {
  try {
    console.log('Computing constants from database...');

    const constants = await db.select().from(keyValStore);
    
    for (const constant of constants) {
      const redisKey = `${CONST_REDIS_PREFIX}${constant.key}`;
      const value = JSON.stringify(constant.value);
      console.log({redisKey, value})
      
      await redisClient.set(redisKey, value);
    }

    console.log(`Computed and stored ${constants.length} constants in Redis`);
  } catch (error) {
    console.error('Failed to compute constants:', error);
    throw error;
  }
};

export const getConstant = async <T = any>(key: string): Promise<T | null> => {
  const redisKey = `${CONST_REDIS_PREFIX}${key}`;
  const value = await redisClient.get(redisKey);
  
  if (!value) {
    return null;
  }
  
  try {
    return JSON.parse(value) as T;
  } catch {
    return value as unknown as T;
  }
};

export const getConstants = async <T = any>(keys: string[]): Promise<Record<string, T | null>> => {
  const redisKeys = keys.map(key => `${CONST_REDIS_PREFIX}${key}`);
  const values = await redisClient.MGET(redisKeys);
  
  const result: Record<string, T | null> = {};
  keys.forEach((key, index) => {
    const value = values[index];
    if (!value) {
      result[key] = null;
    } else {
      try {
        result[key] = JSON.parse(value) as T;
      } catch {
        result[key] = value as unknown as T;
      }
    }
  });
  
  return result;
};

export const getAllConstValues = async (): Promise<Record<ConstKey, any>> => {
  const result: Record<string, any> = {};
  
  for (const key of CONST_KEYS_ARRAY) {
    result[key] = await getConstant(key);
  }
  
  return result as Record<ConstKey, any>;
};

export { CONST_KEYS, CONST_KEYS_ARRAY };
