<svelte:head>
  <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Ensures optimal rendering on mobile devices. -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <!-- Optimal Internet Explorer compatibility -->
</svelte:head>

<script>
  import { onMount, createEventDispatcher } from 'svelte';
  import { inject_remote } from './Source.svelte';
  import Spinner from './Spinner.svelte';
  import { fake_payments, paypal_public } from '$/client/config.js';
  import api from "$/client/api.js";
  import { log } from "$/client/logging.js";
  import { fade } from "svelte/transition";

  export let product;
  export let credit_card = false;
  export let disabled = false;
  let paypal_ready = false;
  let paypal_sending = false;
  let paypal_loaded = false;
  let show_warning = false;

  const dispatch = createEventDispatcher();

  const dispatch_finished = async (paypal) => {
    paypal_sending = false;

    if(paypal.status === "COMPLETED") {
      let payment = {
        system: 'paypal',
        sys_primary_id: paypal.id,
        sys_secondary_id: paypal.purchase_units[0].payments.captures[0].id,
        sys_created_on: paypal.create_time,
        status: 'complete',
      };

      const [status, data] = await api.post('/api/payments/paypal', payment);

      if(status == 200) {
        log.debug("Paypal request returned.");

        // TODO: confirm no errors on reply and the returned data matches
        payment.internal_id = data.internal_id;
        dispatch('finished', payment);
      } else {
        log.debug("ERROR RESPONSE", status, data);
        dispatch("error", {message: "Validation error.", payment});
      }
    } else {
      dispatch("error", {message: `dispatch_finished called but status is ${paypal.status}`});
    }
  }

  const dispatch_canceled = (what) => dispatch('canceled', {paypal: what});

  const dispatch_error  = (what) => dispatch('error', {paypal: what});

  const dispatch_loading = (what) => dispatch('loading', {paypal: what});

  const load_paypal = () => {
    paypal_loaded = true;

    dispatch_loading();

    paypal.Buttons(
      {
        style: {
          layout: 'vertical',
          color: 'black',
          label: 'pay',
          tagline: false
        },

        onInit: () => {
          dispatch("init");
          paypal_ready = true;
        },

        onClick: () => {
          dispatch("click");
          show_warning = true;
        },

        createOrder: (data, actions) => {
          return actions.order.create({
            purchase_units: [{
              amount: { value: `${ product.price }` },
              description: `${product.title}: ${product.description}`,
            }],
            application_context: {
              brand_name: product.title,
              landing_page: 'BILLING',
              shipping_preference: 'NO_SHIPPING',
              user_action: 'PAY_NOW',
            },
          });
        },

        onApprove: (data, actions) => {
          paypal_sending = true;
          // do a warning here about the paypal BS?
          return actions.order.capture().then((details) => {
            if(details.error === 'INSTRUMENT_DECLINED') {
              dispatch("error", {
                message: "Instrument declined.",
                instrument_declined: true
              });
              return false;
            } else {
              dispatch_finished(details);
              return true;
            }
          });
        },

        onCancel: (data) => dispatch_canceled(data),
        onError: (err) => dispatch_error(err),
      }).render('#paypal-button-container');
  }

  const install_paypal = async () => {
    if(disabled) return;

    if(fake_payments) {
      log.debug("fake_payments set to true, sending error");
      dispatch("error", { system: "paypal", sys_primary_id: 11333, status: "complete", invoice_id: "FAKE" });
    } else if(!window.paypal) {
      let disable_funding = ['credit', 'bancontact',
        'blik', 'eps', 'giropay', 'ideal', 'mybank',
        'p24', 'sepa', 'sofort', 'venmo'];

      if(!credit_card) disable_funding.push('card');

      let script_url = `https://www.paypal.com/sdk/js?client-id=${paypal_public.client_id}&disable-funding=${disable_funding.join(',')}&debug=false&intent=capture&commit=true`;

      await inject_remote(document, script_url, load_paypal);
    } else {
      load_paypal();
    }
  }

  onMount(async () => {
    await install_paypal();
  });
</script>

<style>
  button.paypal-activate {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    width: 100%;
    margin-bottom: 0.5rem;
    background-color: var(--color-bg-secondary);
    color: var(--color);
  }

  .paypal-logo {
    max-height: 1.3rem;
    margin: 0.5rem;
    vertical-align: bottom;
    width: unset;
  }
</style>

{#if paypal_sending}
  <p>Please wait while we confirm your payment...</p>
  <Spinner />
{/if}

{#if !paypal_loaded}
  <Spinner />
{/if}

<div id="paypal-button-container">
</div>

{#if show_warning}
  <callout in:fade|local="{{ delay: 5000, duration: 500}}" class="info" style="max-height: min-content; z-index: -1000;"><span>Check your <b>Street Address</b> if your submit "does nothing". Paypal will add a <b>Street Address</b> for validation, but not tell you.</span></callout>
{/if}
