import logging from '../lib/logging.js';
import { Payment } from "../lib/models.js";

const log = logging.create("/queues/stripe.js");

const find_payment = async (msg) => {
  // sys_primary_id is the payment_intent and sys_secondary_id is charge_id
  const dobj = msg.data.object;

  // stripe is stupid and changes the name/location of payment_intent IDs
  if(dobj.payment_intent) {
    // it has a payment intent so need to find by that
    return await Payment.first({sys_primary_id: dobj.payment_intent});
  } else {
    switch(dobj.object) {
      case "payment_intent":
        return await Payment.first({sys_primary_id: dobj.id});
      case "charge":
        return await Payment.first({sys_secondary_id: dobj.id});
      default:
        return undefined;
    }
  }
}

export const webhook = async (job) => {
  try {
    const msg = job.data;
    const payment = await find_payment(msg);

    log.debug(`Stripe WebHook event ${msg.type} ID ${msg.id} created ${msg.created} payment ID ${payment ? payment.id : "none"}`);

    if(payment) {
      switch(msg.type) {
        case "payment_intent.created":
          log.debug(`Payment intent created, payment ${payment.id} is in process for user ${payment.user_id}`)
          break;
          // these create a refunded status
        case "charge.dispute.created":
        case "charge.refunded":
          await Payment.update({id: payment.id}, {status: "refunded", status_reason: msg.type});
          break;
          // these result in pending
        case "charge.failed": // not sure if this is temporary
        case "payment_intent.requires_action":
          await Payment.update({id: payment.id}, {status: "pending", status_reason: msg.type});
          break;
          // these all result in complete status
        case "charge.succeeded":
          await Payment.update({id: payment.id}, {
            sys_secondary_id: msg.data.object.id,
            status: "complete",
            status_reason: msg.type
          });
          break;
        case "payment_intent.succeeded":
          // on charge success we need to start tracking the charge id
          await Payment.update({id: payment.id}, { status: "complete", status_reason: msg.type });
          break;
        case "charge.dispute.funds_reinstated":
        case "charge.dispute.funds_withdrawn":
          await Payment.update({id: payment.id}, {status: "complete", status_reason: msg.type});
          break;
        case "radar.early_fraud_warning.created":
          await Payment.update({id: payment.id}, {status: "failed", status_reason: msg.type});
          break;
        default:
          log.info(`UNKNOWN STRIPE EVENT ${msg.type} ID: ${payment.id}`);
      }
    } else {
      console.log("<<< UNKNOWN WEBHOOK POST", msg.type, msg);
    }

  } catch (error) {
    log.error(error);
  }
}
