/**
 * Authentication Routes
 *
 * Route definitions for authentication endpoints
 */

import { Router } from 'express';
import { authController } from './auth.controller';
import { authenticate } from '../../shared/middleware/auth.middleware';
import { validateBody } from '../../shared/middleware/validation.middleware';
import { registerSchema, loginSchema, refreshTokenSchema } from './dtos';
import { authRateLimiter } from '../../shared/middleware/rate-limit.middleware';
import { asyncHandler } from '../../shared/middleware/validation.middleware';
import { z } from 'zod';

/**
 * Create authentication router
 */
export function createAuthRoutes(): Router {
  const router = Router();

  /**
   * POST /api/auth/register
   * Register a new user
   *
   * Request body:
   * - email: string (valid email)
   * - username: string (3-20 chars, alphanumeric + underscore)
   * - password: string (min 8 chars, uppercase, lowercase, number, special char)
   *
   * Response: 201 Created
   * - user: object (id, email, username, isActive, createdAt)
   * - token: string (JWT)
   * - expiresIn: number (seconds)
   */
  router.post(
    '/register',
    authRateLimiter,
    validateBody(registerSchema),
    asyncHandler(async (req, res) => authController.register(req, res))
  );

  /**
   * POST /api/auth/login
   * Login with email and password
   *
   * Request body:
   * - email: string
   * - password: string
   *
   * Response: 200 OK
   * - user: object (id, email, username, isActive, lastLoginAt)
   * - token: string (JWT)
   * - expiresIn: number (seconds)
   */
  router.post(
    '/login',
    authRateLimiter,
    validateBody(loginSchema),
    asyncHandler(async (req, res) => authController.login(req, res))
  );

  /**
   * GET /api/auth/me
   * Get current user profile
   *
   * Requires: Bearer token in Authorization header
   *
   * Response: 200 OK
   * - user: object (id, email, username, isActive, telegramChatId, createdAt, updatedAt, lastLoginAt)
   */
  router.get(
    '/me',
    authenticate,
    asyncHandler(async (req, res) => authController.getProfile(req, res))
  );

  /**
   * POST /api/auth/logout
   * Logout current user (invalidates token)
   *
   * Requires: Bearer token in Authorization header
   *
   * Request body (optional):
   * - refreshToken: string (will be revoked if provided)
   *
   * Response: 200 OK
   * - message: string
   *
   * Note: Client should delete both tokens from storage
   */
  router.post(
    '/logout',
    authenticate,
    asyncHandler(async (req, res) => authController.logout(req, res))
  );

  /**
   * POST /api/auth/refresh
   * Refresh access token using refresh token
   *
   * Request body:
   * - refreshToken: string (required)
   *
   * Response: 200 OK
   * - token: string (new JWT access token)
   * - refreshToken: string (new refresh token - rotated)
   * - expiresIn: number (seconds until access token expires)
   * - refreshTokenExpiresIn: number (seconds until refresh token expires)
   *
   * Note: The old refresh token is invalidated after use
   */
  router.post(
    '/refresh',
    validateBody(refreshTokenSchema),
    asyncHandler(async (req, res) => authController.refreshToken(req, res))
  );

  /**
   * POST /api/auth/forgot-password
   * Request password reset email
   *
   * Request body:
   * - email: string
   *
   * Response: 200 OK
   * - message: string
   *
   * Note: Always returns success to prevent email enumeration
   */
  router.post(
    '/forgot-password',
    authRateLimiter,
    validateBody(z.object({
      email: z.string().email('Invalid email format'),
    })),
    asyncHandler(async (req, res) => authController.forgotPassword(req, res))
  );

  /**
   * POST /api/auth/reset-password
   * Reset password with token
   *
   * Request body:
   * - token: string (reset token from email)
   * - newPassword: string (same requirements as registration)
   *
   * Response: 200 OK
   * - message: string
   *
   * Note: Not yet fully implemented
   */
  router.post(
    '/reset-password',
    validateBody(z.object({
      token: z.string().min(1, 'Token is required'),
      newPassword: z.string().min(8, 'Password must be at least 8 characters'),
    })),
    asyncHandler(async (req, res) => authController.resetPassword(req, res))
  );

  return router;
}

// Export singleton instance
export const authRoutes = createAuthRoutes();
