import express from 'express';
import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';

// Config
dotenv.config();

// Database
import databaseClient from './infrastructure/database/prisma.js';
import redisClient from './infrastructure/database/redis.js';

// Repositories
import { UserRepository } from './infrastructure/repositories/UserRepository.js';
import { BlogRepository } from './infrastructure/repositories/BlogRepository.js';

// Handlers
import { CreateBlogHandler } from './application/handlers/CreateBlogHandler.js';
import { UpdateBlogHandler } from './application/handlers/UpdateBlogHandler.js';
import { DeleteBlogHandler } from './application/handlers/DeleteBlogHandler.js';
import { BlogQueryHandler } from './application/handlers/BlogQueryHandler.js';

// Controllers
import { BlogController } from './api/controllers/BlogController.js';
import { AuthController } from './api/controllers/AuthController.js';

// Routes
import { createBlogRoutes } from './api/routes/blogRoutes.js';
import { createAuthRoutes } from './api/routes/authRoutes.js';
import { createUserRoutes } from './api/routes/userRoutes.js';

// Middlewares
import { errorHandler, notFoundHandler } from './api/middlewares/errorHandler.js';

const app = express();
const PORT = process.env.PORT || 3000;

// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(process.env.COOKIE_SECRET));

// Dependency Injection - Repository létrehozás
const userRepository = new UserRepository();
const blogRepository = new BlogRepository();

// Repository-k injektálása app.locals-ba (middleware-ek számára)
app.locals.userRepository = userRepository;
app.locals.blogRepository = blogRepository;

// Dependency Injection - Handler létrehozás
const createBlogHandler = new CreateBlogHandler(blogRepository);
const updateBlogHandler = new UpdateBlogHandler(blogRepository);
const deleteBlogHandler = new DeleteBlogHandler(blogRepository);
const blogQueryHandler = new BlogQueryHandler(blogRepository);

// Dependency Injection - Controller létrehozás
const blogController = new BlogController(
  createBlogHandler,
  updateBlogHandler,
  deleteBlogHandler,
  blogQueryHandler
);

const authController = new AuthController(userRepository);

// Health check
app.get('/health', (req, res) => {
  res.json({
    status: 'OK',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV
  });
});

// Routes
app.use('/api/auth', createAuthRoutes(authController));
app.use('/api/blogs', createBlogRoutes(blogController));
app.use('/api/users', createUserRoutes(blogController));

// Error handling
app.use(notFoundHandler);
app.use(errorHandler);

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('\n🛑 Shutting down gracefully...');
  await databaseClient.disconnect();
  await redisClient.disconnect();
  process.exit(0);
});

process.on('SIGTERM', async () => {
  console.log('\n🛑 Shutting down gracefully...');
  await databaseClient.disconnect();
  await redisClient.disconnect();
  process.exit(0);
});

// Start server
app.listen(PORT, () => {
  console.log(`🚀 Server running on port ${PORT}`);
  console.log(`📝 Environment: ${process.env.NODE_ENV}`);
  console.log(`🔗 API: http://localhost:${PORT}/api`);
  console.log(`💚 Health: http://localhost:${PORT}/health`);
});

export default app;
