const axios = require('axios');
const fs = require('fs');
const path = require('path');
const os = require('os');

const DEFAULT_TIMEOUT = 60000;

// ANSI 颜色代码
const COLORS = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
  bold: '\x1b[1m',
  dim: '\x1b[2m'
};

const logger = {
  success: (msg) => console.log(`${COLORS.green}[✓] ${msg}${COLORS.reset}`),
  error: (msg) => console.error(`${COLORS.red}${COLORS.bold}[✗] ${msg}${COLORS.reset}`),
  warn: (msg) => console.warn(`${COLORS.yellow}[!] ${msg}${COLORS.reset}`),
  info: (msg) => console.log(`${COLORS.blue}[i] ${msg}${COLORS.reset}`),
  important: (msg) => console.log(`${COLORS.cyan}${COLORS.bold}▶ ${msg}${COLORS.reset}`),
  debug: (msg) => {
    if (process.env.DEBUG) {
      console.log(`${COLORS.dim}[DEBUG] ${msg}${COLORS.reset}`);
    }
  }
};

function parseArgs() {
  const args = process.argv.slice(2);
  const result = { st: '', et: '', keyword: '' };
  for (let i = 0; i < args.length; i++) {
    if (args[i] === '--st' && i + 1 < args.length) {
      result.st = args[++i];
    } else if (args[i] === '--et' && i + 1 < args.length) {
      result.et = args[++i];
    } else if (args[i] === '--keyword' && i + 1 < args.length) {
      result.keyword = args[++i];
    }
  }
  return result;
}

function parseTime(timeStr, defaultTime) {
  let datePart = timeStr;
  let timePart = defaultTime;

  if (timeStr.includes(' ')) {
    const parts = timeStr.split(' ');
    datePart = parts[0];
    timePart = parts[1];
  }

  return new Date(`${datePart} ${timePart}`).getTime();
}

function getAuthorizationFromCache() {
  try {
    const CACHE_DIR = path.join(os.homedir(), '.mid-cli');
    const CACHE_FILE = path.join(CACHE_DIR, 'auth-cache.json');
    if (fs.existsSync(CACHE_FILE)) {
      const cacheData = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
      return cacheData.authorization || '';
    }
  } catch (error) {
    logger.debug(`读取授权缓存失败: ${error.message}`);
  }
  return '';
}

function getIndexName(pid) {
  if (pid.includes('.rf.')) {
    return 'sms-ns-rf';
  }
  return 'sms-ns-api';
}

function isSameDay(beginTime, endTime) {
  const begin = new Date(beginTime);
  const end = new Date(endTime);
  return begin.getFullYear() === end.getFullYear() &&
    begin.getMonth() === end.getMonth() &&
    begin.getDate() === end.getDate();
}

async function main() {
  const cliArgs = parseArgs();

  const today = new Date();
  const todayStr = today.toISOString().slice(0, 10);

  if (!cliArgs.st) {
    cliArgs.st = todayStr;
  }
  if (!cliArgs.et) {
    cliArgs.et = todayStr;
  }

  const beginTime = parseTime(cliArgs.st, '00:00:00');
  const endTime = parseTime(cliArgs.et, '23:59:59');

  if (beginTime >= endTime) {
    logger.error('开始时间必须小于结束时间');
    process.exit(1);
  }

  if (!isSameDay(beginTime, endTime)) {
    logger.error('日志最多下载一天，不能跨天');
    process.exit(1);
  }

  const packageJsonPath = path.join(__dirname, '../../package.json');
  let packageJson;
  try {
    packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
  } catch (error) {
    logger.error(`读取 package.json 失败: ${error.message}`);
    process.exit(1);
  }

  const pid = packageJson.name;
  if (!pid) {
    logger.error('无法获取项目名称 (package.json.name)');
    process.exit(1);
  }

  const authorization = getAuthorizationFromCache();
  if (!authorization) {
    logger.error('未检测到授权信息，请先通过 mid-cli clone/init 命令配置授权');
    process.exit(1);
  }

  const indexName = getIndexName(pid);

  logger.important('开始下载中台云端日志');
  logger.info(`项目: ${pid}`);
  logger.info(`索引: ${indexName}`);
  logger.info(`时间: ${new Date(beginTime).toLocaleString()} ~ ${new Date(endTime).toLocaleString()}`);
  if (cliArgs.keyword) {
    logger.info(`关键字: ${cliArgs.keyword}`);
  }

  const baseUrl = 'https://me.keytop.cn/logs/service/logSearch/v2/meLog/export';
  const params = {
    podId: '',
    message: cliArgs.keyword || '',
    errorLog: false,
    indexName,
    deploymentId: '',
    pid,
    beginTime,
    endTime,
    envCode: 'PROD'
  };

  try {
    const response = await axios.get(baseUrl, {
      params,
      headers: { authorization },
      responseType: 'stream',
      timeout: DEFAULT_TIMEOUT
    });

    const contentDisposition = response.headers['content-disposition'] || '';
    let filename = `${pid}_PROD_${new Date(beginTime).toISOString().slice(0, 10).replace(/-/g, '')}.log`;
    if (contentDisposition.includes('filename=')) {
      const match = contentDisposition.match(/filename=(.+)/);
      if (match) {
        filename = match[1].trim();
      }
    }

    const logsDir = path.join(__dirname, '../../logs');
    if (!fs.existsSync(logsDir)) {
      fs.mkdirSync(logsDir, { recursive: true });
    }

    const filePath = path.join(logsDir, filename);
    const writer = fs.createWriteStream(filePath);

    response.data.pipe(writer);

    await new Promise((resolve, reject) => {
      writer.on('finish', resolve);
      writer.on('error', reject);
    });

    logger.success(`日志下载成功: ${filePath}`);
  } catch (error) {
    logger.error(`日志下载失败: ${error.message}`);
    process.exit(1);
  }
}

main();