<script setup lang="ts">
import { ref, watch, onErrorCaptured } from 'vue'
import { useRoute } from 'vue-router'
import Icon from '@/components/ds/core/Icon.vue'
import Button from '@/components/ds/core/Button.vue'

withDefaults(defineProps<{
  /** 'screen' fills the viewport (app root); 'content' fills its container (inside layout chrome) */
  variant?: 'screen' | 'content'
}>(), { variant: 'screen' })

const route = useRoute()
const hasError = ref(false)
const errorMessage = ref('')

onErrorCaptured((err) => {
  hasError.value = true
  errorMessage.value = err.message || 'An unexpected error occurred'
  console.error('ErrorBoundary caught:', err)
  return false
})

// A failed view must not brick navigation — clear the error when the route changes
watch(() => route.fullPath, () => {
  hasError.value = false
  errorMessage.value = ''
})

function retry() {
  hasError.value = false
  errorMessage.value = ''
  window.location.reload()
}
</script>

<template>
  <div v-if="hasError" class="eb-screen" :class="{ 'eb-screen--content': variant === 'content' }">
    <div class="eb-card">
      <div class="eb-icon-wrap">
        <Icon name="triangle-alert" :size="24" :stroke-width="1.75" />
      </div>
      <h1 class="eb-title">Something went wrong</h1>
      <p class="eb-msg">{{ errorMessage }}</p>
      <Button icon="refresh-cw" @click="retry">Retry</Button>
    </div>
  </div>
  <slot v-else />
</template>

<style scoped>
.eb-screen {
  min-height: 100vh;
  background: var(--surface-canvas);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.eb-screen--content {
  min-height: 60vh;
  background: transparent;
}

.eb-card {
  background: var(--surface-base);
  box-shadow: var(--ring-default), var(--shadow-md);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  max-width: 380px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
}

.eb-icon-wrap {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--status-offline-soft);
  box-shadow: inset 0 0 0 1px var(--status-offline-border);
  color: var(--status-offline);
  flex: none;
}

.eb-title {
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}

.eb-msg {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  line-height: 1.55;
  max-width: 300px;
}
</style>
