import { PUBLIC_CALENDAR_API_URL, PUBLIC_CALENDAR_API_KEY } from '$env/static/public';

// Types matching the scheduler microservice API

export interface EventDateTime {
	dateTime?: string; // ISO 8601 datetime (e.g., "2023-06-15T10:00:00Z")
	date?: string; // For all-day events (YYYY-MM-DD format)
	timeZone?: string; // Optional timezone (e.g., "UTC", "America/New_York")
}

export interface Attendee {
	email: string;
	displayName?: string;
	optional?: boolean;
}

export interface EventReminder {
	method: 'email' | 'popup'; // Notification method
	minutes: number; // Minutes before event to send reminder
}

export interface EventReminders {
	useDefault: boolean; // Whether to use the calendar's default reminders
	overrides?: EventReminder[]; // Custom reminders (only used if useDefault is false)
}

export interface CalendarEvent {
	id: string;
	summary: string;
	description?: string;
	location?: string;
	start: EventDateTime;
	end: EventDateTime;
	attendees?: Attendee[];
	reminders?: EventReminders;
	colorId?: string;
	htmlLink?: string;
	created?: string;
	updated?: string;
}

// Google Calendar color IDs and their display values
export const EVENT_COLORS = [
	{ id: '1', name: 'Lavender', bg: 'bg-purple-300', text: 'text-purple-900' },
	{ id: '2', name: 'Sage', bg: 'bg-green-300', text: 'text-green-900' },
	{ id: '3', name: 'Grape', bg: 'bg-violet-400', text: 'text-violet-900' },
	{ id: '4', name: 'Flamingo', bg: 'bg-pink-400', text: 'text-pink-900' },
	{ id: '5', name: 'Banana', bg: 'bg-yellow-300', text: 'text-yellow-900' },
	{ id: '6', name: 'Tangerine', bg: 'bg-orange-400', text: 'text-orange-900' },
	{ id: '7', name: 'Peacock', bg: 'bg-cyan-500', text: 'text-cyan-900' },
	{ id: '8', name: 'Graphite', bg: 'bg-gray-400', text: 'text-gray-900' },
	{ id: '9', name: 'Blueberry', bg: 'bg-blue-500', text: 'text-blue-100' },
	{ id: '10', name: 'Basil', bg: 'bg-emerald-600', text: 'text-emerald-100' },
	{ id: '11', name: 'Tomato', bg: 'bg-red-500', text: 'text-red-100' }
] as const;

export function getEventColor(colorId?: string) {
	return EVENT_COLORS.find((c) => c.id === colorId) ?? null;
}

export interface CreateEventInput {
	id?: string; // Optional custom ID (5-1024 chars, a-v + 0-9 only)
	summary: string;
	description?: string;
	location?: string;
	start: EventDateTime;
	end: EventDateTime;
	attendees?: Attendee[];
	reminders?: EventReminders;
	colorId?: string;
}

export interface UpdateEventInput {
	summary?: string;
	description?: string;
	location?: string;
	start?: EventDateTime;
	end?: EventDateTime;
	attendees?: Attendee[];
	reminders?: EventReminders;
	colorId?: string;
}

export interface ListEventsParams {
	timeMin?: string; // RFC3339 format
	timeMax?: string; // RFC3339 format
	maxResults?: number;
	q?: string; // Search query
}

export interface CalendarError {
	error: string;
	message: string;
}

class CalendarService {
	private baseUrl: string;
	private apiKey: string;

	constructor() {
		this.baseUrl = PUBLIC_CALENDAR_API_URL;
		this.apiKey = PUBLIC_CALENDAR_API_KEY;
	}

	private async request<T>(
		endpoint: string,
		options: RequestInit = {}
	): Promise<{ data?: T; error?: CalendarError }> {
		const url = `${this.baseUrl}${endpoint}`;

		const headers: HeadersInit = {
			'X-API-Key': this.apiKey,
			'Content-Type': 'application/json',
			...options.headers
		};

		try {
			const response = await fetch(url, {
				...options,
				headers
			});

			// Handle 204 No Content (for delete operations)
			if (response.status === 204) {
				return { data: undefined };
			}

			const data = await response.json();

			if (!response.ok) {
				return { error: data as CalendarError };
			}

			return { data: data as T };
		} catch (err) {
			console.error('Calendar API error:', err);
			return {
				error: {
					error: 'NetworkError',
					message: err instanceof Error ? err.message : 'Unknown network error'
				}
			};
		}
	}

	/**
	 * List calendar events with optional filters
	 */
	async listEvents(params: ListEventsParams = {}): Promise<{
		data?: CalendarEvent[];
		error?: CalendarError;
	}> {
		const searchParams = new URLSearchParams();

		if (params.timeMin) searchParams.set('timeMin', params.timeMin);
		if (params.timeMax) searchParams.set('timeMax', params.timeMax);
		if (params.maxResults) searchParams.set('maxResults', params.maxResults.toString());
		if (params.q) searchParams.set('q', params.q);

		const queryString = searchParams.toString();
		const endpoint = `/events${queryString ? `?${queryString}` : ''}`;

		return this.request<CalendarEvent[]>(endpoint);
	}

	/**
	 * Get a single calendar event by ID
	 */
	async getEvent(eventId: string): Promise<{ data?: CalendarEvent; error?: CalendarError }> {
		return this.request<CalendarEvent>(`/events/${eventId}`);
	}

	/**
	 * Create a new calendar event
	 */
	async createEvent(
		input: CreateEventInput
	): Promise<{ data?: CalendarEvent; error?: CalendarError }> {
		return this.request<CalendarEvent>('/events', {
			method: 'POST',
			body: JSON.stringify(input)
		});
	}

	/**
	 * Update an existing calendar event (partial updates supported)
	 */
	async updateEvent(
		eventId: string,
		input: UpdateEventInput
	): Promise<{ data?: CalendarEvent; error?: CalendarError }> {
		return this.request<CalendarEvent>(`/events/${eventId}`, {
			method: 'PUT',
			body: JSON.stringify(input)
		});
	}

	/**
	 * Delete a calendar event
	 */
	async deleteEvent(eventId: string): Promise<{ error?: CalendarError }> {
		return this.request<void>(`/events/${eventId}`, {
			method: 'DELETE'
		});
	}

	/**
	 * Health check for the calendar service
	 */
	async healthCheck(): Promise<{ data?: { status: string }; error?: CalendarError }> {
		return this.request<{ status: string }>('/health');
	}
}

// Export singleton instance
export const calendarService = new CalendarService();

// Export class for testing or custom instances
export { CalendarService };
