const UnitOfWork = require('../../database/UnitOfWork');
const ReferralService = require('../../services/referral/ReferralService');
const AbonemmentService = require('../../services/abonemments/AbonemmentService');
const { logger } = require('../../middleware/logger');

const abonemmentService = new AbonemmentService();

class ReferralRegistrationController {
  static async getReferrerInfo(req, res) {
    const { token } = req.params;
    // Unlimited tokens (max_uses / uses_remaining = -1) now bypass expiry & remaining checks.
    logger.info('ReferralRegistrationController:getReferrerInfo:start', { token });
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const info = await ReferralService.getReferrerInfo(token, unitOfWork);
      await unitOfWork.commit();

      if (!info.valid) {
        const reason = info.reason;
        let status = 400;
        if (reason === 'not_found') status = 404;
        else if (reason === 'expired' || reason === 'exhausted') status = 410;
        else if (reason === 'inactive') status = 403;
        logger.warn('ReferralRegistrationController:getReferrerInfo:invalid', { token, reason, status });
        return res.status(status).json({ success: false, reason });
      }

      logger.info('ReferralRegistrationController:getReferrerInfo:success', { token, referrerName: info.referrerName });
      return res.json({
        success: true,
        referrerName: info.referrerName,
        referrerEmail: info.referrerEmail,
        isUnlimited: info.isUnlimited,
        usesRemaining: info.usesRemaining
      });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralRegistrationController:getReferrerInfo:error', { token, error: error.message });
      return res.status(500).json({ success: false, message: 'internal_error' });
    }
  }

  static async registerPersonalReferral(req, res) {
    const { refToken, lang, ...registrationData } = req.body;
    logger.info('ReferralRegistrationController:registerPersonalReferral:start', {
      refToken,
      lang,
      email: registrationData.email
    });

    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const user = await ReferralService.registerPersonalWithReferral(
        { ...registrationData, lang }, refToken, unitOfWork
      );
      await unitOfWork.commit();
      await abonemmentService.linkGiftFlagsToUser(user.email, user.id);
      logger.info('ReferralRegistrationController:registerPersonalReferral:success', { userId: user.id, email: user.email });
      res.json({ success: true, userId: user.id, email: user.email });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralRegistrationController:registerPersonalReferral:error', {
        refToken,
        message: error?.message,
        name: error?.name
      });
      res.status(400).json({ success: false, message: error.message });
    }
  }

  static async registerCompanyReferral(req, res) {
    const { refToken, lang, ...registrationData } = req.body;
    logger.info('ReferralRegistrationController:registerCompanyReferral:start', {
      refToken,
      lang,
      companyEmail: registrationData.companyEmail,
      companyName: registrationData.companyName
    });

    const {
      companyEmail,
      password,
      companyName,
      companyPhone,
      contactPersonName,
      contactPersonPhone
    } = registrationData;

    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const user = await ReferralService.registerCompanyWithReferral({
        companyEmail,
        password,
        companyName,
        companyPhone,
        contactPersonName,
        contactPersonPhone,
        lang
      }, refToken, unitOfWork);
      await unitOfWork.commit();
      await abonemmentService.linkGiftFlagsToUser(user.email, user.id);
      logger.info('ReferralRegistrationController:registerCompanyReferral:success', { userId: user.id, email: user.email });
      res.json({ success: true, userId: user.id, email: user.email });
    } catch (error) {
      await unitOfWork.rollback(error);
      logger.error('ReferralRegistrationController:registerCompanyReferral:error', {
        refToken,
        message: error?.message,
        name: error?.name
      });
      res.status(400).json({ success: false, message: error.message });
    }
  }
}

module.exports = ReferralRegistrationController;
