import express from 'express';
import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';
import { Container } from '../application/services/Container.js';
import DatabaseConnection from '../infrastructure/db/DatabaseConnection.js';
import { corsMiddleware } from './middlewares/corsMiddleware.js';
import { errorHandler } from './middlewares/errorHandler.js';
import { scopedMiddleware } from './middlewares/scopedMiddleware.js';
import { createAuthRoutes } from './routers/authRoutes.js';
import { createUserRoutes } from './routers/userRoutes.js';

// Services
import { JwtService } from '../application/services/JwtService.js';
import { EmailService } from '../application/services/EmailService.js';

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

// Auth Handlers
import { RegisterUserCommandHandler } from '../application/auth/commands/RegisterUserCommandHandler.js';
import { LoginUserCommandHandler } from '../application/auth/commands/LoginUserCommandHandler.js';

// User Handlers
import { GetMeQueryHandler } from '../application/user/queries/GetMeQueryHandler.js';
import { GetAllUsersQueryHandler } from '../application/user/queries/GetAllUsersQueryHandler.js';
import { GetUserByIdQueryHandler } from '../application/user/queries/GetUserByIdQueryHandler.js';
import { UpdateUserProfileCommandHandler } from '../application/user/commands/UpdateUserProfileCommandHandler.js';

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

dotenv.config();

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

// ===== DI Container Setup =====
const container = new Container();

// Register Singleton Services (shared across all requests)
container.registerSingleton('JwtService', () => new JwtService());
container.registerSingleton('EmailService', () => new EmailService());
container.registerSingleton('UserRepository', () => new UserRepository());

// Register Transient Handlers (new instance per resolve)
container.registerTransient('RegisterUserCommandHandler', (c) => 
  new RegisterUserCommandHandler(
    c.resolve('UserRepository'),
    c.resolve('JwtService'),
    c.resolve('EmailService')
  )
);

container.registerTransient('LoginUserCommandHandler', (c) =>
  new LoginUserCommandHandler(
    c.resolve('UserRepository'),
    c.resolve('JwtService')
  )
);

container.registerTransient('GetMeQueryHandler', (c) =>
  new GetMeQueryHandler(c.resolve('UserRepository'))
);

container.registerTransient('GetAllUsersQueryHandler', (c) =>
  new GetAllUsersQueryHandler(c.resolve('UserRepository'))
);

container.registerTransient('GetUserByIdQueryHandler', (c) =>
  new GetUserByIdQueryHandler(c.resolve('UserRepository'))
);

container.registerTransient('UpdateUserProfileCommandHandler', (c) =>
  new UpdateUserProfileCommandHandler(c.resolve('UserRepository'))
);

// Register Controllers
container.registerTransient('AuthController', (c) =>
  new AuthController(
    c.resolve('RegisterUserCommandHandler'),
    c.resolve('LoginUserCommandHandler')
  )
);

container.registerTransient('UserController', (c) =>
  new UserController(
    c.resolve('GetMeQueryHandler'),
    c.resolve('GetAllUsersQueryHandler'),
    c.resolve('GetUserByIdQueryHandler'),
    c.resolve('UpdateUserProfileCommandHandler')
  )
);

// ===== Middleware =====
app.use(corsMiddleware); // CORS with whitelist
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(scopedMiddleware(container)); // Request-scoped DI

// ===== Database Connection =====
await DatabaseConnection.connect();

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

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

// ===== Error Handling =====
app.use((req, res) => {
  res.status(404).json({
    success: false,
    error: 'Endpoint not found'
  });
});

app.use(errorHandler);

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

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

// ===== Start Server =====
app.listen(PORT, () => {
  console.log(`✅ Server running on http://localhost:${PORT}`);
  console.log(`📊 Environment: ${process.env.NODE_ENV}`);
  console.log(`🔒 CORS enabled for: ${process.env.ALLOWED_ORIGINS}`);
});
