// src/controllers/auth.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

// import env from "../config/env.js";
import { NextFunction, Request, Response } from "express";

import { DtpController } from "../lib/controller.js";

import UserService from "../services/user.js";
import SessionService, { SessionType } from "../services/session.js";

export class AuthController extends DtpController {
  get name(): string {
    return "AuthController";
  }
  get slug(): string {
    return "auth";
  }
  get route(): string {
    return "/auth";
  }

  constructor() {
    super();
  }

  async start(): Promise<void> {
    this.router.post("/sign-in", this.postSignIn.bind(this));
    this.router.post("/renew-token", this.postRenewToken.bind(this));

    this.router.get("/welcome", this.getWelcomeView.bind(this));
    this.router.get("/sign-in", this.getSignInForm.bind(this));
    this.router.get("/sign-out", this.getSignOut.bind(this));
  }

  async postSignIn(
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> {
    try {
      const user = await UserService.authenticate(
        req.body.email,
        req.body.password
      );
      req.session.user = {
        _id: user._id,
        email: user.email,
        displayName: user.displayName,
        flags: user.flags,
      };

      const token = await SessionService.createJsonWebToken(user);
      req.session.token = token;
      req.session.type = SessionType.WEB;

      req.session.save((err: Error) => {
        if (err) {
          return next(err);
        }
        res.status(200).json({
          success: true,
          user: {
            _id: user._id.toString(),
            email: user.email,
            displayName: user.displayName,
            flags: user.flags,
          },
          token,
        });
      });
    } catch (error) {
      return next(error);
    }
  }

  async postRenewToken(req: Request, res: Response): Promise<void> {
    try {
      const user = await SessionService.verifyJsonWebToken(req.body.token);
      const token = await SessionService.createJsonWebToken(user);
      req.session.token = token;
      res.status(200).json({ success: true, token });
    } catch (error) {
      this.log.error("failed to process token renewal", { error });
      res.status((error as Error).statusCode || 500).json({
        success: false,
        message: (error as Error).message,
      });
    }
  }

  async getWelcomeView(_req: Request, res: Response): Promise<void> {
    res.status(200).json({
      success: true,
      message: "Welcome to DTP Web Application",
    });
  }

  async getSignInForm(_req: Request, res: Response): Promise<void> {
    res.status(200).json({
      success: true,
      form: "sign-in",
    });
  }

  async getSignOut(
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<void> {
    if (req.session.token) {
      try {
        await SessionService.revokeJsonWebToken(req.session.token);
      } catch (error) {
        this.log.error("failed to revoke JSON Web Token", { error });
      }
    }
    req.session.destroy((err: Error) => {
      if (err) {
        this.log.error("failed to destroy user session", { error: err });
        return next(err);
      }
      res.status(200).json({ success: true, message: "Signed out successfully" });
    });
  }
}

export default AuthController;
