const AbonemmentService = require('../../services/abonemments/AbonemmentService');
const PermissionService = require('../../services/permissions/PermissionService');
const service = new AbonemmentService();

module.exports = {
  async subscribe(req, res) {
    try {
      const rawUser = req.user || {};
      console.log('[CONTROLLER SUBSCRIBE] Raw req.user:', { id: rawUser.id, userId: rawUser.userId, email: rawUser.email, role: rawUser.role });
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      console.log('[CONTROLLER SUBSCRIBE] Normalized actorUser:', { id: actorUser.id, email: actorUser.email, role: actorUser.role });

      // Permission check: user must have can_subscribe
      const hasPermission = await PermissionService.userHasPermission(actorUser.id, 'can_subscribe');
      if (!hasPermission) {
        return res.status(403).json({ success: false, message: 'You do not have permission to complete a subscription.' });
      }

      const result = await service.subscribeOrder({
        userId: actorUser.id || null,
        items: req.body.items,
        billingInterval: req.body.billing_interval,
        intervalCount: req.body.interval_count,
        isAutoRenew: req.body.is_auto_renew,
        isForSelf: req.body.is_for_self,
        recipientName: req.body.recipient_name,
        recipientEmail: req.body.recipient_email,
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        email: req.body.email,
        street: req.body.street,
        postalCode: req.body.postalCode,
        city: req.body.city,
        country: req.body.country,
        frequency: req.body.frequency,
        phone: req.body.phone,
        recipientContractName: req.body.recipientContractName,
        recipientAddress: req.body.recipientAddress,
        paymentMethod: req.body.paymentMethod,
        invoiceByEmail: req.body.invoiceByEmail,
        invoiceSameAsShipping: req.body.invoiceSameAsShipping,
        invoiceFullName: req.body.invoiceFullName,
        invoiceStreet: req.body.invoiceStreet,
        invoicePostalCode: req.body.invoicePostalCode,
        invoiceCity: req.body.invoiceCity,
        invoicePhone: req.body.invoicePhone,
        invoiceEmail: req.body.invoiceEmail,
        uidNumber: req.body.uidNumber || req.body.uid_number,
        atuNumber: req.body.atuNumber || req.body.atu_number,
        taxMode: req.body.taxMode || req.body.tax_mode,
        contractNumber: req.body.contractNumber || req.body.contract_number,
        signingCity: req.body.signingCity || req.body.signing_city || '',
        signatureDataUrl: req.body.signatureDataUrl || req.body.signature_data_url,
        actorUser, // normalized to include id
        referredBy: req.body.referred_by,
      });
      return res.json({ success: true, data: result });
    } catch (err) {
      console.error('[ABONEMENT SUBSCRIBE]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async pause(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.pause({ abonementId: req.params.id, actorUser });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT PAUSE]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async resume(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.resume({ abonementId: req.params.id, actorUser });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT RESUME]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async cancel(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.cancel({ abonementId: req.params.id, actorUser });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT CANCEL]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async updateContent(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.updateContent({
        abonementId: req.params.id,
        actorUser,
        items: req.body.items,
      });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT UPDATE CONTENT]', err);
      if (err?.message === 'Not found') {
        return res.status(404).json({ success: false, message: 'Abonement not found' });
      }
      if (err?.message === 'Forbidden') {
        return res.status(403).json({ success: false, message: 'Forbidden' });
      }
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async renew(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.adminRenew({ abonementId: req.params.id, actorUser });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT RENEW]', err);
      return res.status(403).json({ success: false, message: err.message });
    }
  },

  async getMine(req, res) {
    try {
      const rawUser = req.user || {};
      const id = rawUser.id ?? rawUser.userId;
      if (!id) {
        return res.status(401).json({ success: false, message: 'Unauthorized: missing user id' });
      }
      console.log('[CONTROLLER GET MINE] Using user id:', id);
      const data = await service.getMyAbonements({ userId: id });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT MINE]', err);
      return res.status(500).json({ success: false, message: 'Internal error' });
    }
  },

  async getMineStatus(req, res) {
    try {
      const rawUser = req.user || {};
      const id = rawUser.id ?? rawUser.userId;
      if (!id) {
        return res.status(401).json({ success: false, message: 'Unauthorized: missing user id' });
      }
      const data = await service.getMyAbonementStatus({ userId: id });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT MINE STATUS]', err);
      return res.status(500).json({ success: false, message: 'Internal error' });
    }
  },

  async getInvoices(req, res) {
    try {
      const rawUser = req.user || {};
      const actorUser = { ...rawUser, id: rawUser.id ?? rawUser.userId ?? null };
      const data = await service.getInvoicesForAbonement({
        abonementId: req.params.id,
        actorUser,
      });
      return res.json({ success: true, data });
    } catch (err) {
      console.error('[ABONEMENT INVOICES]', err);
      if (err?.message === 'Not found') {
        return res.status(404).json({ success: false, message: 'Abonement not found' });
      }
      if (err?.message === 'Forbidden') {
        return res.status(403).json({ success: false, message: 'Forbidden' });
      }
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async getHistory(req, res) {
    try {
      return res.json({ success: true, data: await service.getHistory({ abonementId: req.params.id }) });
    } catch (err) {
      console.error('[ABONEMENT HISTORY]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },

  async adminList(req, res) {
    try {
      return res.json({ success: true, data: await service.adminList({ status: req.query.status }) });
    } catch (err) {
      console.error('[ABONEMENT ADMIN LIST]', err);
      return res.status(403).json({ success: false, message: err.message });
    }
  },

  async getReferredSubscriptions(req, res) {
    try {
      const rawUser = req.user || {};
      const id = rawUser.id ?? rawUser.userId;
      return res.json({ success: true, data: await service.getReferredSubscriptions({ userId: id, email: rawUser.email }) });
    } catch (err) {
      console.error('[ABONEMENT REFERRED SUBSCRIPTIONS]', err);
      return res.status(400).json({ success: false, message: err.message });
    }
  },
};