<template>
	<div class="billing-payment-methods-container">
		<n-card class="payment-methods-card">
			<ObjectList :options="options" />
		</n-card>
	</div>
</template>
<script setup>
import { defineAsyncComponent, h, computed, getCurrentInstance } from 'vue';
import { NCard } from 'naive-ui';
import ObjectList from '../components/ObjectList.vue';
import { Badge, FeatherIcon, Tooltip } from 'jingrow-ui';
import { toast } from 'vue-sonner';
import { confirmDialog, renderDialog, icon } from '../utils/components';

const instance = getCurrentInstance();
const $t = instance?.appContext.config.globalProperties.$t || ((key) => key);
const $team = instance?.appContext.config.globalProperties.$team;

const props = defineProps(['tab']);

const options = computed(() => {
	return {
		pagetype: 'Stripe Payment Method',
		fields: [
			'name',
			'is_default',
			'expiry_month',
			'expiry_year',
			'brand',
			'stripe_mandate_id'
		],
		emptyStateMessage: $t('No cards added'),
		columns: [
			{
				label: $t('Card Name'),
				fieldname: 'name_on_card'
			},
			{
				label: $t('Card'),
				fieldname: 'last_4',
				width: 1.5,
				format(value) {
					return `•••• ${value}`;
				},
				prefix: row => {
					return cardBrandIcon(row.brand);
				},
				suffix(row) {
					if (row.is_default) {
						return h(
							Badge,
							{
								theme: 'green'
							},
							() => $t('Default')
						);
					}
				}
			},
			{
				label: $t('Expiry Date'),
				width: 0.5,
				format(value, row) {
					return `${row.expiry_month}/${row.expiry_year}`;
				}
			},
			{
				label: $t('Authorization'),
				type: 'Component',
				width: 1,
				align: 'center',
				component({ row }) {
					if (row.stripe_mandate_id) {
						return h(FeatherIcon, {
							name: 'check-circle',
							class: 'h-4 w-4 text-green-600'
						});
					}
				}
			},
			{
				label: '',
				type: 'Component',
				align: 'right',
				component({ row }) {
					if (row.is_default && row.stripe_payment_method) {
						return h(
							Tooltip,
							{
								text: $t('This card failed to pay last time. Please use another card.')
							},
							() =>
								h(FeatherIcon, {
									name: 'alert-circle',
									class: 'h-4 w-4 text-red-600'
								})
						);
					}
				}
			},
			{
				label: '',
				fieldname: 'creation',
				type: 'Timestamp',
				align: 'right'
			}
		],
		rowActions: ({ listResource, row }) => {
			return [
				{
					label: $t('Set as Default'),
					onClick: () => {
						toast.promise(
							listResource.runDocMethod.submit({
								method: 'set_default',
								name: row.name
							}),
							{
								loading: $t('Setting as default...'),
								success: $t('Default card set'),
								error: $t('Failed to set default card')
							}
						);
					},
					condition: () => !row.is_default
				},
				{
					label: $t('Remove'),
					onClick: () => {
						if (row.is_default && $team.pg.payment_mode === 'Card') {
							toast.error($t('Cannot remove default card'));
							return;
						}
						confirmDialog({
							title: $t('Remove Card'),
							message: $t('Are you sure you want to remove this card?'),
							onSuccess: ({ hide }) => {
								toast.promise(
									listResource.delete.submit(row.name, {
										onSuccess() {
											hide();
										}
									}),
									{
										loading: $t('Removing card...'),
										success: $t('Card removed'),
										error: error =>
											error.messages?.length
												? error.messages.join('\n')
												: error.message || $t('Failed to remove card')
									}
								);
							}
						});
					}
				}
			];
		},
		orderBy: 'creation desc',
		primaryAction() {
			return {
				label: $t('Add Card'),
				slots: {
					prefix: icon('plus')
				},
				onClick: () => {
					let StripeCardDialog = defineAsyncComponent(() =>
						import('../components/StripeCardDialog.vue')
					);
					renderDialog(StripeCardDialog);
				}
			};
		}
	};
});

function cardBrandIcon(brand) {
	let component = {
		'master-card': defineAsyncComponent(() =>
			import('@/components/icons/cards/MasterCard.vue')
		),
		visa: defineAsyncComponent(() =>
			import('@/components/icons/cards/Visa.vue')
		),
		amex: defineAsyncComponent(() =>
			import('@/components/icons/cards/Amex.vue')
		),
		jcb: defineAsyncComponent(() =>
			import('@/components/icons/cards/JCB.vue')
		),
		generic: defineAsyncComponent(() =>
			import('@/components/icons/cards/Generic.vue')
		),
		'union-pay': defineAsyncComponent(() =>
			import('@/components/icons/cards/UnionPay.vue')
		)
	}[brand || 'generic'];

	return h(component, { class: 'h-4 w-6' });
}
</script>

<style scoped>
.billing-payment-methods-container {
	padding: 24px;
	max-width: 1400px;
	margin: 0 auto;
}

.payment-methods-card {
	border-radius: 12px;
	box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
}

@media (max-width: 768px) {
	.billing-payment-methods-container {
		padding: 16px;
	}
}
</style>