'use server';

import { MontonioOrderToken } from '@/app/home/(user)/_components/cart/types';
import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account';
import { retrieveCart } from '@lib/data/cart';
import jwt from 'jsonwebtoken';

import { handlePlaceOrder } from '../../../_lib/server/cart-actions';

const MONTONIO_PAID_STATUS = 'PAID';

async function decodeOrderToken(orderToken: string) {
  const secretKey = process.env.MONTONIO_SECRET_KEY as string;

  const decoded = jwt.verify(orderToken, secretKey, {
    algorithms: ['HS256'],
  }) as MontonioOrderToken;

  if (decoded.paymentStatus !== MONTONIO_PAID_STATUS) {
    throw new Error('Payment not successful');
  }

  return decoded;
}

async function getCartByOrderToken(decoded: MontonioOrderToken) {
  const [, , cartId] = decoded.merchantReferenceDisplay.split(':');
  if (!cartId) {
    throw new Error('Cart ID not found');
  }
  const cart = await retrieveCart(cartId);
  if (!cart) {
    throw new Error('Cart not found');
  }
  return cart;
}

export async function processMontonioCallback(orderToken: string) {
  const { account } = await loadCurrentUserAccount();
  if (!account) {
    throw new Error('Account not found in context');
  }

  try {
    const decoded = await decodeOrderToken(orderToken);
    const cart = await getCartByOrderToken(decoded);
    const result = await handlePlaceOrder({ cart });
    return result;
  } catch (error) {
    console.error('Failed to place order', error);
    throw new Error(`Failed to place order, message=${error}`);
  }
}
