import loglevel from 'loglevel';
import { isShowLogger } from '@/config/env';

const categoryColors = {
  shopee: '#FF6B35',
  worker: '#4ECDC4',
  api: '#45B7D1',
  vue: '#96CEB4',
  content: '#FFEAA7',
};

const logIdStorage = new Map();
let logIdCounter = 0;

const generateLogId = () => {
  logIdCounter++;
  return `LOG-${Date.now()}-${logIdCounter}`;
};

const formatLogMessage = (prefix, logId, args) => {
  const timestamp = new Date().toISOString();
  const categoryColor = categoryColors[prefix] || '#999999';

  if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && !Array.isArray(args[0])) {
    const logData = args[0];
    const {
      msg, id, category, ...rest
    } = logData;

    const logIdToUse = id || logId || generateLogId();
    const categoryToUse = category || prefix;

    if (id) {
      logIdStorage.set(id, {
        category: categoryToUse,
        timestamp,
        data: logData,
      });
    }

    const prefixMsg = `%c[${categoryToUse}]%c [${logIdToUse}]`;
    const styleCategory = `color: ${categoryColor}; font-weight: bold;`;
    const styleId = 'color: #666; font-size: 0.9em;';

    return {
      prefixMsg,
      styles: [styleCategory, styleId],
      logData: {
        msg: msg || '',
        timestamp,
        category: categoryToUse,
        logId: logIdToUse,
        ...rest,
      },
      isObject: true,
    };
  }

  const logIdToUse = logId || generateLogId();
  const prefixMsg = `%c[${prefix}]%c [${logIdToUse}]`;
  const styleCategory = `color: ${categoryColor}; font-weight: bold;`;
  const styleId = 'color: #666; font-size: 0.9em;';

  return {
    prefixMsg,
    styles: [styleCategory, styleId],
    logData: args,
    isObject: false,
  };
};

const createLogger = (name, prefix) => {
  const logger = loglevel.getLogger(name);

  if (!isShowLogger) {
    logger.setLevel('silent');
  } else {
    logger.setLevel(1);
  }

  const originalFactory = logger.methodFactory;
  logger.methodFactory = (methodName, logLevel, loggerName) => {
    const rawMethod = originalFactory(methodName, logLevel, loggerName);

    return (...args) => {
      const {
        prefixMsg, styles, logData, isObject,
      } = formatLogMessage(prefix, null, args);

      if (isObject) {
        rawMethod(prefixMsg, ...styles, logData);
      } else {
        rawMethod(prefixMsg, ...styles, ...logData);
      }
    };
  };

  logger.setLevel(logger.getLevel());

  logger.withId = (logId) => {
    const childLogger = loglevel.getLogger(`${name}:${logId}`);
    childLogger.setLevel(logger.getLevel());

    childLogger.methodFactory = (methodName, logLevel, loggerName) => {
      const rawMethod = originalFactory(methodName, logLevel, loggerName);

      return (...args) => {
        const {
          prefixMsg, styles, logData, isObject,
        } = formatLogMessage(prefix, logId, args);

        if (isObject) {
          rawMethod(prefixMsg, ...styles, logData);
        } else {
          rawMethod(prefixMsg, ...styles, ...logData);
        }
      };
    };

    childLogger.setLevel(childLogger.getLevel());
    return childLogger;
  };

  logger.getLogById = (logId) => {
    return logIdStorage.get(logId);
  };

  logger.filterByCategory = (category) => {
    const filtered = [];
    logIdStorage.forEach((value, key) => {
      if (value.category === category) {
        filtered.push({ logId: key, ...value });
      }
    });
    return filtered;
  };

  logger.getAllLogs = () => {
    const logs = [];
    logIdStorage.forEach((value, key) => {
      logs.push({ logId: key, ...value });
    });
    return logs;
  };

  logger.clearLogs = () => {
    logIdStorage.clear();
  };

  return logger;
};

export const loggerShopee = createLogger('shopee', 'shopee');
export const loggerTiktok = createLogger('tiktok', 'tiktok');
export const loggerLazada = createLogger('lazada', 'lazada');

export const loggerApi = createLogger('api', 'api');
export const loggerVue = createLogger('vue', 'vue');
export const loggerContent = createLogger('content', 'content');

export const loggerPlugin = createLogger('plugin', 'plugin');
export const loggerModel = createLogger('model', 'model');

export const loggerWorker = createLogger('worker', 'worker');
export const loggerBackground = createLogger('background', 'background');
