<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { useForm, Link } from '@inertiajs/vue3'
import AccountLayout from '@/Layouts/AccountLayout.vue'
import type { PaymentMethod } from '@/types'
import { loadStripe, type Stripe, type StripeElements, type StripeCardElement } from '@stripe/stripe-js'

interface Props {
  paymentMethods: PaymentMethod[]
  defaultPaymentMethod: string | null
  intent: { client_secret: string }
  stripeKey: string
}

defineOptions({ layout: AccountLayout })

const props = defineProps<Props>()

let stripe: Stripe | null = null
let elements: StripeElements | null = null
let cardElement: StripeCardElement | null = null

const isAddingCard = ref(false)
const addCardError = ref<string | null>(null)

const defaultForm = useForm({
  payment_method_id: '',
})

const deleteForm = useForm({
  payment_method_id: '',
})

const showDeleteDialog = ref<boolean>(false)
const deletingMethod = ref<PaymentMethod | null>(null)

function setDefault(id: string): void {
  defaultForm.payment_method_id = id
  defaultForm.post('/billing/payment-methods/default')
}

function openDeleteDialog(pm: PaymentMethod): void {
  deletingMethod.value = pm
  showDeleteDialog.value = true
}

function confirmDelete(): void {
  if (!deletingMethod.value) {
    return
  }

  deleteForm.payment_method_id = deletingMethod.value.id
  deleteForm.delete('/billing/payment-methods/' + deletingMethod.value.id, {
    onSuccess: () => {
      showDeleteDialog.value = false
      deletingMethod.value = null
    },
  })
}

function resolveBrandIcon(brand: string): string {
  const brandMap: Record<string, string> = {
    visa: 'tabler-brand-visa',
    mastercard: 'tabler-brand-mastercard',
    amex: 'tabler-credit-card',
    discover: 'tabler-credit-card',
    diners: 'tabler-credit-card',
    jcb: 'tabler-credit-card',
    unionpay: 'tabler-credit-card',
  }

  return brandMap[brand.toLowerCase()] || 'tabler-credit-card'
}

async function handleAddCard(): Promise<void> {
  if (!stripe || !cardElement) {
    return
  }

  isAddingCard.value = true
  addCardError.value = null

  try {
    const { setupIntent, error } = await stripe.confirmCardSetup(props.intent.client_secret, {
      payment_method: {
        card: cardElement,
      },
    })

    if (error) {
      addCardError.value = error.message || 'An error occurred while adding your card.'
      isAddingCard.value = false
      return
    }

    if (setupIntent?.payment_method) {
      // Submit the payment method ID to the backend
      const addForm = useForm({
        payment_method_id: setupIntent.payment_method as string,
      })

      addForm.post('/billing/payment-methods', {
        onSuccess: () => {
          // Reset the card element
          cardElement?.clear()
        },
        onError: () => {
          addCardError.value = 'Failed to save payment method.'
        },
        onFinish: () => {
          isAddingCard.value = false
        },
      })
    }
  }
  catch (err) {
    console.error('Error adding card:', err)
    addCardError.value = 'An unexpected error occurred.'
    isAddingCard.value = false
  }
}

onMounted(async () => {
  // Load Stripe.js
  stripe = await loadStripe(props.stripeKey)

  if (!stripe) {
    console.error('Failed to load Stripe')
    return
  }

  // Create elements
  elements = stripe.elements()

  // Create card element
  cardElement = elements.create('card', {
    style: {
      base: {
        fontSize: '16px',
        color: 'rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity))',
        '::placeholder': {
          color: 'rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity))',
        },
      },
      invalid: {
        color: 'rgb(var(--v-theme-error))',
      },
    },
  })

  // Mount the card element
  const cardElementContainer = document.getElementById('card-element')
  if (cardElementContainer) {
    cardElement.mount(cardElementContainer)
  }
})
</script>

<template>
  <div>
    <!-- Breadcrumb -->
    <div class="d-flex align-center ga-2 mb-4">
      <Link href="/billing" class="text-decoration-none">
        <VBtn variant="text" size="small" color="primary">
          <VIcon icon="tabler-arrow-left" start />
          Billing
        </VBtn>
      </Link>
      <VIcon icon="tabler-chevron-right" size="16" color="disabled" />
      <span class="text-body-2 text-medium-emphasis">Payment Methods</span>
    </div>

    <div class="text-h4 font-weight-bold mb-6">Payment Methods</div>

    <!-- Payment Methods List -->
    <VCard class="mb-6">
      <VCardTitle>Your Cards</VCardTitle>
      <VCardText>
        <!-- Empty State -->
        <div v-if="paymentMethods.length === 0" class="text-center py-8">
          <VIcon icon="tabler-credit-card-off" size="48" color="disabled" class="mb-4" />
          <div class="text-body-1 text-medium-emphasis mb-2">No payment methods on file</div>
          <div class="text-body-2 text-disabled">
            Payment methods are added automatically during checkout.
          </div>
        </div>

        <!-- Payment Methods -->
        <div v-else class="d-flex flex-column ga-3">
          <VSheet
            v-for="pm in paymentMethods"
            :key="pm.id"
            rounded
            border
            class="pa-4 d-flex align-center justify-space-between"
            :class="pm.is_default ? 'border-primary' : ''"
          >
            <div class="d-flex align-center ga-3">
              <VAvatar
                :icon="resolveBrandIcon(pm.brand)"
                size="40"
                variant="tonal"
                color="primary"
                rounded
              />
              <div>
                <div class="d-flex align-center ga-2">
                  <span class="text-body-1 font-weight-medium text-capitalize">{{ pm.brand }}</span>
                  <span class="text-body-2 text-medium-emphasis">ending in {{ pm.last_four }}</span>
                  <VChip v-if="pm.is_default" color="primary" size="x-small">Default</VChip>
                </div>
                <div class="text-body-2 text-disabled mt-1">
                  Expires {{ pm.exp_month }}/{{ pm.exp_year }}
                </div>
              </div>
            </div>
            <div class="d-flex align-center ga-2">
              <VBtn
                v-if="!pm.is_default"
                variant="tonal"
                color="primary"
                size="small"
                :loading="defaultForm.processing && defaultForm.payment_method_id === pm.id"
                :disabled="defaultForm.processing"
                prepend-icon="tabler-star"
                @click="setDefault(pm.id)"
              >
                Set as Default
              </VBtn>
              <VBtn
                variant="tonal"
                color="error"
                size="small"
                prepend-icon="tabler-trash"
                @click="openDeleteDialog(pm)"
              >
                Remove
              </VBtn>
            </div>
          </VSheet>
        </div>
      </VCardText>
    </VCard>

    <!-- Add New Card -->
    <VCard>
      <VCardTitle>Add a New Card</VCardTitle>
      <VCardText>
        <div class="mb-4">
          <label class="text-body-2 text-medium-emphasis d-block mb-2">Card Information</label>
          <div
            id="card-element"
            class="pa-3 rounded border"
            style="min-height: 40px;"
          />
        </div>

        <VAlert v-if="addCardError" type="error" variant="tonal" class="mb-4">
          {{ addCardError }}
        </VAlert>

        <VBtn
          color="primary"
          :loading="isAddingCard"
          :disabled="isAddingCard"
          @click="handleAddCard"
        >
          <VIcon icon="tabler-plus" start />
          Add Card
        </VBtn>
      </VCardText>
    </VCard>

    <!-- Delete Confirmation Dialog -->
    <VDialog v-model="showDeleteDialog" max-width="450">
      <VCard>
        <VCardTitle class="d-flex align-center ga-2">
          <VIcon icon="tabler-alert-triangle" color="error" />
          Remove Payment Method
        </VCardTitle>
        <VCardText>
          <p class="text-body-1 mb-4">
            Are you sure you want to remove this payment method?
          </p>
          <VSheet
            v-if="deletingMethod"
            rounded
            border
            class="pa-3 d-flex align-center ga-3"
          >
            <VAvatar
              :icon="resolveBrandIcon(deletingMethod.brand)"
              size="36"
              variant="tonal"
              color="primary"
              rounded
            />
            <div>
              <div class="text-body-2 font-weight-medium text-capitalize">
                {{ deletingMethod.brand }} ending in {{ deletingMethod.last_four }}
              </div>
              <div class="text-caption text-disabled">
                Expires {{ deletingMethod.exp_month }}/{{ deletingMethod.exp_year }}
              </div>
            </div>
          </VSheet>

          <VAlert
            v-if="deletingMethod?.is_default"
            type="warning"
            variant="tonal"
            class="mt-4"
          >
            <div class="text-body-2">
              This is your default payment method. Removing it may affect active subscriptions.
            </div>
          </VAlert>
        </VCardText>
        <VCardActions class="pa-4 pt-0">
          <VSpacer />
          <VBtn
            variant="outlined"
            @click="showDeleteDialog = false"
          >
            Cancel
          </VBtn>
          <VBtn
            color="error"
            :loading="deleteForm.processing"
            @click="confirmDelete"
          >
            Remove
          </VBtn>
        </VCardActions>
      </VCard>
    </VDialog>
  </div>
</template>
