<script setup>
import { ref, computed } from 'vue'

const props = defineProps({
    data: { type: [Object, Array, String, Number, Boolean, null], default: null },
    expandDepth: { type: Number, default: 2 },
    label: { type: String, default: '' },
    depth: { type: Number, default: 0 },
    isRoot: { type: Boolean, default: true },
})

const expanded = ref(props.depth < props.expandDepth)

const dataType = computed(() => {
    if (props.data === null || props.data === undefined) return 'null'
    if (Array.isArray(props.data)) return 'array'
    return typeof props.data
})

const isExpandable = computed(() => {
    return dataType.value === 'object' || dataType.value === 'array'
})

const entries = computed(() => {
    if (!isExpandable.value || !props.data) return []
    return Object.entries(props.data)
})

const previewText = computed(() => {
    if (dataType.value === 'array') return `Array[${props.data.length}]`
    if (dataType.value === 'object') {
        const keys = Object.keys(props.data)
        return `{${keys.length}}`
    }
    return ''
})

function formatValue(val) {
    if (val === null || val === undefined) return 'null'
    if (typeof val === 'string') return `"${val}"`
    if (typeof val === 'boolean') return val ? 'true' : 'false'
    return String(val)
}

function valueClass(val) {
    if (val === null || val === undefined) return 'text-gray-400 italic'
    if (typeof val === 'string') return 'text-emerald-700'
    if (typeof val === 'number') return 'text-blue-700'
    if (typeof val === 'boolean') return 'text-amber-700'
    return 'text-gray-700'
}

function toggle() {
    if (isExpandable.value) {
        expanded.value = !expanded.value
    }
}

function copyToClipboard() {
    const text = JSON.stringify(props.data, null, 2)
    navigator.clipboard.writeText(text).catch(() => {})
}
</script>

<template>
    <div :class="['json-tree', { 'json-tree--root': isRoot }]">
        <!-- Root-level copy button -->
        <div v-if="isRoot && data && typeof data === 'object'" class="flex items-center justify-end mb-1.5">
            <button
                @click="copyToClipboard"
                class="flex items-center gap-1 rounded-md px-2 py-0.5 text-[10px] font-medium text-gray-400 transition hover:bg-gray-100 hover:text-gray-600"
                title="JSON kopieren"
            >
                <svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9.75a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184" />
                </svg>
                Kopieren
            </button>
        </div>

        <!-- String data (not object/array) at root level -->
        <pre v-if="isRoot && typeof data === 'string'" class="text-xs text-gray-700 whitespace-pre-wrap leading-relaxed">{{ data }}</pre>

        <!-- Null/empty at root level -->
        <span v-else-if="isRoot && (data === null || data === undefined)" class="text-sm italic text-gray-400">Keine Daten</span>

        <!-- Primitive at root level -->
        <span v-else-if="isRoot && !isExpandable" :class="['text-xs font-mono', valueClass(data)]">{{ formatValue(data) }}</span>

        <!-- Tree view for objects/arrays -->
        <div v-else-if="isExpandable" class="font-mono text-xs leading-relaxed">
            <!-- Expandable node header -->
            <div
                class="json-node-header group flex items-center gap-1 cursor-pointer rounded px-1 -mx-1 transition-colors hover:bg-gray-50"
                @click="toggle"
            >
                <!-- Triangle -->
                <svg
                    class="h-3 w-3 shrink-0 text-gray-400 transition-transform duration-150"
                    :class="{ 'rotate-90': expanded }"
                    fill="currentColor"
                    viewBox="0 0 20 20"
                >
                    <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
                </svg>

                <!-- Key label -->
                <span v-if="label" class="text-purple-700 font-medium">{{ label }}</span>
                <span v-if="label" class="text-gray-400">:</span>

                <!-- Collapsed preview -->
                <span class="text-gray-400">
                    {{ dataType === 'array' ? '[' : '{' }}
                </span>
                <span v-if="!expanded" class="text-gray-400">
                    {{ previewText }}
                    {{ dataType === 'array' ? ']' : '}' }}
                </span>
            </div>

            <!-- Children -->
            <div v-if="expanded" class="ml-4 border-l border-gray-200 pl-3">
                <template v-for="([key, val], idx) in entries" :key="key">
                    <!-- Nested expandable -->
                    <JsonTreeViewer
                        v-if="val !== null && typeof val === 'object'"
                        :data="val"
                        :expand-depth="expandDepth"
                        :label="key"
                        :depth="depth + 1"
                        :is-root="false"
                    />
                    <!-- Leaf value -->
                    <div v-else class="flex items-center gap-1 py-0.5 px-1 -mx-1 rounded transition-colors hover:bg-gray-50">
                        <span class="h-3 w-3 shrink-0" />
                        <span class="text-purple-700 font-medium">{{ key }}</span>
                        <span class="text-gray-400">:</span>
                        <span :class="valueClass(val)">{{ formatValue(val) }}</span>
                    </div>
                </template>
            </div>

            <!-- Closing bracket -->
            <div v-if="expanded" class="text-gray-400 px-1 -mx-1">
                <span class="ml-0">{{ dataType === 'array' ? ']' : '}' }}</span>
            </div>
        </div>
    </div>
</template>

<style scoped>
.json-tree--root {
    padding: 8px;
    border-radius: 8px;
    background: rgb(249 250 251 / 0.5);
}
</style>
