require('dotenv').config();
const express = require('express');
const cors = require('cors');
const path = require('path');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const app = express();

// ✅ Health check (맨 처음에 등록 - 모든 미들웨어보다 우선)
app.get('/api/health', (req, res) => {
  console.log('🟢 Health check 호출됨!');
  res.status(200).json({ 
    status: 'healthy',
    service: 'Hyungi API',
    timestamp: new Date().toISOString()
  });
});

// ✅ 보안 헤더 설정 (Helmet)
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
      scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
      imgSrc: ["'self'", "data:", "https:", "blob:"],
      fontSrc: ["'self'", "https://fonts.gstatic.com"],
      connectSrc: ["'self'", "https://api.technicalkorea.com"],
    },
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  }
}));

// ✅ 요청 바디 용량 제한 확장
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
app.use(express.json({ limit: '50mb' }));

//개발용 
app.use(cors({
  origin: true,  // 모든 origin 허용 (개발용)
  credentials: true
}));

// ✅ CORS 설정: 허용 origin 명시 (수정된 버전)
//app.use(cors({
//  origin: function (origin, callback) {
//    const allowedOrigins = process.env.ALLOWED_ORIGINS 
//      ? process.env.ALLOWED_ORIGINS.split(',')
//      : [
//          'http://localhost:3000',
//          'http://localhost:3005',
//          'http://web-ui',
//          'http://web-ui:80',
//          'http://web-ui:3001',         // 실제 내부 포트
//          'http://172.18.0.1',
//          'http://172.18.0.1:3001',
//          'http://172.18.0.2',          // web-ui 컨테이너 IP
//          'http://172.18.0.2:3001',     // web-ui 컨테이너 IP:포트
//          'http://192.168.0.3',         // 나스 외부 IP (포트 없음)
//          'http://192.168.0.3:80',      // 나스 외부 접근
//          'http://192.168.0.3:3001',    // 나스 외부 접근 (실제 포트)
//          'http://192.168.0.3:5000',    // 시놀로지 기본 포트
//          'http://192.168.0.3:5001',    // 시놀로지 HTTPS 포트
//          // 추가: 더 유연한 허용
//          'http://192.168.0.3:3000',    // 다른 포트들도 허용
//          'http://192.168.0.3:8080',
//          'http://192.168.0.3:8000'
//        ];
//    
//    // 개발 환경에서는 모든 로컬 IP 허용
//    if (process.env.NODE_ENV === 'development' || !origin) {
//      return callback(null, true);
//    }
//    
//    // 192.168.x.x 대역 자동 허용 (시놀로지 환경)
//    if (origin && origin.match(/^http:\/\/192\.168\.\d+\.\d+(:\d+)?$/)) {
//      console.log('✅ 로컬 네트워크 IP 자동 허용:', origin);
//      return callback(null, true);
//    }
//    
//    if (allowedOrigins.includes(origin)) {
//      callback(null, true);
//    } else {
//      console.error('❌ CORS 차단됨:', origin);
//      console.log('허용된 Origins:', allowedOrigins);
//      callback(new Error('CORS 차단됨: ' + origin));
//    }
//  },
//  credentials: true
// }));

// ✅ 신뢰할 수 있는 프록시 설정 (IP 주소 정확히 가져오기)
app.set('trust proxy', 1);

// ✅ API 속도 제한 설정
// 일반 API 속도 제한
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15분
  max: process.env.RATE_LIMIT_MAX_REQUESTS || 100,
  message: 'API 요청 한도를 초과했습니다. 잠시 후 다시 시도하세요.',
  standardHeaders: true,
  legacyHeaders: false,
});

// 로그인 API 속도 제한 (더 엄격하게)
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15분
  max: process.env.LOGIN_RATE_LIMIT_MAX_REQUESTS || 5,
  message: '너무 많은 로그인 시도입니다. 15분 후에 다시 시도하세요.',
  standardHeaders: true,
  legacyHeaders: false,
  skipSuccessfulRequests: true, // 성공한 요청은 카운트하지 않음
});

// ✅ 라우터 등록
const authRoutes = require('./routes/authRoutes');
const projectRoutes = require('./routes/projectRoutes');
const workerRoutes = require('./routes/workerRoutes');
const taskRoutes = require('./routes/taskRoutes');
const processRoutes = require('./routes/processRoutes');
const workReportRoutes = require('./routes/workReportRoutes');
const cuttingPlanRoutes = require('./routes/cuttingPlanRoutes');
const factoryInfoRoutes = require('./routes/factoryInfoRoutes');
const equipmentListRoutes = require('./routes/equipmentListRoutes');
const toolsRoute = require('./routes/toolsRoute');
const uploadRoutes = require('./routes/uploadRoutes');
const uploadBgRoutes = require('./routes/uploadBgRoutes');
const dailyIssueReportRoutes = require('./routes/dailyIssueReportRoutes');
const issueTypeRoutes = require('./routes/issueTypeRoutes');
const healthRoutes = require('./routes/healthRoutes');
const pipeSpecRoutes = require('./routes/pipeSpecRoutes');
const dailyWorkReportRoutes = require('./routes/dailyWorkReportRoutes');
const workAnalysisRoutes = require('./routes/workAnalysisRoutes');

// 🔒 인증 미들웨어 가져오기
const { verifyToken } = require('./middlewares/authMiddleware');

// ahn.hyungi.net 배포용
app.use(express.static(path.join(__dirname, 'public')));

// ✅ 업로드된 파일 정적 라우팅 추가 (웹에서 이미지 접근 가능하게)
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// 🔒 활동 로깅 미들웨어
const activityLogger = (req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = Date.now() - start;
    const logData = {
      timestamp: new Date().toISOString(),
      method: req.method,
      url: req.originalUrl,
      status: res.statusCode,
      duration: duration + 'ms',
      ip: req.ip,
      user: req.user?.username || 'anonymous'
    };
    
    // 성공/실패에 따른 로그 레벨 분기
    if (res.statusCode >= 400) {
      console.error('[API Error]', logData);
    } else if (res.statusCode >= 300) {
      console.warn('[API Redirect]', logData);
    } else {
      console.log('[API Access]', logData);
    }
  });
  
  next();
};

// ===== 📋 미들웨어 적용 순서 수정 (🔥 핵심 수정 부분) =====

// 모든 API 요청에 활동 로거 적용
app.use('/api/*', activityLogger);

// 🔓 인증이 필요 없는 경로들을 먼저 등록 (순서 중요!)

// Health check는 이미 맨 위에서 등록됨

// 🔓 로그인 관련 경로들 (인증 없이 접근 가능)
// 로그인 엔드포인트에 특별한 속도 제한 적용
app.post('/api/auth/login', loginLimiter, (req, res, next) => {
  console.log('🔓 로그인 요청 받음:', req.body.username);
  authRoutes.handle(req, res, next);
});

// 기타 공개 인증 엔드포인트들
app.use('/api/auth/refresh-token', loginLimiter);
app.use('/api/auth/check-password-strength', loginLimiter);

// 나머지 인증 라우트
app.use('/api/auth', authRoutes);

// 🔒 일반 API 속도 제한 적용
app.use('/api/', apiLimiter);

// 🔒 인증이 필요한 모든 API에 대해 토큰 검증 (수정된 버전)
app.use('/api/*', (req, res, next) => {
  console.log(`🔍 API 요청: ${req.method} ${req.originalUrl}`);
  
  // 🔓 인증이 필요 없는 경로들은 통과 (정확한 매칭)
  const publicPaths = [
    '/api/auth/login',
    '/api/auth/refresh-token',
    '/api/auth/check-password-strength',
    '/api/health'
  ];
  
  // 정확한 경로 매칭 확인
  const isPublicPath = publicPaths.some(path => {
    // 정확한 경로 또는 쿼리 파라미터가 있는 경우
    const isMatch = req.originalUrl === path || 
                   req.originalUrl.startsWith(path + '?') ||
                   req.originalUrl.startsWith(path + '/');
    if (isMatch) {
      console.log(`🔓 Public path 허용: ${req.originalUrl}`);
    }
    return isMatch;
  });
  
  if (isPublicPath) {
    return next();
  }
  
  // 나머지는 모두 인증 필요
  console.log(`🔒 인증 필요한 경로: ${req.originalUrl}`);
  verifyToken(req, res, next);
});

// ===== 📊 모든 라우트 등록 (인증된 사용자만) =====

// 📝 일반 기능들
app.use('/api/issue-reports', dailyIssueReportRoutes);
app.use('/api/issue-types', issueTypeRoutes);

// 👥 기본 데이터들 (모든 인증된 사용자)
app.use('/api/workers', workerRoutes);
app.use('/api/daily-work-reports', dailyWorkReportRoutes);
app.use('/api/work-analysis', workAnalysisRoutes);

// 📊 리포트 및 분석
app.use('/api/workreports', workReportRoutes);
app.use('/api/uploads', uploadRoutes);

// ⚙️ 시스템 데이터들 (모든 인증된 사용자)
app.use('/api/projects', projectRoutes);
app.use('/api/tasks', taskRoutes);
app.use('/api/processes', processRoutes);
app.use('/api/cuttingplans', cuttingPlanRoutes);
app.use('/api/factoryinfo', factoryInfoRoutes);
app.use('/api/equipment', equipmentListRoutes);
app.use('/api/tools', toolsRoute);
app.use('/api/pipespecs', pipeSpecRoutes);

// 📤 파일 업로드
app.use('/api', uploadBgRoutes);


// ===== 🔍 API 정보 엔드포인트 =====
app.get('/api', (req, res) => {
  res.json({
    name: 'Technical Korea Work Management API',
    version: '2.1.0',
    description: '보안이 강화된 생산관리 시스템 API',
    timestamp: new Date().toISOString(),
    security: {
      authentication: 'JWT Bearer Token',
      rateLimit: {
        general: '100 requests per 15 minutes',
        login: '5 attempts per 15 minutes'
      },
      cors: 'Configured for specific origins',
      headers: 'Security headers enabled (Helmet)'
    },
    user: {
      username: req.user?.username || 'anonymous',
      access_level: req.user?.access_level || 'none',
      worker_id: req.user?.worker_id || null
    },
    endpoints: {
      auth: {
        login: 'POST /api/auth/login',
        logout: 'POST /api/auth/logout',
        refreshToken: 'POST /api/auth/refresh-token',
        changePassword: 'POST /api/auth/change-password',
        adminChangePassword: 'POST /api/auth/admin/change-password',
        checkPasswordStrength: 'POST /api/auth/check-password-strength',
        me: 'GET /api/auth/me',
        users: 'GET /api/auth/users',
        register: 'POST /api/auth/register',
        updateUser: 'PUT /api/auth/users/:id',
        deleteUser: 'DELETE /api/auth/users/:id',
        loginHistory: 'GET /api/auth/login-history'
      },
      dailyWorkReports: {
        workTypes: 'GET /api/daily-work-reports/work-types',
        workStatusTypes: 'GET /api/daily-work-reports/work-status-types', 
        errorTypes: 'GET /api/daily-work-reports/error-types',
        create: 'POST /api/daily-work-reports',
        search: 'GET /api/daily-work-reports/search',
        summary: 'GET /api/daily-work-reports/summary',
        byDate: 'GET /api/daily-work-reports/date/:date',
        update: 'PUT /api/daily-work-reports/:id',
        delete: 'DELETE /api/daily-work-reports/:id'
      },
      workAnalysis: {
       stats: 'GET /api/work-analysis/stats?start=YYYY-MM-DD&end=YYYY-MM-DD',
       dailyTrend: 'GET /api/work-analysis/daily-trend?start=YYYY-MM-DD&end=YYYY-MM-DD',
       workerStats: 'GET /api/work-analysis/worker-stats?start=YYYY-MM-DD&end=YYYY-MM-DD',
       projectStats: 'GET /api/work-analysis/project-stats?start=YYYY-MM-DD&end=YYYY-MM-DD',
       workTypeStats: 'GET /api/work-analysis/work-type-stats?start=YYYY-MM-DD&end=YYYY-MM-DD',
       recentWork: 'GET /api/work-analysis/recent-work?start=YYYY-MM-DD&end=YYYY-MM-DD&limit=10',
       weekdayPattern: 'GET /api/work-analysis/weekday-pattern?start=YYYY-MM-DD&end=YYYY-MM-DD',
       errorAnalysis: 'GET /api/work-analysis/error-analysis?start=YYYY-MM-DD&end=YYYY-MM-DD',
       monthlyComparison: 'GET /api/work-analysis/monthly-comparison?year=YYYY',
       workerSpecialization: 'GET /api/work-analysis/worker-specialization?start=YYYY-MM-DD&end=YYYY-MM-DD',
       dashboard: 'GET /api/work-analysis/dashboard?start=YYYY-MM-DD&end=YYYY-MM-DD',
       health: 'GET /api/work-analysis/health'
      },
      workers: 'GET/POST/PUT/DELETE /api/workers',
      projects: 'GET/POST/PUT/DELETE /api/projects',
      issues: 'GET/POST/PUT/DELETE /api/issue-reports',
      reports: 'GET /api/workreports',
      uploads: 'POST /api/uploads'
    },
    note: '모든 API는 로그인 후 접근 가능합니다. 자세한 API 문서는 관리자에게 문의하세요.'
  });
});

// ===== 🏠 메인 페이지 라우트 =====
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// ✅ 서버 실행
const PORT = process.env.PORT || 3005;
const server = app.listen(PORT, () => {
  console.log(`
🚀 Technical Korea Work Management System v2.1.0
📍 서버가 포트 ${PORT}에서 실행 중입니다.
🌐 접속 URL: http://localhost:${PORT}
📊 API 문서: http://localhost:${PORT}/api

🔒 보안 기능:
   ✅ JWT 토큰 인증
   ✅ 로그인 실패 제한 (5회)
   ✅ API 속도 제한
   ✅ 보안 헤더 (Helmet)
   ✅ CORS 설정 (192.168.0.3:3001 허용)
   ✅ 활동 로깅

📋 새로운 기능:
   🔐 비밀번호 변경 (본인/관리자)
   🔄 토큰 갱신 (Refresh Token)
   📊 로그인 이력 조회
   💪 비밀번호 강도 체크
  `);
}).on('error', (err) => {
  console.error('❌ 서버 실행 중 오류 발생:', err);
  if (err.code === 'EADDRINUSE') {
    console.error(`포트 ${PORT}이(가) 이미 사용 중입니다.`);
  }
});

// ===== 🚨 에러 핸들링 =====

// 404 핸들러
app.use((req, res) => {
  console.log(`[404] ${req.method} ${req.originalUrl} - IP: ${req.ip}`);
  
  if (req.originalUrl.startsWith('/api/')) {
    res.status(404).json({ 
      error: 'API 엔드포인트를 찾을 수 없습니다.',
      path: req.originalUrl,
      available: '/api',
      timestamp: new Date().toISOString()
    });
  } else {
    res.status(404).json({ 
      error: '요청하신 페이지를 찾을 수 없습니다.',
      timestamp: new Date().toISOString()
    });
  }
});

// 전역 에러 핸들러  
app.use((err, req, res, next) => {
  const errorId = Date.now().toString(36);
  
  console.error(`[ERROR ${errorId}] ${new Date().toISOString()}:`, {
    message: err.message,
    stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
    url: req.originalUrl,
    method: req.method,
    ip: req.ip,
    user: req.user?.username || 'anonymous'
  });

  // CORS 에러
//  if (err.message && err.message.includes('CORS 차단됨')) {
//    return res.status(403).json({ 
//      error: 'CORS 정책에 의해 차단되었습니다.',
//      message: 'API 접근이 허용되지 않은 도메인입니다.',
//      errorId
//    });
//  }

  // JWT 에러
  if (err.name === 'JsonWebTokenError') {
    return res.status(401).json({ 
      error: '유효하지 않은 토큰입니다.',
      errorId
    });
  }

  if (err.name === 'TokenExpiredError') {
    return res.status(401).json({ 
      error: '토큰이 만료되었습니다. 다시 로그인해주세요.',
      errorId
    });
  }

  // 요청 크기 초과
  if (err.type === 'entity.too.large') {
    return res.status(413).json({ 
      error: '요청 크기가 너무 큽니다. 50MB 이하로 줄여주세요.',
      errorId
    });
  }

  // 일반 서버 에러
  res.status(err.status || 500).json({ 
    error: '서버 오류가 발생했습니다.',
    message: process.env.NODE_ENV === 'development' ? err.message : '관리자에게 문의하세요.',
    errorId,
    timestamp: new Date().toISOString()
  });
});

// ===== 🔄 Graceful Shutdown =====
const gracefulShutdown = () => {
  console.log('\n🛑 서버 종료 신호를 받았습니다...');
  
  server.close(() => {
    console.log('✅ HTTP 서버가 정상적으로 종료되었습니다.');
    
    // DB 연결 종료 등 추가 정리 작업
    // 예: db.end(), redis.quit() 등
    
    process.exit(0);
  });
  
  // 30초 후 강제 종료
  setTimeout(() => {
    console.error('❌ 정상 종료 실패, 강제 종료합니다.');
    process.exit(1);
  }, 30000);
};

process.on('SIGTERM', gracefulShutdown);
process.on('SIGINT', gracefulShutdown);

// 처리되지 않은 Promise 거부
process.on('unhandledRejection', (reason, promise) => {
  console.error('처리되지 않은 Promise 거부:', reason);
  // 개발 환경에서는 크래시, 프로덕션에서는 로그만
  if (process.env.NODE_ENV === 'development') {
    process.exit(1);
  }
});

// 처리되지 않은 예외
process.on('uncaughtException', (error) => {
  console.error('처리되지 않은 예외:', error);
  gracefulShutdown();
});

module.exports = app;