#!/usr/bin/env node

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');
const fs = require('fs');
const yargs = require('yargs');
const { hideBin } = require('yargs/helpers');
const chalk = require('chalk');

// 命令行参数配置
const argv = yargs(hideBin(process.argv))
  .option('port', {
    alias: 'p',
    type: 'number',
    default: 3001,
    description: '服务器端口号'
  })
  .option('host', {
    alias: 'h',
    type: 'string',
    default: 'localhost',
    description: '服务器主机地址'
  })
  .option('client-port', {
    type: 'number',
    default: 3000,
    description: '前端开发服务器端口'
  })
  .option('log-limit', {
    type: 'number',
    default: 10000,
    description: '最大保存日志数量'
  })
  .option('production', {
    type: 'boolean',
    default: false,
    description: '生产模式'
  })
  .option('help', {
    alias: 'H',
    type: 'boolean',
    description: '显示帮助信息'
  })
  .help()
  .argv;

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

const PORT = argv.port;
const HOST = argv.host;
const MAX_LOGS = argv.logLimit;
const IS_PRODUCTION = argv.production;

// 存储日志的内存数据库
let logs = [];

// 日志数据结构
// {
//   id: String,
//   level: String,
//   message: String,
//   timestamp: String,
//   appName: String,
//   userAgent: String,
//   url: String,
//   createdAt: Date
// }

// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 生产环境提供静态文件
if (IS_PRODUCTION) {
  const clientBuildPath = path.join(__dirname, '../client/build');
  if (fs.existsSync(clientBuildPath)) {
    app.use(express.static(clientBuildPath));
  }
} else {
  // 开发环境代理到React开发服务器
  const { createProxyMiddleware } = require('http-proxy-middleware');
  app.use('/sockjs-node', createProxyMiddleware({
    target: `http://localhost:${argv.clientPort}`,
    changeOrigin: true,
    ws: true
  }));
}

// 根路径 - 提供API信息和重定向
app.get('/', (req, res) => {
  if (IS_PRODUCTION) {
    // 生产环境显示前端应用
    const clientBuildPath = path.join(__dirname, '../client/build/index.html');
    if (fs.existsSync(clientBuildPath)) {
      return res.sendFile(clientBuildPath);
    }
  }
  
  // API信息页面
  res.json({
    name: 'Webhook Serverless',
    version: '1.0.0',
    description: '完整的日志管理系统',
    status: 'running',
    config: {
      port: PORT,
      host: HOST,
      maxLogs: MAX_LOGS,
      production: IS_PRODUCTION
    },
    endpoints: {
      'GET /': IS_PRODUCTION ? '前端界面' : 'API信息',
      'GET /health': '健康检查',
      'POST /log': '接收日志',
      'GET /logs': '获取日志列表',
      'GET /apps': '获取应用列表',
      'GET /stats': '获取统计信息',
      'DELETE /logs': '清空日志'
    },
    stats: {
      totalLogs: logs.length,
      appsCount: [...new Set(logs.map(log => log.appName))].length,
      uptime: process.uptime()
    },
    serverTime: new Date().toISOString()
  });
});

// 接收日志的API端点
app.get('/log', (req, res) => {
  try {
    const {
      level = 'log',
      message = '',
      timestamp,
      appName = 'unknown',
      userAgent = '',
      url = ''
    } = req.query;

    const logEntry = {
      id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
      level: level.toLowerCase(),
      message: message,
      timestamp: timestamp || new Date().toISOString(),
      appName: appName,
      userAgent: userAgent,
      url: url,
      createdAt: new Date()
    };

    // 添加到日志数组
    logs.unshift(logEntry);
    
    // 限制日志数量
    if (logs.length > MAX_LOGS) {
      logs = logs.slice(0, MAX_LOGS);
    }

    // 通过Socket.io实时广播新日志
    io.emit('new-log', logEntry);

    // 控制台输出日志
    const levelColors = {
      'log': chalk.blue,
      'info': chalk.green,
      'warn': chalk.yellow,
      'error': chalk.red,
      'debug': chalk.gray
    };
    
    const colorFn = levelColors[logEntry.level] || chalk.blue;
    console.log(colorFn(`[${logEntry.level.toUpperCase()}]`), chalk.cyan(`[${logEntry.appName}]`), logEntry.message);

    res.json({ success: true, logId: logEntry.id });
  } catch (error) {
    console.error('Error processing log:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST方式接收日志（支持JSON）
app.post('/log', (req, res) => {
  try {
    const logEntry = {
      id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
      level: (req.body.level || 'log').toLowerCase(),
      message: req.body.message || '',
      timestamp: req.body.timestamp || new Date().toISOString(),
      appName: req.body.appName || 'unknown',
      userAgent: req.body.userAgent || 'Unknown',
      url: req.body.url || 'Unknown',
      createdAt: new Date(),
      ...req.body
    };

    logs.unshift(logEntry);
    
    if (logs.length > MAX_LOGS) {
      logs = logs.slice(0, MAX_LOGS);
    }

    io.emit('new-log', logEntry);

    const levelColors = {
      'log': chalk.blue,
      'info': chalk.green,
      'warn': chalk.yellow,
      'error': chalk.red,
      'debug': chalk.gray
    };
    
    const colorFn = levelColors[logEntry.level] || chalk.blue;
    console.log(colorFn(`[${logEntry.level.toUpperCase()}]`), chalk.cyan(`[${logEntry.appName}]`), logEntry.message);

    res.json({ success: true, logId: logEntry.id });
  } catch (error) {
    console.error('Error processing POST log:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// 获取所有日志的API
app.get('/logs', (req, res) => {
  try {
    const { 
      level, 
      appName, 
      page = 1, 
      limit = 100,
      search 
    } = req.query;

    let filteredLogs = [...logs];

    // 按级别过滤
    if (level) {
      filteredLogs = filteredLogs.filter(log => log.level === level);
    }

    // 按应用名称过滤
    if (appName) {
      filteredLogs = filteredLogs.filter(log => log.appName === appName);
    }

    // 按搜索词过滤
    if (search) {
      const searchLower = search.toLowerCase();
      filteredLogs = filteredLogs.filter(log => 
        log.message.toLowerCase().includes(searchLower) ||
        log.appName.toLowerCase().includes(searchLower)
      );
    }

    // 分页
    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    const startIndex = (pageNum - 1) * limitNum;
    const endIndex = startIndex + limitNum;
    const paginatedLogs = filteredLogs.slice(startIndex, endIndex);

    res.json({
      logs: paginatedLogs,
      total: filteredLogs.length,
      page: pageNum,
      limit: limitNum,
      totalPages: Math.ceil(filteredLogs.length / limitNum)
    });
  } catch (error) {
    console.error('Error fetching logs:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// 获取应用列表
app.get('/apps', (req, res) => {
  try {
    const appNames = [...new Set(logs.map(log => log.appName))];
    res.json({ 
      apps: appNames,
      total: appNames.length
    });
  } catch (error) {
    console.error('Error fetching apps:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// 获取日志统计信息
app.get('/stats', (req, res) => {
  try {
    const stats = {
      total: logs.length,
      byLevel: {},
      byApp: {},
      recent: logs.slice(0, 10),
      uptime: process.uptime(),
      memoryUsage: process.memoryUsage(),
      serverTime: new Date().toISOString()
    };

    logs.forEach(log => {
      stats.byLevel[log.level] = (stats.byLevel[log.level] || 0) + 1;
      stats.byApp[log.appName] = (stats.byApp[log.appName] || 0) + 1;
    });

    res.json(stats);
  } catch (error) {
    console.error('Error fetching stats:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// 清除所有日志
app.delete('/logs', (req, res) => {
  try {
    logs = [];
    io.emit('logs-cleared');
    res.json({ success: true, message: 'All logs cleared' });
  } catch (error) {
    console.error('Error clearing logs:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// Socket.io 连接处理
io.on('connection', (socket) => {
  console.log(chalk.green('Client connected:'), socket.id);
  
  socket.on('disconnect', () => {
    console.log(chalk.yellow('Client disconnected:'), socket.id);
  });
});

// 健康检查端点
app.get('/health', (req, res) => {
  res.json({ 
    status: 'OK', 
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    logsCount: logs.length,
    version: '1.0.0',
    config: {
      port: PORT,
      host: HOST,
      maxLogs: MAX_LOGS,
      production: IS_PRODUCTION
    }
  });
});

// 404 处理
app.use('*', (req, res) => {
  res.status(404).json({ 
    error: 'Not found',
    path: req.originalUrl,
    method: req.method,
    timestamp: new Date().toISOString()
  });
});

// 错误处理中间件
app.use((error, req, res, next) => {
  console.error(chalk.red('Server error:'), error);
  res.status(500).json({ 
    error: 'Internal server error',
    message: error.message,
    timestamp: new Date().toISOString()
  });
});

// 启动服务器
server.listen(PORT, HOST, () => {
  console.log();
  console.log(chalk.cyan('🚀 Webhook Serverless 启动成功!'));
  console.log(chalk.blue('━'.repeat(50)));
  console.log(chalk.yellow('📊 服务器地址:'), `http://${HOST}:${PORT}`);
  console.log(chalk.yellow('📝 日志接收端点:'), `http://${HOST}:${PORT}/log`);
  console.log(chalk.yellow('🌐 WebSocket连接:'), '已启用');
  console.log(chalk.yellow('📈 最大日志数量:'), MAX_LOGS);
  console.log(chalk.yellow('🔧 运行模式:'), IS_PRODUCTION ? chalk.red('生产模式') : chalk.green('开发模式'));
  console.log(chalk.blue('━'.repeat(50)));
  console.log(chalk.green('💡 使用 webhook-server --help 查看命令行选项'));
  console.log(chalk.cyan('📖 API文档:'), `http://${HOST}:${PORT}/`);
  console.log();
});

// 优雅关闭
process.on('SIGINT', () => {
  console.log(chalk.yellow('\n收到关闭信号，正在关闭服务器...'));
  server.close(() => {
    console.log(chalk.red('服务器已关闭'));
    process.exit(0);
  });
});

process.on('SIGTERM', () => {
  console.log(chalk.yellow('\n收到终止信号，正在关闭服务器...'));
  server.close(() => {
    console.log(chalk.red('服务器已关闭'));
    process.exit(0);
  });
});

module.exports = { app, server, io };