<svelte:options runes={true} />

<script lang="ts">
	import { page } from '$app/stores'
	import { goto } from '$app/navigation'
	import { createQuery } from '@tanstack/svelte-query'
	import { crewQueries } from '$lib/api/queries/crew.queries'
	import { useAcceptInvitation, useRejectInvitation } from '$lib/api/mutations/crew.mutations'
	import { crewStore } from '$lib/stores/crew.store.svelte'
	import Button from '$lib/components/ui/Button.svelte'
	import type { PageData } from './$types'

	interface Props {
		data: PageData
	}

	let { data }: Props = $props()

	// Check if user already has a crew - redirect to crew page
	$effect(() => {
		if (crewStore.isInCrew && !crewStore.isLoading) {
			goto('/crew')
		}
	})

	// Get invitation ID from URL if present
	const selectedInvitationId = $derived($page.url.searchParams.get('invitation'))

	// Query for pending invitations
	const invitationsQuery = createQuery(() => crewQueries.pendingInvitations())

	// Mutations
	const acceptMutation = useAcceptInvitation()
	const rejectMutation = useRejectInvitation()

	// Track which invitation is being processed
	let processingId = $state<string | null>(null)

	// Accept invitation
	async function handleAccept(invitationId: string) {
		processingId = invitationId
		try {
			await acceptMutation.mutateAsync(invitationId)
			// Successfully joined - redirect to crew
			goto('/crew')
		} catch (error) {
			console.error('Failed to accept invitation:', error)
			processingId = null
		}
	}

	// Reject invitation
	async function handleReject(invitationId: string) {
		processingId = invitationId
		try {
			await rejectMutation.mutateAsync(invitationId)
			processingId = null
		} catch (error) {
			console.error('Failed to reject invitation:', error)
			processingId = null
		}
	}

	// Format date
	function formatDate(dateString: string): string {
		return new Date(dateString).toLocaleDateString(undefined, {
			year: 'numeric',
			month: 'short',
			day: 'numeric'
		})
	}

	// Check if invitation is expired
	function isExpired(expiresAt: string): boolean {
		return new Date(expiresAt) < new Date()
	}
</script>

<svelte:head>
	<title>Join Crew | Hensei</title>
</svelte:head>

<div class="join-page">
	<header class="page-header">
		<h1>Join a Crew</h1>
		<p class="description">Accept an invitation to join a crew.</p>
	</header>

	{#if invitationsQuery.isLoading}
		<div class="loading-state">
			<p>Loading invitations...</p>
		</div>
	{:else if invitationsQuery.isError}
		<div class="error-state">
			<p>Failed to load invitations</p>
		</div>
	{:else if !invitationsQuery.data || invitationsQuery.data.length === 0}
		<div class="empty-state">
			<p>You don't have any pending invitations.</p>
			<p class="hint">
				Ask a crew captain or vice captain to send you an invitation.
			</p>
			<Button variant="secondary" onclick={() => goto('/crew')}>
				Go Back
			</Button>
		</div>
	{:else}
		<div class="invitations-list">
			{#each invitationsQuery.data as invitation}
				{@const expired = isExpired(invitation.expiresAt)}
				{@const highlighted = invitation.id === selectedInvitationId}
				{@const crew = invitation.crew}
				{@const invitedBy = invitation.invitedBy}

				{#if crew && invitedBy}
					<div class="invitation-card" class:highlighted class:expired>
						<div class="invitation-header">
							<h2 class="crew-name">{crew.name}</h2>
							{#if crew.gamertag}
								<span class="gamertag">[{crew.gamertag}]</span>
							{/if}
						</div>

						{#if 'description' in crew && crew.description}
							<p class="crew-description">{crew.description}</p>
						{/if}

						<div class="invitation-meta">
							<span class="invited-by">
								Invited by <strong>{invitedBy.username}</strong>
							</span>
							<span class="invited-date">
								{formatDate(invitation.createdAt)}
							</span>
						</div>

						{#if 'memberCount' in crew && crew.memberCount !== undefined}
							<div class="crew-stats">
								<span class="stat">
									{crew.memberCount} member{crew.memberCount === 1 ? '' : 's'}
								</span>
							</div>
						{/if}

					{#if expired}
						<div class="expired-notice">
							This invitation has expired.
						</div>
					{:else}
						<div class="expires-notice">
							Expires: {formatDate(invitation.expiresAt)}
						</div>

						<div class="invitation-actions">
							<Button
								variant="secondary"
								size="small"
								onclick={() => handleReject(invitation.id)}
								disabled={processingId === invitation.id}
							>
								{processingId === invitation.id && rejectMutation.isPending ? 'Declining...' : 'Decline'}
							</Button>
							<Button
								variant="primary"
								size="small"
								onclick={() => handleAccept(invitation.id)}
								disabled={processingId === invitation.id}
							>
								{processingId === invitation.id && acceptMutation.isPending ? 'Joining...' : 'Accept'}
							</Button>
						</div>
					{/if}
					</div>
				{/if}
			{/each}
		</div>
	{/if}
</div>

<style lang="scss">
	@use '$src/themes/colors' as colors;
	@use '$src/themes/spacing' as spacing;
	@use '$src/themes/typography' as typography;

	.join-page {
		max-width: 600px;
		margin: 0 auto;
	}

	.page-header {
		margin-bottom: spacing.$unit-3x;

		h1 {
			margin-bottom: spacing.$unit-half;
		}

		.description {
			color: var(--text-secondary);
		}
	}

	.loading-state,
	.error-state {
		display: flex;
		justify-content: center;
		align-items: center;
		min-height: 200px;
		color: var(--text-secondary);
	}

	.empty-state {
		text-align: center;
		padding: spacing.$unit-4x spacing.$unit-2x;
		background: var(--surface);
		border: 1px solid var(--border-color);
		border-radius: 8px;

		p {
			margin-bottom: spacing.$unit;
		}

		.hint {
			color: var(--text-secondary);
			font-size: 0.875rem;
			margin-bottom: spacing.$unit-2x;
		}
	}

	.invitations-list {
		display: flex;
		flex-direction: column;
		gap: spacing.$unit-2x;
	}

	.invitation-card {
		background: var(--surface);
		border: 1px solid var(--border-color);
		border-radius: 8px;
		padding: spacing.$unit-2x;
		transition: border-color 0.2s;

		&.highlighted {
			border-color: var(--color-blue, #3b82f6);
			box-shadow: 0 0 0 3px var(--color-blue-light, rgba(59, 130, 246, 0.1));
		}

		&.expired {
			opacity: 0.6;
		}
	}

	.invitation-header {
		display: flex;
		align-items: baseline;
		gap: spacing.$unit;
		margin-bottom: spacing.$unit;
	}

	.crew-name {
		font-size: 1.25rem;
		margin: 0;
	}

	.gamertag {
		color: var(--text-secondary);
		font-size: 0.875rem;
	}

	.crew-description {
		color: var(--text-secondary);
		margin-bottom: spacing.$unit-2x;
		line-height: 1.5;
	}

	.invitation-meta {
		display: flex;
		gap: spacing.$unit-2x;
		font-size: 0.875rem;
		color: var(--text-secondary);
		margin-bottom: spacing.$unit;
	}

	.crew-stats {
		font-size: 0.875rem;
		color: var(--text-secondary);
		margin-bottom: spacing.$unit-2x;
	}

	.expired-notice {
		color: var(--color-red, #dc2626);
		font-size: 0.875rem;
		padding: spacing.$unit;
		background: var(--color-red-light, #fef2f2);
		border-radius: 4px;
	}

	.expires-notice {
		font-size: 0.75rem;
		color: var(--text-secondary);
		margin-bottom: spacing.$unit-2x;
	}

	.invitation-actions {
		display: flex;
		justify-content: flex-end;
		gap: spacing.$unit;
	}
</style>
