<script setup lang="ts">
import { ref, onErrorCaptured } from 'vue'

interface Props {
  fallbackMessage?: string
}

withDefaults(defineProps<Props>(), {
  fallbackMessage: 'Something went wrong. Please try again.',
})

const error = ref<Error | null>(null)
const errorMessage = ref('')

onErrorCaptured((err: unknown) => {
  error.value = err instanceof Error ? err : new Error(String(err))
  errorMessage.value = error.value.message || 'An unexpected error occurred'
  return false // Prevent error from propagating
})

const retry = () => {
  error.value = null
  errorMessage.value = ''
}
</script>

<template>
  <div>
    <!-- Error state -->
    <div v-if="error" class="error-boundary">
      <div class="error-icon">⚠️</div>
      <div class="error-content">
        <h3>Error</h3>
        <p class="error-message">{{ errorMessage || fallbackMessage }}</p>
        <button @click="retry" class="btn btn-primary">Retry</button>
      </div>
    </div>

    <!-- Normal rendering -->
    <slot v-else></slot>
  </div>
</template>

<style scoped>
.error-boundary {
  padding: var(--spacing-6);
  background: var(--color-danger-50);
  border: var(--border-width-2) solid var(--color-danger-200);
  border-radius: var(--border-radius-lg);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-4);
}

.error-icon {
  font-size: 48px;
  line-height: 1;
}

.error-content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  max-width: 400px;
}

.error-content h3 {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-danger-700);
}

.error-message {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-danger-600);
  line-height: var(--line-height-normal);
}

.btn {
  padding: var(--spacing-2) var(--spacing-4);
  border: var(--border-width-1) solid var(--color-danger-300);
  border-radius: var(--border-radius-base);
  background: var(--color-danger-500);
  color: white;
  cursor: pointer;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  transition: all var(--transition-fast);
  font-family: var(--font-sans);
}

.btn-primary:hover:not(:disabled) {
  background: var(--color-danger-600);
  border-color: var(--color-danger-600);
}

.btn-primary:active:not(:disabled) {
  transform: scale(0.98);
}
</style>
