require('dotenv').config();
const express = require('express');
const cookieParser = require('cookie-parser');

// Infrastructure
const databaseConnection = require('../infrastructure/db/DatabaseConnection');
const UserRepository = require('../infrastructure/repositories/UserRepository');

// Application Services
const Container = require('../application/services/Container');
const EmailService = require('../application/services/EmailService');
const JwtService = require('../application/services/JwtService');

// Command Handlers
const RegisterUserCommandHandler = require('../application/auth/commands/RegisterUserCommandHandler');
const LoginUserCommandHandler = require('../application/auth/commands/LoginUserCommandHandler');
const UpdateUserProfileCommandHandler = require('../application/user/commands/UpdateUserProfileCommandHandler');

// Query Handlers
const GetMeQueryHandler = require('../application/user/queries/GetMeQueryHandler');
const GetAllUsersQueryHandler = require('../application/user/queries/GetAllUsersQueryHandler');
const GetUserByIdQueryHandler = require('../application/user/queries/GetUserByIdQueryHandler');

// Controllers
const AuthController = require('./controllers/AuthController');
const UserController = require('./controllers/UserController');

// Middlewares
const corsMiddleware = require('./middlewares/corsMiddleware');
const scopeMiddleware = require('./middlewares/scopeMiddleware');

// Routes
const createAuthRoutes = require('./routers/authRoutes');
const createUserRoutes = require('./routers/userRoutes');

const app = express();
const container = new Container();

/**
 * Dependency Injection Setup (CQRS Pattern)
 */
function setupDependencies() {
  // Database Connection (singleton)
  container.register('DatabaseConnection', () => databaseConnection, 'singleton');

  // PrismaClient (singleton)
  container.register('PrismaClient', () => {
    return databaseConnection.getClient();
  }, 'singleton');

  // UserRepository (singleton)
  container.register('UserRepository', () => {
    return new UserRepository(container.resolve('PrismaClient'));
  }, 'singleton');

  // EmailService (singleton) - A DIÁKOK IMPLEMENTÁLJÁK!
  container.register('EmailService', () => new EmailService(), 'singleton');

  // JwtService (singleton)
  container.register('JwtService', () => new JwtService(), 'singleton');

  // === Command Handlers ===
  
  // RegisterUserCommandHandler (singleton)
  container.register('RegisterUserCommandHandler', () => {
    return new RegisterUserCommandHandler(
      container.resolve('PrismaClient'),
      container.resolve('EmailService')
    );
  }, 'singleton');

  // LoginUserCommandHandler (singleton)
  container.register('LoginUserCommandHandler', () => {
    return new LoginUserCommandHandler(container.resolve('PrismaClient'));
  }, 'singleton');

  // UpdateUserProfileCommandHandler (singleton)
  container.register('UpdateUserProfileCommandHandler', () => {
    return new UpdateUserProfileCommandHandler(container.resolve('PrismaClient'));
  }, 'singleton');

  // === Query Handlers ===

  // GetMeQueryHandler (singleton)
  container.register('GetMeQueryHandler', () => {
    return new GetMeQueryHandler(container.resolve('PrismaClient'));
  }, 'singleton');

  // GetAllUsersQueryHandler (singleton)
  container.register('GetAllUsersQueryHandler', () => {
    return new GetAllUsersQueryHandler(container.resolve('PrismaClient'));
  }, 'singleton');

  // GetUserByIdQueryHandler (singleton)
  container.register('GetUserByIdQueryHandler', () => {
    return new GetUserByIdQueryHandler(container.resolve('PrismaClient'));
  }, 'singleton');

  // === Controllers ===

  // AuthController (singleton)
  container.register('AuthController', () => {
    return new AuthController(
      container.resolve('RegisterUserCommandHandler'),
      container.resolve('LoginUserCommandHandler'),
      container.resolve('JwtService')
    );
  }, 'singleton');

  // UserController (singleton)
  container.register('UserController', () => {
    return new UserController(
      container.resolve('GetMeQueryHandler'),
      container.resolve('GetAllUsersQueryHandler'),
      container.resolve('GetUserByIdQueryHandler'),
      container.resolve('UpdateUserProfileCommandHandler')
    );
  }, 'singleton');

  console.log('✅ DI Container configured (CQRS pattern)');
}

/**
 * Express Middleware Chain
 */
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

// TODO (DIÁKOK): Alkalmazd a CORS middleware-t
// Tipp: app.use(corsMiddleware);

// TODO (DIÁKOK): Alkalmazd a Scope middleware-t (opcionális)
// Tipp: app.use(scopeMiddleware(container));

/**
 * Routes
 */
app.use('/api/auth', createAuthRoutes(container));
app.use('/api/users', createUserRoutes(container));

/**
 * Health Check Endpoint
 */
app.get('/health', (req, res) => {
  res.status(200).json({ 
    status: 'OK', 
    message: 'Server is running',
    timestamp: new Date().toISOString()
  });
});

/**
 * Error Handling Middleware
 */
app.use((err, req, res, next) => {
  console.error('❌ Error:', err.message);
  res.status(err.status || 500).json({ 
    error: err.message || 'Internal Server Error' 
  });
});

/**
 * 404 Handler
 */
app.use((req, res) => {
  res.status(404).json({ error: 'Route not found' });
});

/**
 * Server Startup
 */
const PORT = process.env.PORT || 3000;

async function startServer() {
  try {
    // Database connection
    await databaseConnection.connect();

    // DI Container inicializálása
    setupDependencies();

    // Server indítása
    app.listen(PORT, () => {
      console.log('🚀 Server running on http://localhost:' + PORT);
      console.log('📧 Email Service configured (implement EmailService!)');
      console.log('🔐 JWT Authentication enabled (cookie-based)');
      console.log('🍪 Cookies: httpOnly, secure (production), sameSite=strict');
      console.log('');
      console.log('📍 Endpoints:');
      console.log('   POST   /api/auth/register');
      console.log('   POST   /api/auth/login');
      console.log('   POST   /api/auth/logout');
      console.log('   GET    /api/users/me (protected)');
      console.log('   PUT    /api/users/me (protected)');
      console.log('   GET    /api/users (protected)');
      console.log('   GET    /api/users/:id (protected)');
    });
  } catch (error) {
    console.error('❌ Failed to start server:', error);
    await databaseConnection.disconnect();
    process.exit(1);
  }
}

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

startServer();

module.exports = app;
