<script setup lang="ts">
import { reactive } from 'vue'
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
import { Badge } from '@/components/ui/badge'

const props = withDefaults(
  defineProps<{
  data: Record<string, any> | any[]
  expandObjectsByDefault?: boolean
  }>(),
  {
    expandObjectsByDefault: true,
  },
)

const expanded = reactive<Record<string, boolean>>({})
const isOpen = (id: string): boolean => {
  const localValue = expanded[id]
  return localValue === undefined ? props.expandObjectsByDefault : localValue
}
const setOpen = (id: string, value: boolean): void => {
  expanded[id] = value
}
const isObject = (value: any): boolean => {
  return value !== null && typeof value === 'object' && !Array.isArray(value)
}
const isArray = (value: any): boolean => {
  return Array.isArray(value)
}
const formatValue = (value: any): string => {
  if (value === null) return 'null'
  if (value === undefined) return 'undefined'
  if (typeof value === 'string') return value
  if (typeof value === 'boolean') return value ? 'true' : 'false'
  if (typeof value === 'number') return value.toString()
  return String(value)
}
</script>

<template>
  <div class="grid grid-cols-[auto_1fr] gap-x-5 gap-y-1 text-[14px] p-1">
    <template v-for="(value, key) in data" :key="key">
      <!-- Simple key-value row for primitive values -->
      <template v-if="!isObject(value) && !isArray(value)">
        <div class="col-span-2 bg-accent/50 -mx-2 px-2 py-1 rounded-md grid grid-cols-subgrid">
          <span class="text-foreground/65">{{ String(key) }}</span>
          <span class="text-foreground/90 break-all">{{ formatValue(value) }}</span>
        </div>
      </template>

      <!-- Collapsible section for objects -->
      <template v-else-if="isObject(value)">
        <div class="col-span-2 bg-accent/50 -mx-2 px-2 py-1 rounded-md">
          <Collapsible :open="isOpen(String(key))" @update:open="setOpen(String(key), $event)">
            <CollapsibleTrigger
              class="flex items-center justify-between w-full text-foreground/85 cursor-pointer py-0.5"
            >
              <span>{{ String(key) }}</span>
              <i
                class="dku-icon-chevron-right-16 transition-transform duration-200"
                :class="{ 'rotate-90': isOpen(String(key)) }"
              />
            </CollapsibleTrigger>
            <CollapsibleContent
              class="ml-2 mt-1 pl-3 border-l border-primary-alpha-light-50 text-sm"
            >
              <JsonKeyValueDisplay
                :data="value"
                :expand-objects-by-default="props.expandObjectsByDefault"
              />
            </CollapsibleContent>
          </Collapsible>
        </div>
      </template>

      <!-- Collapsible section for arrays -->
      <template v-else-if="isArray(value)">
        <span class="text-gray-500">{{ String(key) }}</span>
        <div class="flex flex-wrap gap-1">
          <template v-if="value.length === 0">
            {{ '<empty array>' }}
          </template>
          <template v-else v-for="(item, index) in value" :key="index">
            <Badge v-if="!isObject(item)" variant="outline" class="text-xs">
              {{ formatValue(item) }}
            </Badge>
            <Collapsible
              v-else
              :open="isOpen(`${String(key)}-${index}`)"
              class="w-full"
              @update:open="setOpen(`${String(key)}-${index}`, $event)"
            >
              <CollapsibleTrigger
                class="flex items-center text-sm text-gray-500 cursor-pointer py-0.5"
              >
                <Badge variant="outline" class="text-xs flex items-center gap-1">
                  <span>Item {{ index }}</span>
                  <i
                    class="dku-icon-chevron-right-12 transition-transform duration-200"
                    :class="{ 'rotate-90': isOpen(`${String(key)}-${index}`) }"
                  />
                </Badge>
              </CollapsibleTrigger>
              <CollapsibleContent class="ml-1 mt-1 pl-3 border-l-1 border-gray-300">
                <JsonKeyValueDisplay
                  :data="item"
                  :expand-objects-by-default="props.expandObjectsByDefault"
                />
              </CollapsibleContent>
            </Collapsible>
          </template>
        </div>
      </template>
    </template>
  </div>
</template>

<style scoped>
button {
  transition: background-color 0.15s ease;
}
</style>
