/**
 * controller.ts
 * AuthController: maneja las peticiones HTTP de autenticación.
 * - Recibe los datos
 * - Llama al use-case correspondiente
 * - Responde al cliente
 * - Maneja los errores
 */

import { Response } from "express";
import { AuthRequest } from "../middlewares/auth.middleware.js";
import { CustomError } from "../../domain/errors/custom.error.js";
import { AuthRepositoryImpl } from "../../data/repositories/auth.repository.impl.js";
import { RegisterUserUseCase } from "../../domain/use-cases/auth/register-user.use-case.js";
import { LoginUserUseCase } from "../../domain/use-cases/auth/login-user.use-case.js";
import { GetMeUseCase } from "../../domain/use-cases/auth/get-me.use-case.js";

export class AuthController {
  private repository = new AuthRepositoryImpl();
  private registerUseCase = new RegisterUserUseCase(this.repository);
  private loginUseCase = new LoginUserUseCase(this.repository);
  private getMeUseCase = new GetMeUseCase(this.repository);

  register = async (req: AuthRequest, res: Response) => {
    try {
      const result = await this.registerUseCase.execute(req.body);
      res.status(201).json(result);
    } catch (error) {
      this.handleError(error, res);
    }
  };

  login = async (req: AuthRequest, res: Response) => {
    try {
      const result = await this.loginUseCase.execute(req.body);
      res.status(200).json(result);
    } catch (error) {
      this.handleError(error, res);
    }
  };

  getMe = async (req: AuthRequest, res: Response) => {
    try {
      if (!req.user) {
        throw CustomError.unauthorized("User not authenticated");
      }

      const result = await this.getMeUseCase.execute(req.user.id);
      res.status(200).json(result);
    } catch (error) {
      this.handleError(error, res);
    }
  };

  private handleError(error: unknown, res: Response): void {
    if (error instanceof CustomError) {
      res.status(error.statusCode).json({ error: error.message });
      return;
    }

    if (error instanceof Error) {
      res.status(400).json({ error: error.message });
      return;
    }

    res.status(500).json({ error: "Internal server error" });
  }
}