const UnitOfWork = require('../../database/UnitOfWork');
const ReferralService = require('../../services/referral/ReferralService'); // <-- use unified service
const { logger } = require('../../middleware/logger');

// Helper to get frontend URL without trailing slash, no localhost fallback
function getFrontendUrl() {
  let url = process.env.FRONTEND_URL || '';
  if (url.endsWith('/')) {
    url = url.slice(0, -1);
  }
  return url;
}

class ReferralTokenController {
  static async create(req, res) {
    const userId = req.user.userId;
    const userRole = req.user.role;
    const { expiresInDays, maxUses } = req.body;
    // Normalize unlimited expiry from frontend (0 or -1) to -1 sentinel
    let normalizedExpiresInDays = (expiresInDays === 0) ? -1 : expiresInDays;
    logger.info('ReferralTokenController:createReferralToken:start', { userId, normalizedExpiresInDays, maxUses });
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      let maxActiveLinks = 5;
      if (userRole === 'admin' || userRole === 'super_admin') {
        maxActiveLinks = 15;
      }
      const activeCount = await ReferralService.countActiveReferralTokens(userId, unitOfWork);
      if (activeCount >= maxActiveLinks) {
        await unitOfWork.rollback();
        return res.status(403).json({
          success: false,
          message: `Maximum active referral links reached (${maxActiveLinks}) for your role (${userRole}).`
        });
      }
      const token = await ReferralService.createReferralToken({
        userId,
        expiresInDays: normalizedExpiresInDays,
        maxUses,
        unitOfWork
      });
      if (normalizedExpiresInDays === -1) {
        logger.info('ReferralTokenController:createReferralToken:unlimited_expiry', { userId });
      }
      await unitOfWork.commit();
      logger.info('ReferralTokenController:createReferralToken:success', { token });
      const link = `${getFrontendUrl()}/register?ref=${token.token}`;
      res.json({ success: true, token: token.token, link, expiresAt: token.expiresAt, maxUses: token.maxUses });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralTokenController:createReferralToken:error', { userId, error });
      res.status(400).json({ success: false, message: error.message });
    }
  }

  static async list(req, res) {
    const userId = req.user.userId;
    logger.info('ReferralTokenController:getUserReferralTokens:start', { userId });
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const tokens = await ReferralService.getUserReferralTokens(userId, unitOfWork);
      await unitOfWork.commit();
      logger.info('ReferralTokenController:getUserReferralTokens:success', { count: tokens.length });
      const frontendUrl = getFrontendUrl();

      // FIX: tokens already transformed by service; use provided fields instead of raw DB column names
      const result = tokens.map(t => {
        const isUnlimitedExpiry = t.isUnlimited || !t.expires;
        const usage = t.usage || (t.isUnlimited ? `${t.used}/∞` : `${t.used}/${t.maxUses}`);
        return {
          id: t.id,
          status: t.status,
          created: t.created,
          created_at: t.created,          // legacy alias
          expires: isUnlimitedExpiry ? '∞' : t.expires,
          expires_at: t.expires,          // legacy alias
          link: t.link || `${frontendUrl}/register?ref=${t.token}`,
            token: t.token,
          // normalized usage fields
          used: t.used,
          maxUses: t.maxUses,
          isUnlimited: t.isUnlimited,
          usage,
          usageDisplay: usage,
          // backward compatibility (old FE expected these)
          max_uses: t.isUnlimited ? -1 : t.maxUses,
          usage_count: t.used
        };
      });

      return res.json({ success: true, tokens: result });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralTokenController:getUserReferralTokens:error', { userId, error });
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async stats(req, res) {
    const userId = req.user.userId;
    logger.info('ReferralTokenController:getUserReferralStats:start', { userId });
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const stats = await ReferralService.getUserReferralStats(userId, unitOfWork);
      await unitOfWork.commit();
      logger.info('ReferralTokenController:getUserReferralStats:success', { stats });
      // Response now includes companyUsersReferred and personalUsersReferred
      res.json({ success: true, stats });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralTokenController:getUserReferralStats:error', { userId, error });
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async deactivate(req, res) {
    const userId = req.user.userId;
    const { tokenId } = req.body;
    logger.info('ReferralTokenController:deactivateReferralToken:start', { userId, tokenId });
    if (!tokenId) {
      return res.status(400).json({ success: false, message: 'tokenId is required' });
    }
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await ReferralService.deactivateReferralToken(userId, tokenId, unitOfWork);
      await unitOfWork.commit();
      logger.info('ReferralTokenController:deactivateReferralToken:success', { userId, tokenId });
      res.json({ success: true, message: 'Referral link deactivated' });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralTokenController:deactivateReferralToken:error', { userId, tokenId, error });
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async referredUsers(req, res) {
    const userId = req.user.userId;
    logger.info('ReferralTokenController:referredUsers:start', { userId });
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const result = await ReferralService.getReferredUsers(userId, unitOfWork);
      await unitOfWork.commit();
      logger.info('ReferralTokenController:referredUsers:success', { userId, total: result.total_referred_users });
      return res.json({
        success: true,
        total_referred_users: result.total_referred_users,
        users: result.users
      });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralTokenController:referredUsers:error', { userId, error });
      return res.status(500).json({ success: false, message: error.message });
    }
  }
}

module.exports = ReferralTokenController;
