'use server';

import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account';
import { MontonioOrderHandlerService } from '@/packages/billing/montonio/src';
import { addToCart, deleteLineItem, retrieveCart } from '@lib/data/cart';
import { getCartId } from '@lib/data/cookies';
import { StoreCartLineItem, StoreProductVariant } from '@medusajs/types';
import { isSameMinute } from 'date-fns';
import { z } from 'zod';

import {
  cancelReservation,
  getOrderedTtoServices,
} from '~/lib/services/reservation.service';

import { createCartEntriesLog } from './audit/cartEntries';
import { getAvailableAppointmentsForService } from './connected-online.service';

const env = () =>
  z
    .object({
      medusaBackendPublicUrl: z
        .string({
          error: 'MEDUSA_BACKEND_PUBLIC_URL is required',
        })
        .min(1),
      siteUrl: z
        .string({
          error: 'NEXT_PUBLIC_SITE_URL is required',
        })
        .min(1),
    })
    .parse({
      medusaBackendPublicUrl: (process.env.DEV_MONTONIO_CALLBACK_URL ||
        process.env.MEDUSA_BACKEND_PUBLIC_URL)!,
      siteUrl: (process.env.DEV_MONTONIO_CALLBACK_URL ||
        process.env.NEXT_PUBLIC_SITE_URL)!,
    });

export async function handleAddToCart({
  selectedVariant,
  countryCode,
}: {
  selectedVariant: Pick<StoreProductVariant, 'id'>;
  countryCode: string;
}) {
  try {
  } catch (e) {
    console.error('medusa card error: ', e);
  }
  const { account } = await loadCurrentUserAccount();
  if (!account) {
    throw new Error('Account not found');
  }

  const quantity = 1;
  const { newCart, addedItem } = await addToCart({
    variantId: selectedVariant.id,
    quantity,
    countryCode,
  });

  await createCartEntriesLog({
    variantId: selectedVariant.id,
    operation: 'ADD_TO_CART',
    accountId: account.id,
    cartId: newCart.id,
  });

  return { cart: newCart, addedItem };
}

export async function handleDeleteCartItem({ lineId }: { lineId: string }) {
  await deleteLineItem(lineId);
  await cancelReservation(lineId);

  const cartId = await getCartId();
  const { account } = await loadCurrentUserAccount();
  if (!account) {
    throw new Error('Account not found');
  }

  await createCartEntriesLog({
    variantId: lineId,
    operation: 'REMOVE_FROM_CART',
    accountId: account.id,
    cartId: cartId!,
  });
}

export async function handleNavigateToPayment({
  language,
  paymentSessionId,
  amount,
  currencyCode,
  cartId,
}: {
  language: string;
  paymentSessionId: string;
  amount: number;
  currencyCode: string;
  cartId: string;
}) {
  const { account } = await loadCurrentUserAccount();
  if (!account) {
    throw new Error('Account not found');
  }

  const cart = await retrieveCart();
  if (!cart) {
    throw new Error('No cart found');
  }
  const orderedTtoServices = await getOrderedTtoServices({ cart });

  if (orderedTtoServices?.length) {
    const unavailableLineItemIds: string[] = [];
    for (const ttoService of orderedTtoServices) {
      const availabilities = await getAvailableAppointmentsForService(
        ttoService.service_id,
        ttoService.provider.key,
        ttoService.location_sync_id,
        new Date(ttoService.start_time),
        1,
      );
      const isAvailable = availabilities?.T_Booking?.length
        ? availabilities.T_Booking.find((timeSlot) =>
            isSameMinute(ttoService.start_time, timeSlot.StartTime),
          )
        : false;

      if (!isAvailable) {
        unavailableLineItemIds.push(ttoService.medusa_cart_line_item_id!);
      }
    }

    if (unavailableLineItemIds.length) {
      return { unavailableLineItemIds };
    }
  }

  const paymentLink =
    await new MontonioOrderHandlerService().getMontonioPaymentLink({
      notificationUrl: `${env().medusaBackendPublicUrl}/hooks/payment/montonio_montonio`,
      returnUrl: `${env().siteUrl}/home/cart/montonio-callback`,
      amount,
      currency: currencyCode.toUpperCase(),
      description: `Order from Medreport`,
      locale: language,
      merchantReference: `${account.id}:${paymentSessionId}:${cartId}`,
    });

  await createCartEntriesLog({
    operation: 'NAVIGATE_TO_PAYMENT',
    accountId: account.id,
    cartId: cart.id,
  });

  return { url: paymentLink };
}

export async function handleLineItemTimeout({
  lineItem,
}: {
  lineItem: StoreCartLineItem;
}) {
  const { account } = await loadCurrentUserAccount();
  if (!account) {
    throw new Error('Account not found');
  }

  await deleteLineItem(lineItem.id);

  await createCartEntriesLog({
    operation: 'LINE_ITEM_TIMEOUT',
    accountId: account.id,
    cartId: lineItem.cart_id,
  });
}
