<script setup>
import { ref, defineProps } from 'vue';
import { SessionUser } from "@/components/session/token/SessionUser.vue";
import { StripeModule } from "@/components/stripe/StripeModule.vue";

const props = defineProps({
  departmentId: {
    type: Number,
    required: true,
  },
  label: {
    type: String,
    default: 'Næste',
  },
  order_id: {
    type: Number,
    required: true,
  },
  order_items: {
    type: Array,
    required: true,
  },
});

import { Colors } from "@/ThemeConfig.vue";
import NextStep from "@/components/forms/department/pos/buttons/NextStep.vue";
import PrintInvoiceFromOrderItems from "@/components/forms/department/pos/buttons/PrintInvoiceFromOrderItems.vue";

// Readers variables
const readers = ref([]);
const isLoading = ref(false);
const error = ref(null);
const isReady = ref(false);
const selectedReader = ref(null);
const isReaderSelected = ref(false);
const isReadersLoading = ref(false);

const tax_rates = ref([
  { id: 1, display_name: 'Dansk kunde', percentage: 25 },
  { id: 2, display_name: 'EU kunde', percentage: 0 },
]);

const selectedTaxRate = ref(tax_rates.value[0].id);

const getTaxRatePercentage = (taxRateId) => {
  const taxRate = tax_rates.value.find(rate => rate.id === taxRateId);
  return taxRate ? taxRate.percentage : 0;
}

const isReaderConnected = (reader) => {
  return reader.status === 'online';
};
const isReaderAvailable = (reader) => {
  if (!isReaderConnected(reader)) {
    return false;
  }
  // If the action status is available, the reader is available
  if (getReaderStatus(reader) === 'Available') {
    return true;
  }
  return (reader.action === null || reader.action === undefined || reader.action === "")
};
const getAvailableReaders = () => {
  return readers.value.filter(isReaderAvailable);
}
const attemptAutomaticReaderSelection = (readers) => {
  const availableReaders = readers.filter(isReaderAvailable);
  if (availableReaders.length > 0) {
    selectedReader.value = availableReaders[0];
    isReaderSelected.value = true;
  } else {
    selectedReader.value = null;
    isReaderSelected.value = false;
  }
};

const getStripeReaders = async () => {
  isReadersLoading.value = true;
  SessionUser.request(
      '/modules/stripe/department/terminal/readers',
      'GET',
      {
        id: props.departmentId,
      },
  ).then((response) => {
    console.log('Response from Stripe:', response.data.data.data);
    if (response.status === 200) {
      isReadersLoading.value = false;
      isReady.value = true;
      readers.value = response.data.data.data;
      // Attempt to automatically select a reader
      attemptAutomaticReaderSelection(readers.value);
      return response;
    } else {
      isReadersLoading.value = false;
      error.value = response.data.data.message;
      console.error('Error fetching readers:', response);
    }
  }).catch((error) => {
    isReadersLoading.value = false;
    error.value = error.message;
    console.error('Error fetching readers:', error);
  })
}

const onClick = () => {
  console.log('Stripe payment initiated', selectedReader.value);
  isLoading.value = true;
  // Start the payment process with the selected reader
  StripeModule.paymentIntents.createPaymentIntent(selectedReader.value, props.order_id, getTaxRatePercentage(selectedTaxRate.value))
      .then((response) => {
        if (response.status === 200) {
          console.log('Payment intent created successfully:', response.data.data);
          // Load the payment intent
          StripeModule.paymentIntents.getPaymentIntent(props.order_id);
        } else {
          // Handle error
          error.value = response.data.message;
          console.error('Error creating payment intent:', response);
        }
        isLoading.value = false;
      })
      .catch((error) => {
        console.error('Error creating payment intent:', error);
        // Handle error
        error.value = error.message;
        isLoading.value = false;
      });
}

const isAnyReadersUnavailable = () => {
  return readers.value.some(reader => !isReaderAvailable(reader));
}

const isAnyReadersAvailable = () => {
  return readers.value.some(reader => isReaderAvailable(reader));
}

// This will return "Available", "Disconnected", "Busy", or "Unknown"
const getReaderStatus = (reader) => {
  if (reader.status === 'online') {
    return 'Available';
  } else if (reader.status === 'offline') {
    return 'Disconnected';
  } else if (reader.status === 'busy') {
    return 'Busy';
  } else {
    return 'Unknown ( ' + reader.status + ' )';
  }
}

getStripeReaders();
StripeModule.paymentIntents.getPaymentIntent(props.order_id);
// Check if the readers are available every 5 seconds
setInterval(() => {
  if (isReady.value) {
    getStripeReaders();
  }
}, 5000);

// Reload the payment intent every 5 seconds
setInterval(() => {
  if (isReady.value) {
    StripeModule.paymentIntents.getPaymentIntent(props.order_id);
  }
}, 5000);

const loadingDeleteButton = ref(false);

const setDeleteButtonLoading = (isLoading) => {
  console.log('Loading delete button:', isLoading);
    loadingDeleteButton.value = !!isLoading;
}

const onClickCancelPaymentIntent = () => {
  console.log('Delete payment intent');
  loadingDeleteButton.value = true;
  StripeModule.paymentIntents.deletePaymentIntent(props.order_id)
      .then(async (response) => {
        if (response.status === 200) {
          console.log('Payment intent deleted successfully:', response.data.data);
          // Unset the payment intent
          StripeModule.paymentIntents.paymentIntent.value = null;
          // Reload the payment intent
          StripeModule.paymentIntents.getPaymentIntent(props.order_id).finally(() => {
            getStripeReaders().finally(() => {
              setDeleteButtonLoading(false);
            })
          });
        } else {
          console.error('Error deleting payment intent:', response);
          setDeleteButtonLoading(false);
        }
      })
      .catch((error) => {
        console.error('Error deleting payment intent:', error);
        setDeleteButtonLoading(false);
      });
}

const showPaymentDetails = (paymentIntent) => {
  console.log('Payment details:', paymentIntent);
  let metadata = '';
  for (const key in paymentIntent.metadata) {
    if (paymentIntent.metadata.hasOwnProperty(key)) {
      metadata += `
      ${key}: ${paymentIntent.metadata[key]}`;
    }
  }
  // Show payment details in a modal or alert
  let details = `
    Payment Intent ID: ${paymentIntent.id}
    Amount Received: ${paymentIntent.amount_received / 100} ${paymentIntent.currency}
    Status: ${paymentIntent.status}
    Payment Method: ${paymentIntent.payment_method_types[0]}
    Created At: ${new Date(paymentIntent.created * 1000).toLocaleString()}
    Metadata: ${metadata}
  `;
  alert(details);
}

</script>

<template>
  <div class="columns">
    <!-- Complete transaction, if the payment intent has been captured -->
    <template v-if="StripeModule.paymentIntents.isPaymentIntentAmountReceived(StripeModule.paymentIntents.paymentIntent.value)">
      <div class="column">
        <NextStep
            class="is-fullwidth"
            label="Gennemfør"
        />
      </div>
    </template>
    <div class="column">
    <!-- Error state -->
    <template v-if="error">
      <button class="button is-danger" @click="getAvailableReaders">
        <span class="icon is-small">
          <i class="fas fa-exclamation-triangle"></i>
        </span>
        <span>{{ error }}</span>
      </button>
    </template>
    <!-- Ready state, no readers -->
    <template v-else-if="readers.length === 0 && isReady">
      <button class="button is-warning" @click="getAvailableReaders">
        <span class="icon is-small">
          <i class="fas fa-exclamation-triangle"></i>
        </span>
        <span>No readers available</span>
      </button>
    </template>
    <!-- Ready state, readers available -->
    <template v-else-if="readers.length > 0 && isReady && !isLoading && StripeModule.paymentIntents.paymentIntent.value === null">
      <button
          class="button"
          @click="onClick"
          :disabled="!isReaderSelected"
          :style="{ 'background-color': Colors.buttons.success.backgroundColor, 'color': Colors.buttons.success.textColor }"
      >
        <span class="icon is-small">
          <i class="fas fa-credit-card"></i>
        </span>
        <span>{{ props.label }}</span>
      </button>
    </template>
      <!-- Currently processing payment -->
    <template v-else-if="StripeModule.paymentIntents.paymentIntent.value !== null">
      <template v-if="StripeModule.paymentIntents.isPaymentIntentReadyToCapture(StripeModule.paymentIntents.paymentIntent.value)">
        <button
            class="button"
            :style="{ 'background-color': Colors.buttons.success.backgroundColor, 'color': Colors.buttons.success.textColor }"
            @click="StripeModule.paymentIntents.capturePaymentIntent(order_id)"
        >
          <span class="icon is-small">
            <i class="fas fa-credit-card"></i>
          </span>
          <span>Capture payment {{ StripeModule.paymentIntents.getReadyToCapturePaymentAmount(StripeModule.paymentIntents.paymentIntent.value).amount_capturable / 100 }} {{ StripeModule.paymentIntents.getReadyToCapturePaymentAmount(StripeModule.paymentIntents.paymentIntent.value).currency }}</span>
        </button>
      </template>
      <template v-else-if="StripeModule.paymentIntents.isPaymentIntentAmountReceived(StripeModule.paymentIntents.paymentIntent.value) && StripeModule.paymentIntents.paymentIntent.value.status === 'succeeded'">
        <button
            class="button is-text"
            :style="{ 'color': Colors.buttons.success.backgroundColor, 'text-decoration': 'none' }"
            @click="showPaymentDetails(StripeModule.paymentIntents.paymentIntent.value)"
        >
          <span class="icon is-small">
            <i class="fas fa-check"></i>
          </span>
          <span>{{SessionUser.objects.global.language.payment.payment_recieved}} {{ StripeModule.paymentIntents.getReadyToCapturePaymentAmount(StripeModule.paymentIntents.paymentIntent.value).amount_received / 100 }} {{ StripeModule.paymentIntents.getReadyToCapturePaymentAmount(StripeModule.paymentIntents.paymentIntent.value).currency }}</span>
        </button>
      </template>
      <template v-else>
        <button
            class="button"
            :style="{ 'background-color': Colors.buttons.success.backgroundColor, 'color': Colors.buttons.success.textColor }"
            @click="onClick"
        >
          <span class="icon is-small">
            <i class="fas fa-credit-card"></i>
          </span>
          <span>Payment in progress</span>
        </button>
      </template>
    </template>
    <!-- Default state, loading -->
    <template v-else-if="isLoading">
      <button class="button is-loading">
        <span class="icon is-small">
          <i class="fas fa-spinner"></i>
        </span>
        <span>Loading...</span>
      </button>
    </template>
    </div>
    <!-- Reader selection -->
    <div class="column">
      <template v-if="isReady && readers.length > 0 && StripeModule.paymentIntents.paymentIntent.value === null">
        <div class="select">
          <select v-model="selectedReader">
            <option disabled value="">
              <template v-if="isAnyReadersAvailable()">Select a reader</template>
              <template v-else>No available readers</template>
            </option>
            <template v-for="reader of getAvailableReaders()" :key="reader.id">
              <option :value="reader" v-if="isReaderAvailable(reader)">
                {{ reader.label }} ({{ getReaderStatus(reader) }})
              </option>
            </template>
            <!-- Unavailable readers -->
            <template v-if="isAnyReadersUnavailable()">
              <option disabled>Unavailable Readers</option>
              <template v-for="reader of readers" :key="reader.id">
                <option :value="reader" v-if="!isReaderAvailable(reader)" :disabled="true">
                  {{ reader.label }} ({{ getReaderStatus(reader) }})
                </option>
              </template>
            </template>
          </select>
        </div>
      </template>
      <!-- Currently processing payment -->
      <template v-else-if="StripeModule.paymentIntents.paymentIntent.value !== null">
      </template>
      <!-- No readers available -->
      <template v-else-if="readers.length === 0 && isReady">
        <div class="select">
          <select disabled>
            <option>No readers available</option>
          </select>
        </div>
      </template>
    </div>
    <!-- Select tax percentage -->
    <template v-if="StripeModule.paymentIntents.paymentIntent.value === null">
      <div class="column">
        <div class="select">
          <select v-model="selectedTaxRate">
            <template v-for="taxRate in tax_rates" :key="taxRate.id">
              <option :value="taxRate.id">
                {{ taxRate.display_name }} ({{ taxRate.percentage }}% moms)
              </option>
            </template>
          </select>
        </div>
      </div>
    </template>
    <!-- If the payment intent exists, show the delete button -->
    <div class="column">
      <template v-if="StripeModule.paymentIntents.paymentIntent.value !== null && StripeModule.paymentIntents.paymentIntent.value.status !== 'succeeded'">
        <button
            class="button is-danger"
            :class="{ 'is-loading': loadingDeleteButton }"
            @click="onClickCancelPaymentIntent()"
            >
          <span class="icon is-small">
            <i class="fas fa-trash"></i>
          </span>
          <span>Delete Payment Intent</span>
        </button>
      </template>
    </div>
    <!-- Print invoice (if the payment intent has been captured) -->
    <template v-if="StripeModule.paymentIntents.isPaymentIntentAmountReceived(StripeModule.paymentIntents.paymentIntent.value)">
      <div class="column">
        <PrintInvoiceFromOrderItems
            v-bind:order_id="props.order_id"
            v-bind:order-items="props.order_items"
            v-bind:tax_percentage="getTaxRatePercentage(selectedTaxRate)"
            v-bind:paid="true"
        />
      </div>
    </template>
    {{ error }}
  </div>
</template>

<style scoped>

</style>