/* eslint-disable ts/strict-boolean-expressions */
import { computed } from 'vue'

export interface CalendarEvent {
	title: string
	description?: string
	location?: string
	startDate: Date | string
	endDate?: Date | string
}

export type CalendarProvider = 'google' | 'apple' | 'outlook' | 'outlookcom' | 'yahoo' | 'ics'

export function useAddToCalendar(event: CalendarEvent) {
	// Parse dates if they're strings
	const parseDate = (date: Date | string): Date => {
		return typeof date === 'string' ? new Date(date) : date
	}

	const eventStartDate = parseDate(event.startDate)

	// Calculate end date if not provided (45 minutes after start)
	const calculateEndDate = (): Date => {
		if (event.endDate !== undefined) {
			return parseDate(event.endDate)
		}
		const endDate = new Date(eventStartDate)
		endDate.setMinutes(endDate.getMinutes() + 45)
		return endDate
	}

	const eventEndDate = calculateEndDate()

	// Check if location is a URL
	const isUrl = (text?: string): boolean => {
		if (!text || text.length === 0) {
			return false
		}
		return /^https?:\/\/.+/.test(text.trim())
	}

	const locationIsUrl = isUrl(event.location)

	// Format date to YYYYMMDDTHHMMSS format for calendar URLs
	const formatDate = (date: Date): string => {
		const year = date.getFullYear()
		const month = String(date.getMonth() + 1).padStart(2, '0')
		const day = String(date.getDate()).padStart(2, '0')
		const hours = String(date.getHours()).padStart(2, '0')
		const minutes = String(date.getMinutes()).padStart(2, '0')
		const seconds = String(date.getSeconds()).padStart(2, '0')
		return `${year}${month}${day}T${hours}${minutes}${seconds}`
	}

	// Format date to ISO format for Outlook
	const formatDateISO = (date: Date): string => {
		return `${date.toISOString().replace(/[-:]/g, '').split('.')[0]}Z`
	}

	// Generate ICS file content
	const generateICS = (): string => {
		const startDate = formatDate(eventStartDate)
		const endDate = formatDate(eventEndDate)
		const timestamp = formatDate(new Date())

		const icsContent = [
			'BEGIN:VCALENDAR',
			'VERSION:2.0',
			'PRODID:-//Add to Calendar//EN',
			'CALSCALE:GREGORIAN',
			'METHOD:PUBLISH',
			'BEGIN:VEVENT',
			`UID:${timestamp}@addtocalendar`,
			`DTSTAMP:${timestamp}`,
			`DTSTART:${startDate}`,
			`DTEND:${endDate}`,
			`SUMMARY:${event.title}`,
		]

		if (event.description && event.description.length > 0) {
			// ICS descriptions need special handling of newlines and character limits
			const description = event.description.replace(/\n/g, '\\n')
			icsContent.push(`DESCRIPTION:${description}`)
		}

		if (event.location && event.location.length > 0) {
			icsContent.push(`LOCATION:${event.location}`)
			// If location is a URL, also add it as the URL field
			if (locationIsUrl) {
				icsContent.push(`URL:${event.location}`)
			}
		}

		icsContent.push('STATUS:CONFIRMED', 'SEQUENCE:0', 'END:VEVENT', 'END:VCALENDAR')

		return icsContent.join('\r\n')
	}

	// Generate Google Calendar URL
	const googleUrl = computed(() => {
		const params = new URLSearchParams({
			action: 'TEMPLATE',
			text: event.title,
			dates: `${formatDateISO(eventStartDate)}/${formatDateISO(eventEndDate)}`,
		})

		if (event.description && event.description.length > 0) {
			params.append('details', event.description)
		}

		if (event.location && event.location.length > 0) {
			params.append('location', event.location)
		}

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

	// Generate Outlook Web URL
	const outlookWebUrl = computed(() => {
		const params = new URLSearchParams({
			path: '/calendar/action/compose',
			rru: 'addevent',
			subject: event.title,
			startdt: eventStartDate.toISOString(),
			enddt: eventEndDate.toISOString(),
		})

		if (event.description && event.description.length > 0) {
			params.append('body', event.description)
		}

		if (event.location && event.location.length > 0) {
			params.append('location', event.location)
		}

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

	// Generate Outlook Office 365 URL
	const outlookUrl = computed(() => {
		const params = new URLSearchParams({
			path: '/calendar/action/compose',
			rru: 'addevent',
			subject: event.title,
			startdt: eventStartDate.toISOString(),
			enddt: eventEndDate.toISOString(),
		})

		if (event.description && event.description.length > 0) {
			params.append('body', event.description)
		}

		if (event.location && event.location.length > 0) {
			params.append('location', event.location)
		}

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

	// Generate Yahoo Calendar URL
	const yahooUrl = computed(() => {
		const duration = Math.floor((eventEndDate.getTime() - eventStartDate.getTime()) / 1000 / 60) // Duration in minutes

		const params = new URLSearchParams({
			v: '60',
			title: event.title,
			st: formatDateISO(eventStartDate),
			dur: duration.toString(),
		})

		if (event.description && event.description.length > 0) {
			params.append('desc', event.description)
		}

		if (event.location && event.location.length > 0) {
			params.append('in_loc', event.location)
		}

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

	// Get calendar URL or file based on provider
	const getCalendarUrl = (provider: CalendarProvider): string => {
		switch (provider) {
			case 'google':
				return googleUrl.value
			case 'apple':
			case 'ics':
				// For Apple and ICS, we'll trigger a download
				return ''
			case 'outlook':
				return outlookUrl.value
			case 'outlookcom':
				return outlookWebUrl.value
			case 'yahoo':
				return yahooUrl.value
			default:
				return ''
		}
	}

	// Download ICS file
	const downloadICS = (filename = 'event.ics') => {
		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 = filename
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		URL.revokeObjectURL(link.href)
	}

	// Add to calendar action
	const addToCalendar = (provider: CalendarProvider) => {
		if (provider === 'apple' || provider === 'ics') {
			downloadICS()
		} else {
			const url = getCalendarUrl(provider)
			if (url) {
				window.open(url, '_blank', 'noopener,noreferrer')
			}
		}
	}

	return {
		googleUrl,
		outlookUrl,
		outlookWebUrl,
		yahooUrl,
		generateICS,
		downloadICS,
		getCalendarUrl,
		addToCalendar,
	}
}
