<script lang="ts">
  import type { Payment } from "@breeztech/breez-sdk-liquid/web";
  import { satsComma } from "$lib";
  import { getBreezSDK } from "$lib/breez.svelte";
  import Button from "$lib/components/Button.svelte";

  interface CashuPayment {
    txId: string;
    paymentType: "receive" | "send";
    amountSat: number;
    timestamp: number;
    status: string;
  }

  type PaymentLike = Payment | CashuPayment;

  const { payment }: { payment: PaymentLike } = $props();

  const formattedAmt = $derived.by(() => {
    const prefix = payment.paymentType === "receive" ? "+" : "-";
    return `${prefix}${satsComma(payment.amountSat)} sats`;
  });

  const formattedDate = $derived.by(() => {
    const d = new Date(payment.timestamp * 1000);
    return d.toISOString().slice(0, 16).replace("T", " ");
  });

  let isRefunding = $state(false);

  async function refundPayment() {
    if (isRefunding) return;
    isRefunding = true;
    const breezSDK = await getBreezSDK();
    const prepareAddr = await breezSDK.prepareReceivePayment({
      paymentMethod: "bitcoinAddress",
    });
    const receiveRes = await breezSDK.receivePayment({
      prepareResponse: prepareAddr,
    });
    const refundAddress = receiveRes.destination as string;

    try {
      const refundables = await breezSDK.listRefundables();
      let swapAddress: string | undefined;
      if (refundables.length === 1) {
        swapAddress = refundables[0].swapAddress;
      } else {
        swapAddress = refundables.find(
          (r) =>
            r.amountSat === payment.amountSat &&
            Math.abs(r.timestamp - payment.timestamp) < 300
        )?.swapAddress;
      }

      if (!swapAddress) {
        alert("Could not identify refundable swap for this payment.");
        return;
      }

      const fees = await breezSDK.recommendedFees();
      const feeRateSatPerVbyte = fees.economyFee;

      const refundRequest = {
        swapAddress,
        refundAddress,
        feeRateSatPerVbyte,
      } as const;

      try {
        await breezSDK.prepareRefund(refundRequest);
      } catch (err) {
        console.warn(
          "prepareRefund failed (may be expected for some swaps)",
          err
        );
      }

      await breezSDK.refund(refundRequest);
      alert(
        "Refund transaction broadcasted. It may take a moment to appear in history."
      );
    } catch (err) {
      console.error("Refund failed", err);
      alert(`Refund failed: ${err instanceof Error ? err.message : err}`);
    } finally {
      isRefunding = false;
    }
  }
</script>

<div class="item" class:failed={payment.status === "failed"}>
  <div class="info">
    <span class="date">{formattedDate}</span>
    <span class="status">{payment.status}</span>
    {#if payment.paymentType === "receive" && !payment.txId?.startsWith("cashu-")}
      <span class="status">
        {#if (payment as Payment).details.type === "bitcoin"}
          <a href="https://mempool.space/tx/{payment.txId}" target="_blank">
            ...{payment.txId?.slice(-16)}
          </a>
        {:else if (payment as Payment).details.type === "liquid"}
          <a href="https://liquid.network/tx/{payment.txId}" target="_blank">
            ...{payment.txId?.slice(-16)}
          </a>
        {:else if (payment as Payment).details.type === "lightning"}
          <a
            href="https://liquid.network/tx/{payment.details.claimTxId}"
            target="_blank"
          >
            ...{payment.txId?.slice(-16)}
          </a>
        {/if}
      </span>
    {/if}
  </div>

  <span class="amount {payment.paymentType}">{formattedAmt}</span>

  {#if payment.status === "refundable"}
    <Button variant="danger" onclick={refundPayment} disabled={isRefunding}>
      {#if isRefunding}
        Refunding…
      {:else}
        Refund
      {/if}
    </Button>
  {/if}
</div>

<style>
  a {
    color: white;
  }
  .item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.8rem 1rem;
    margin-bottom: 0.5rem;
    border: 2px solid var(--accent-color);
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.3);
    font-family: "Press Start 2P", "VT323", monospace, sans-serif;
  }
  .info {
    display: flex;
    flex-direction: column;
  }
  .amount {
    font-weight: bold;
    text-shadow: 1px 1px 0 #000;
    font-size: 0.8rem;
  }
  .amount.receive {
    color: var(--success-color, #4caf50);
  }
  .amount.send {
    color: var(--error-color, #f44336);
  }
  .status {
    font-size: 0.7rem;
    opacity: 0.8;
  }
  .date {
    font-size: 0.65rem;
    opacity: 0.6;
  }
  .failed {
    border-color: var(--error-color);
    opacity: 0.5;
    transition: opacity 0.2s ease-in-out;
    &:hover {
      opacity: 1;
    }
  }
</style>
