<script>
  import Layout from "$/client/Layout.svelte";
  import { push } from 'svelte-spa-router';
  import Paypal from "$/client/components/Paypal.svelte";
  import Stripe from "$/client/components/Stripe.svelte";
  import FakePayment from "$/client/components/FakePayment.svelte";
  import Spinner from "$/client/components/Spinner.svelte";
  import Icon from "$/client/components/Icon.svelte";
  import * as config from "$/client/config.js";
  import { onMount } from "svelte";
  import { defer } from "$/client/helpers.js";
  import api from "$/client/api.js";

  export let params = {status: false};
  let product = {};
  let loading = false;
  let load_defer = defer();
  let payment_clicked = false;
  let paypal_active = true;
  let stripe_active = false;
  let discount = 0;
  let payment;

  let form = {
    paid: false,
    tos_agree: false,
    _valid: false,
    _errors: {}
  }

  const payment_finished = (system, data) => {
    form.payment_system = system;
    form.paid = true;
    form.payment_id = data.internal_id;
    form = form;
    loading = false;
  }

  const payment_error = (system, data) => {
    loading = false;
    // when data has a payment it's from an invalidated payment
    if(data.payment) {
      if(data.payment.system === "stripe") {
        payment = data.payment;
      } else {
        form._errors.main = "Your last payment failed.";
        form._errors.failed_payment = data.payment;
      }
    } else if(data.instrument_declined) {
      form._errors.main = "Instrument declined. Verify all fields are correct and contact your bank.";
      form._errors.instrument_declined = true;
    } else {
      form._errors.main = "Payment error. Please try again.";
      form._errors.payment = true;
    }

    form = form;
  }

  const payment_canceled = (system, data) => {
    form._errors.payment_canceled = true;
    form._errors.main = "Your payment was canceled.";
    loading = false;
  }

  const load_payment = async () => {
    const [status, data] = await api.get("/api/product", { product_id: config.product.id });
    console.log("DATA", data, "STATUS", status);

    if(status === 200) {
      if(params.status === "finished") {
        // this is a payment like Stripe that does a redirect
        product = data;
        payment_finished("stripe", {});
        load_defer.resolve();
      } else {
        // this is most likely because they paid but came back,
        // bounce to the root and hope it doesn't make a loop
        push("/");
      }
    } else if(status === 402) {
      // we EXPECT a 402 here, since it's the payment page
      product = data.course;

      if(params.status === "finished") {
        // shouldn't get finished and also have a failed
        // payment so reset here
        await push("/payment/");
      } else if(data.payment) {
        // this means they paid but it was invalidated, or
        // or this is a stripe payment and it needs to be
        // redone again
        payment_error(data.payment.system, data);
      }

      load_defer.resolve();
    } else {
      console.error(status, data);
    }
  }

  const reset_payment = async () => {
    // stupid but kind of the only way to pull this off
    product = {};
    loading = false;
    payment_clicked = false;
    discount = 0;

    form = {
      paid: false,
      tos_agree: false,
      _valid: false,
      _errors: {}
    }

    load_defer = defer();
    await load_payment();
  }

  const make_choice = (stripe, paypal) => {
    payment_clicked = true;
    stripe_active = stripe;
    paypal_active = paypal;
  }

  onMount(load_payment);
</script>

<style>
  card#paypal-warning {
    max-width: var(--width-card);
    min-width: var(--width-card);
  }

  card#paypal-warning middle {
    height: 100%;
  }

  card#paypal-warning top {
    text-align: center;
  }

  invoice-totals > table {
    border-radius: 0;
    border: 0px;
    border-top: 1px solid var(--value7);
    width: 100%;
  }

  invoice-totals > table tr {
    background-color: unset;
  }

  invoice-totals > table tr th {
    text-align: left;
    font-weight: normal;
  }

  invoice-totals > table tr td {
    text-align: right;
  }

  invoice-totals > table tr#total {
    border-top: 1px solid var(--value7);
  }

  invoice-totals > table tr#total th {
    font-weight: bold;
    font-size: 1.1em;
  }

  card.error top {
    background-color: var(--color-info);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 1rem;
  }

  card.error middle {
    font-size: 1.5em;
    padding-top: 1rem;
    padding-bottom: 1rem;
  }

  invoice-item {
    padding-top: 1.3rem;
  }

  invoice-discount {
    display: flex;
  }

  payment {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    min-height: calc(100vh - var(--fixed-header-height) - var(--fixed-footer-height));
    width: 100%;
  }

  payment > left,
  payment > right {
    width: 50%;
    display: flex;
    flex-direction: column;
    padding: 1rem;
    padding-top: 1.3rem;
    min-height: min-content;
  }

  payment > right {
    background-color: var(--color-bg-tertiary);
    border-left: 1px solid var(--color-bg-secondary);
  }

  payment > left {
    justify-content: flex-start;
    flex-direction: row-reverse;
  }

  payment > right invoice {
    max-width: calc(var(--width-content) / 2);
  }

  payment > left info {
    display: flex;
    flex-direction: column;
    max-width: calc(var(--width-content) / 2);
  }

  payment > left info product-info {
    display: block;
  }

  .pay-button {
    width: 100%;
    min-width: 100%;
    max-width: 100%;
  }

  @media only screen and (max-width: 800px) {
    payment {
      width: 100%;
      flex-direction: column-reverse;
      justify-content: flex-end;
    }

    payment > right {
      width: 100%;
      align-content: center;
      justify-content: center;
    }

    payment > right invoice {
      align-self: center;
    }

    payment > left info {
      display: flex;
      align-self: center;
      flex-direction: column-reverse;
    }

    payment > left {
      width: 100%;
      max-width: unset;
      min-width: unset;
      box-shadow: unset;
      align-content: center;
      justify-content: center;
    }
  }
</style>

<Layout horizontal={true} authenticated={true} fullwidth={ true }>
  <payment>
    <left>
      <info>
        {#if !payment_clicked && !form.paid}
          <product-info>
            <h1>Product Info Here</h1>
          </product-info>
        {/if}
      {#await load_defer}
        <Spinner />
      {:then}
        {#if form.paid}
          <div>
            <h1>Payment Accepted!</h1>
            <p>Thank you for your purchase, and welcome to my
              course! Be sure to join the Discord server when
              you get a chance.  Details are available once
              you <b>click this button</b>:
            </p>

              <button type="button" data-testid="get-started"
                      on:click|preventDefault={ () => push("/") }>Get Started</button>
          </div>
        {:else if form._errors.main}
          <div>
            <card class="error">
              <top data-testid="payment-error"><h1>Payment Error</h1></top>
              <middle>
                <b>{ form._errors.main }</b>
                <br>
                <span>
                {#if form._errors.failed_payment}
                    There was an error validating your payment.
                    Please contact support to investigate why it failed and check your credit card or paypal to confirm the amount was correct and the payment actually finished.
                {:else if form._errors.instrument_declined}
                    Instrument declined. Check that <b>all fields
                      are filled out correctly.</b>  Paypal also
                    adds fields without labeling them so look
                    for empty fields like <b>Street Address</b>.
                {:else if form._errors.payment}
                    Please try again and confirm that
                    the payment didn't actually process on your
                    side.
                {:else if form._errors.payment_canceled}
                    Payment was canceled, either by you or by
                    the payment processor. Plase try again.
                {/if}
                  You can also email <a href="mailto:help@learnjsthehardway.com">help@learnjsthehardway.com</a> to ask for help.
                </span>
              </middle>
              <bottom>
                <button-group>
                  <button data-testid="try-again" type="button" on:click|preventDefault={ reset_payment }>Try Again</button>
                </button-group>
              </bottom>
            <card>
          </div>
        {:else}
          <div>

            {#if config.fake_payments}
              <h3 class="center">Fake Payment Buttons</h3>
              <FakePayment
                on:finished={ (ev) => payment_finished("fake", ev.detail) }
                on:error={ (ev) => payment_error("fake", ev.detail) }
                on:canceled={ (ev) => payment_canceled("fake", ev.detail) }
                />
            {:else}
              {#if paypal_active}
                <h3 class="center">Select your Payment Method</h3>
                <Paypal
                  product={ product }
                  credit_card={ true }
                  on:click={ () => make_choice(false, true) }
                  on:loading={ () => loading = true }
                  on:finished={ (ev) => payment_finished("paypal", ev.detail) }
                  on:error={ (ev) => payment_error("paypal", ev.detail) }
                  on:canceled={ (ev) => payment_canceled("paypal", ev.detail) }
                  />
              {/if}

              {#if stripe_active}
                <Stripe
                  on:click={ () => make_choice(true, false) }
                  on:loading={ () => loading = true }
                  on:finished={ (ev) => payment_finished("stripe", ev.detail) }
                  on:error={ (ev) => payment_error("stripe", ev.detail) }
                  on:canceled={ (ev) => payment_canceled("stripe", ev.detail) }
                  />
                <br>
                <a on:click|preventDefault={() => make_choice(false, true)}>
                  <button class="pay-button" type="button">
                    Use Paypal Instead.
                  </button>
                </a>
              {:else}
                <br>
                <a on:click|preventDefault={() => make_choice(true, false)}>
                  <button class="pay-button" type="button">Hate Paypal? Use Stripe Instead!</button>
                </a>
              {/if}
            {/if}
          </div>
        {/if}
      {/await}
      </info>
    </left>
    <right>
      <invoice>
        <invoice-item class="horizontal">
          <Icon name="book" /> <b>{ product.title }</b>
        </invoice-item>

        <invoice-totals>
          <table>
            <tr><th>{ product.description }</th><td>{product.currency_symbol}{ product.price }</td></tr>

            {#if discount > 0}
              <tr><th>Discount</th><td>{ discount }</td></tr>
            {/if}

            <tr><th>Subtotal</th><td>{product.currency_symbol}{ product.price }</td></tr>
            <tr id="total"><th>Total ({product.currency})</th>
              <td>{product.currency_symbol}{ product.price }</td>
            </tr>
          </table>
        </invoice-totals>

        <br><hr>
        <p>Thank you for purchasing <b>Learn JavaScript the Hard Way.</b> If you have problems with the purchase please email me at <a href="mailto:payments@learnjsthehardway.com">payments@learnjsthehardway.com</a> and tell what went wrong.</p>
      </invoice>
    </right>
  </payment>
</Layout>
