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

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

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

import UserService from "../../../services/user.js";
import SessionService from "../../../services/session.js";

export class AuthApiControllerV1 extends DtpController {
  get name(): string {
    return "AuthApiControllerV1";
  }
  get slug(): string {
    return "authV1";
  }
  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("/sign-out", this.getSignOut.bind(this));
  }

  async postSignIn(req: Request, res: Response): Promise<void> {
    try {
      this.log.info("authenticating user account", {
        email: req.body.email,
      });
      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,
        persona: user.persona,
      };

      this.log.info("creating JSON Web Token for user session", {
        user: { _id: user._id },
      });
      const token = await SessionService.createJsonWebToken(user);
      req.session.token = token;

      req.session.save((err: Error): void => {
        if (err) {
          res.status(err.statusCode || 500).json({
            success: false,
            message: err.message,
          });
          return;
        }
        res.status(200).json({
          success: true,
          user: {
            _id: user._id.toString(),
            email: user.email,
            displayName: user.displayName,
            flags: user.flags,
            persona: user.persona,
          },
          token,
        });
      });
    } catch (error) {
      this.log.error("failed to process user sign-in", { error });
      res.status((error as Error).statusCode || 500).json({
        success: false,
        message: (error as Error).message,
      });
    }
  }

  async postRenewToken(req: Request, res: Response): Promise<void> {
    try {
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: "No valid session found",
        });
        return;
      }
      const token = await SessionService.createJsonWebToken(req.user);
      req.session.token = token;
      this.log.info("user session token renewed", {
        user: {
          _id: req.user._id,
          displayName: req.user.displayName,
          flags: req.user.flags,
        },
      });
      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 getSignOut(req: Request, res: Response): Promise<void> {
    const user = req.user;
    if (req.session.token) {
      try {
        await SessionService.revokeJsonWebToken(req.session.token);
      } catch (error) {
        this.log.error("failed to revoke user session", { error });
        res.status((error as Error).statusCode || 500).json({
          success: false,
          message: (error as Error).message,
        });
        return;
      }
    }
    req.session.destroy((err: Error): void => {
      if (err) {
        this.log.error("failed to destroy user session", { error: err });
        res.status(200).json({
          success: false,
          message: err.message,
        });
        return;
      }
      if (user) {
        this.log.info("user session destroyed (sign out)", {
          user: { _id: user._id },
        });
      } else {
        this.log.info("userless session destroyed (sign out)");
      }
      res.status(200).json({ success: true });
    });
  }
}

export default AuthApiControllerV1;
