import { DurationUnit } from "@/interfaces/paypal";
import {
  CreateOrderActions,
  CreateOrderData,
  OnApproveActions,
  OnApproveData,
  OnCancelledActions,
  OrderResponseBody,
} from "@paypal/paypal-js";
import {
  PayPalButtons,
  PayPalScriptProvider,
  usePayPalScriptReducer,
} from "@paypal/react-paypal-js";
import axios from "axios";
import { useState, useEffect } from "react";
import { toast } from "react-toastify";

interface Props {
  clientID: string;
  currency: string;
  price: number;
  duration: number;
  duration_unit: DurationUnit;
  loadScript?: boolean;
  setIsLoading: (isLoading: boolean) => void;
  onSuccess: (duration: number, duration_unit: DurationUnit) => void;
  trackingId?: string;
}

export default function PayPalPayment({
  clientID,
  price,
  currency,
  duration,
  duration_unit,
  loadScript,
  setIsLoading,
  onSuccess,
  trackingId,
}: Props) {
  const createOrder = async (
    data: CreateOrderData,
    actions: CreateOrderActions
  ): Promise<string> => {
    if (!trackingId) {
      throw new Error("trackingId is not set");
    }
    setIsLoading(true);

    return axios
      .post<OrderResponseBody>("/api/paypal", {
        currencyCode: currency,
        price,
        trackingId,
      })
      .then((response) => response.data)
      .then((data) => data.id);
  };

  const onApprove = async (data: OnApproveData, actions: OnApproveActions) => {
    if (!trackingId) {
      throw new Error("trackingId is not set");
    }

    const request = await axios.post<{ ok: boolean; reason?: string }>(
      "/api/paypal/approve",
      { id: data.orderID, duration, duration_unit, trackingId }
    );

    if (request.status !== 200) {
      toast.error("Something went wrong, please try again later");
      return;
    }

    toast.success("Your account has been credited more time!");
    return onSuccess(duration, duration_unit);
  };

  const onError = async (data: Record<string, unknown>) => {
    setIsLoading(false);
  };

  const onCancel = async (
    data: Record<string, unknown>,
    actions: OnCancelledActions
  ) => {
    setIsLoading(false);
  };

  if (trackingId) {
    return loadScript ? (
      <PayPalScriptProvider
        options={{
          clientId: clientID,
          currency,
          intent: "capture",
          commit: true,
          vault: true,
        }}
      >
        <PayPalButtons
          className="w-full"
          style={{ layout: "vertical" }}
          createOrder={createOrder}
          onApprove={onApprove}
          onCancel={onCancel}
          onError={onError}
        />
      </PayPalScriptProvider>
    ) : (
      <PayPalButtons
        className="w-full"
        style={{ layout: "vertical" }}
        createOrder={createOrder}
        onApprove={onApprove}
        onCancel={onCancel}
        onError={onError}
      />
    );
  }

  return null;
}
