import { Response, NextFunction } from "express";
import { STATUS_CODES } from "../constants/statusCodes";
import { CustomRequest } from "../interfaces/auth";
import UserModel from "../models/UserModel";
import ResponseUtil from "../utils/Response/responseUtils";
import {
  hasAnyPaidAccess,
  hasFamilyAccess,
  hasPremiumAccess,
} from "../utils/subscriptionAccess";

async function loadUserForSubscription(req: CustomRequest) {
  const userId = req.userId;
  if (!userId) return null;
  return UserModel.findById(userId)
    .select(
      "subscriptionStatus activeEntitlement subscriptionExpiresAt isDeleted isBanned",
    )
    .lean();
}

function forbidden(res: Response, message: string) {
  return ResponseUtil.errorResponse(res, STATUS_CODES.FORBIDDEN, message);
}

/** Requires premium or family entitlement with valid subscription window. */
export const requirePremiumAccess = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction,
) => {
  try {
    const user = await loadUserForSubscription(req);
    if (!user || user.isDeleted || user.isBanned) {
      return forbidden(res, "Subscription required");
    }
    if (!hasPremiumAccess(user)) {
      return forbidden(res, "Premium subscription required");
    }
    next();
  } catch (err) {
    ResponseUtil.handleError(res, err);
  }
};

/** Requires family entitlement only. */
export const requireFamilyAccess = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction,
) => {
  try {
    const user = await loadUserForSubscription(req);
    if (!user || user.isDeleted || user.isBanned) {
      return forbidden(res, "Subscription required");
    }
    if (!hasFamilyAccess(user)) {
      return forbidden(res, "Family subscription required");
    }
    next();
  } catch (err) {
    ResponseUtil.handleError(res, err);
  }
};

/** Alias: any paid tier (premium or family). */
export const requirePaidAccess = requirePremiumAccess;

export { hasPremiumAccess, hasFamilyAccess, hasAnyPaidAccess };
