<script>
  import { link } from 'svelte-spa-router';
  import { fade } from 'svelte/transition';
  import { onMount } from "svelte";
  import api from "$/client/api.js";
  import FormField from "$/client/components/FormField.svelte";
  import Icon from "$/client/components/Icon.svelte";
  import IconImage from "$/client/components/IconImage.svelte";
  import Paypal from "$/client/components/Paypal.svelte";
  import BTCPay from "$/client/components/BTCPay.svelte";
  import Layout from "$/client/Layout.svelte";
  import { fake_payments } from "$/client/config.js";
  import { log } from "$/client/logging.js";

  const quips = {
    "0": "Awww, really? Alright then.",
    "10": "That's a good start.",
    "20": "Even more fair.",
    "30": "Sweet!",
    "40": "Yes! Love it!",
    "50": "Booyah!",
    "60": "Really?! Thank you!",
    "70": "Whoa! No way!",
    "80": "Fantastic! THANK YOU!",
    "90": "NO WAY! YES!",
    "100": "I love you!"
  }

  const form = {
    amount: 10,
    _errors: {},
    _valid: true
  }

  // BUG: we have to duplicate this logic here because of how paypal works
  $: form._valid = form.amount >= 0 && form.amount <= 100;

  const amount_by = 10;

  let paid_in_full = false;
  let payment_failed = false;

  const change_amount = () => {
    form.amount = form.amount < 100 ? form.amount + amount_by : 0;
  }

  const payment_finished = (event) => {
    const { system, status } = event.detail;
    log.assert(status === "complete", "Payment status should be complete with finished event", system, event.detail);
    paid_in_full = true;
  }

  const payment_canceled = (event) => {
    log.debug("CANCELED", event);
  }

  const payment_error = () => {
    payment_failed = true;
  }

  const payment_loading = (event) => {
    log.debug("LOADING", event);
  }

  const pay_nothing = async () => {
    // posting to /api/user/payments is how you do a free purchase
    let [status, data] = await api.post("/api/user/payments", { amount: form.amount }, api.logout_user);

    if(status === 200) {
      paid_in_full = true;
    } else {
      log.error("status", status, "data", data);
      payment_failed = true;
      form._errors.main = data.message || data.error || "Payment Error.";
    }
  }

  // this is a demo of how to check a user's purchase quickly
  const already_paid = async () => {
    let [status, data] = await api.get("/api/user/payments");

    if(status === 200 && data.paid === true) {
      paid_in_full = true;
    } else {
      log.debug("GET to /api/user/payments returned", status, data);
    }
  }

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

<style>

  form#purchase {
    width: min-content;
  }

  label.slider {
    cursor: pointer;
    display: flex;
    height: 4rem;
    width: 100%;
    background-color: var(--color-bg-secondary);
    user-select: none;
    -webkit-user-select: none;
  }

  label.slider::after {
    display: flex;
    justify-content: center;
    align-items: center;
    width: calc(1% * var(--amount));
    min-width: 2ch;
    background-color: var(--color-bg-tertiary);
    height: 4rem;
    counter-reset: amount var(--amount);
    content: '$' counter(amount);
    transition: 0.5s;
  }

  input#amount {
    display: none;
  }

  card {
    width: 400px;
    border-radius: var(--border-radius) var(--border-radius) 0px 0px;
  }

  card#failed top {
    background-color: var(--color-bg-secondary);
    text-align: center;
    padding: 1rem;
  }

  payments {
    display: flex;
    flex-direction: column;
  }

  payments.disabled {
    filter: blur(5px);
  }

  form card bottom {
    padding: 0.5rem;
  }

  callout {
    border-radius: 0px 0px var(--border-radius) var(--border-radius);
  }
</style>

<Layout centered={ true } authenticated={ true }>
  {#if paid_in_full}
    <card in:fade|local id="paid">
      <top>
        <IconImage name="dollar-sign" />
      </top>

      <middle>
        <h1>Welcome!</h1>
        <p>Thank you for your purchase.  You can now enjoy the entire
          site.
        </p>
      </middle>

      <bottom>
        <button-group>
          <button data-testid="payment-done-button"><a href="/" use:link>Start Browsing</a></button>
        </button-group>
      </bottom>
    </card>
  {:else}
    {#if payment_failed}
      <card in:fade|local id="failed">
      <top><h1 data-testid="payment-error">Payment Error!</h1></top>

      <middle>
      <p style="font-size: 1.5em;">There was an error processing your payment.  Please try again later.</p>
        <p>You can email <a href="mailto:help@xor.academy">help@xor.academy</a> to get help with this purchase.</p>
      </middle>

      <bottom>
        <button-group>
          <button type="button"><a href="/" use:link><Icon name="arrow-left-circle" size="36" /> Cancel</a></button>
          <button data-testid="payment-tryagain" on:click={ () => payment_failed = false }><Icon name="credit-card" size="36" light={ true } /> Try Again</button>
        </button-group>
      </bottom>
      </card>
      {:else}
        <form method="POST" id="purchase">
          <card>
            <top>
              {#if payment_failed }
                <h1>Payment Error!</h1>
              {:else}
                <h1>What's a Fair Price?</h1>
              {/if}
            </top>

            <middle>
            <FormField form={ form } field="amount" label="{ quips[form.amount] || `Bad Value! ${form.amount}` }">
                <label data-testid="payment-amount" class="slider"
                       for="amount" style="--amount: { form.amount };"
                         on:click={ () => change_amount() }>
                </label>
                <input type="numeric" id="amount" bind:value={ form.amount } />
              </FormField>

              {#if form._valid}
              <p>Click on the slider to change <b>how much you think this course is worth</b>, then
                <b>select your payment method</b>.</p>
              {:else}
                <p><b>You've caused an error in this form. Please email help@xor.academy and tell them how you did this.</b></p>
              {/if}
            </middle>

            <bottom>
              <payments class:disabled={ !form._valid }>
                {#if form.amount > 0}
                  <Paypal credit_card={ true } amount={ form.amount }
                          on:error={ payment_error}
                          on:finished={ payment_finished }
                          on:canceled={ payment_canceled }
                          on:loading={ payment_loading }
                          disabled = { !form._valid }/>

                  <BTCPay amount={ form.amount }
                          on:error={ payment_error}
                          on:finished={ payment_finished }
                          on:canceled={ payment_canceled }
                          on:loading={ payment_loading }
                          disabled = { !form._valid } />
                {:else}
                  <button type="button" data-testid="button-paynothing" on:click|preventDefault={ pay_nothing }>Pay Nothing</button>
                {/if}
              </payments>
            </bottom>
          </card>
          {#if fake_payments}
            <callout class="warning">
              Payments are fake right now.  Use a fake CC from Paypal,
              and use testnet coins for BTC/LTC.
            </callout>
          {/if}
        </form>
    {/if}
  {/if}
</Layout>
