<script setup lang="ts">
import type { AddToCalendarEvent } from '@bagelink/vue'
import { Btn, Dropdown, ListItem } from '@bagelink/vue'
import { computed } from 'vue'

interface Props {
	event: AddToCalendarEvent
	google?: boolean
	apple?: boolean
	outlook?: boolean
	office365?: boolean
	yahoo?: boolean
	ics?: boolean
}

const props = defineProps<Props>()

// Check if any calendar prop was explicitly passed
const hasExplicitCalendars = computed(() => props.google !== undefined
	|| props.apple !== undefined
	|| props.outlook !== undefined
	|| props.office365 !== undefined
	|| props.yahoo !== undefined
	|| props.ics !== undefined
)

const allCalendars = [
	{
		name: 'Google Calendar',
		icon: 'google',
		action: 'google',
		color: '#EA4335', // Google Red
		prop: 'google' as const,
	},
	{
		name: 'Apple Calendar',
		icon: 'apple',
		action: 'apple',
		color: '#000000', // Apple Black
		prop: 'apple' as const,
	},
	{
		name: 'Outlook',
		icon: 'windows',
		action: 'outlook',
		color: '#0072C6', // Outlook Blue
		prop: 'outlook' as const,
	},
	{
		name: 'Office 365',
		icon: 'microsoft',
		action: 'office365',
		color: '#EA3E23', // Office 365 Orange/Red
		prop: 'office365' as const,
	},
	{
		name: 'Yahoo Calendar',
		icon: 'yahoo',
		action: 'yahoo',
		color: '#6001D2', // Yahoo Purple
		prop: 'yahoo' as const,
	},
	{
		name: 'Calendar (ICS file)',
		icon: 'calendar',
		action: 'ics',
		color: '#96A2B4',
		prop: 'ics' as const,
	},
]

// Filter calendars based on enabled props
const availableCalendars = computed(() => {
	// If no calendar props were passed, show all
	if (!hasExplicitCalendars.value) {
		return allCalendars
	}

	// Filter to only show calendars that are explicitly truthy
	const filtered = allCalendars.filter(cal => props[cal.prop] === true)

	// If none are enabled, default to showing all
	return filtered.length > 0 ? filtered : allCalendars
})

// Check if only one calendar is available
const isSingleCalendar = computed(() => availableCalendars.value.length === 1)

// Get the single calendar if only one is available
const singleCalendar = computed(() => isSingleCalendar.value ? availableCalendars.value[0] : null
)

// Format date to YYYYMMDDTHHMMSS format for calendar links
function formatDateTime(date: Date | string): string {
	const d = typeof date === 'string' ? new Date(date) : date
	return `${d.toISOString().replace(/[-:]/g, '').split('.')[0]}Z`
}

// Format date to YYYY-MM-DDTHH:mm:ss format for Outlook
function formatOutlookDateTime(date: Date | string): string {
	const d = typeof date === 'string' ? new Date(date) : date
	return d.toISOString().split('.')[0]
}

// Generate Google Calendar URL
const googleCalendarUrl = computed(() => {
	const params = new URLSearchParams({
		action: 'TEMPLATE',
		text: props.event.title,
		dates: `${formatDateTime(props.event.startTime)}/${formatDateTime(props.event.endTime)}`,
		details: props.event.description || '',
		location: props.event.location || '',
	})

	if (props.event.url) {
		params.set('details', `${props.event.description || ''}\n\n${props.event.url}`)
	}

	return `https://calendar.google.com/calendar/render?${params.toString()}`
})

// Generate Outlook/Office 365 URL
const outlookUrl = computed(() => {
	const params = new URLSearchParams({
		path: '/calendar/action/compose',
		rru: 'addevent',
		subject: props.event.title,
		startdt: formatOutlookDateTime(props.event.startTime),
		enddt: formatOutlookDateTime(props.event.endTime),
		body: props.event.description || '',
		location: props.event.location || '',
	})

	return `https://outlook.live.com/calendar/0/deeplink/compose?${params.toString()}`
})

// Generate Office 365 URL
const office365Url = computed(() => {
	const params = new URLSearchParams({
		path: '/calendar/action/compose',
		rru: 'addevent',
		subject: props.event.title,
		startdt: formatOutlookDateTime(props.event.startTime),
		enddt: formatOutlookDateTime(props.event.endTime),
		body: props.event.description || '',
		location: props.event.location || '',
	})

	return `https://outlook.office.com/calendar/0/deeplink/compose?${params.toString()}`
})

// Generate Yahoo Calendar URL
const yahooUrl = computed(() => {
	const params = new URLSearchParams({
		v: '60',
		title: props.event.title,
		st: formatDateTime(props.event.startTime),
		et: formatDateTime(props.event.endTime),
		desc: props.event.description || '',
		in_loc: props.event.location || '',
	})

	return `https://calendar.yahoo.com/?${params.toString()}`
})

// Generate ICS file content for Apple Calendar and other clients
function generateICS(): string {
	const icsContent = [
		'BEGIN:VCALENDAR',
		'VERSION:2.0',
		'PRODID:-//Add to Calendar//EN',
		'BEGIN:VEVENT',
		`UID:${Date.now()}@addtocalendar`,
		`DTSTAMP:${formatDateTime(new Date())}`,
		`DTSTART:${formatDateTime(props.event.startTime)}`,
		`DTEND:${formatDateTime(props.event.endTime)}`,
		`SUMMARY:${props.event.title}`,
		props.event.description ? `DESCRIPTION:${props.event.description.replace(/\n/g, '\\n')}` : '',
		props.event.location ? `LOCATION:${props.event.location}` : '',
		props.event.url ? `URL:${props.event.url}` : '',
		'END:VEVENT',
		'END:VCALENDAR',
	].filter(Boolean).join('\r\n')

	return icsContent
}

// Download ICS file for Apple Calendar and generic calendar apps
function downloadICS() {
	const icsContent = generateICS()
	const blob = new Blob([icsContent], { type: 'text/calendar;charset=utf-8' })
	const link = document.createElement('a')
	link.href = URL.createObjectURL(blob)
	link.download = `${props.event.title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.ics`
	document.body.appendChild(link)
	link.click()
	document.body.removeChild(link)
	URL.revokeObjectURL(link.href)
}

function handleCalendarClick(type: string) {
	switch (type) {
		case 'google':
			window.open(googleCalendarUrl.value, '_blank')
			break
		case 'outlook':
			window.open(outlookUrl.value, '_blank')
			break
		case 'office365':
			window.open(office365Url.value, '_blank')
			break
		case 'yahoo':
			window.open(yahooUrl.value, '_blank')
			break
		case 'apple':
		case 'ics':
			downloadICS()
			break
	}
}
</script>

<template>
	<Btn
		v-if="isSingleCalendar && singleCalendar" :icon="singleCalendar.icon" color="white"
		class="inline-block calendar-btn" :flat="false" :style="{ '--bgl-text-color': singleCalendar.color }"
		@click="handleCalendarClick(singleCalendar.action)"
	>
		Add to {{ singleCalendar.name }}
	</Btn>

	<!-- Multiple calendars: show dropdown -->
	<Dropdown
		v-else-if="availableCalendars.length > 1" value="Add to Calendar" icon="calendar" color="white"
		class="inline-block" :flat="false"
	>
		<ListItem
			v-for="calendar in availableCalendars" :key="calendar.action" :icon="calendar.icon" :thin="true"
			class="txt16" :style="{ '--bgl-text-color': '#000000', '--bgl-primary': calendar.color }"
			@click="handleCalendarClick(calendar.action)"
		>
			{{ calendar.name }}
		</ListItem>
	</Dropdown>
</template>

<style>
.calendar-btn .bgl_icon-font {
  color: var(--bgl-text-color);
}
</style>
