<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Plus, ExternalLink } from 'lucide-vue-next'
import type { FieldConfig } from '@/types/field-types'

interface RelatedListConfig {
  title: string
  relationName: string // e.g., 'domains', 'users'
  objectApiName: string // e.g., 'domains', 'users'
  fields: FieldConfig[] // Fields to display in the list
  lookupFieldApiName?: string // Used to filter by parentId when fetching
  parentObjectApiName?: string // Parent object API name, used to derive lookup field if missing
  canCreate?: boolean
  createRoute?: string // Route to create new related record
}

interface Props {
  config: RelatedListConfig
  parentId: string
  relatedRecords?: any[] // Can be passed in if already fetched
  baseUrl?: string // Base API URL, defaults to runtime objects
}

const props = withDefaults(defineProps<Props>(), {
  baseUrl: '/runtime/objects',
  relatedRecords: undefined,
})

const emit = defineEmits<{
  'navigate': [objectApiName: string, recordId: string]
  'create': [objectApiName: string, parentId: string]
}>()

const { api } = useApi()
const records = ref<any[]>([])
const loading = ref(false)
const error = ref<string | null>(null)

// Use provided records or fetch them
const displayRecords = computed(() => {
  return props.relatedRecords || records.value
})

const fetchRelatedRecords = async () => {
  if (props.relatedRecords) {
    // Records already provided, no need to fetch
    return
  }
  
  loading.value = true
  error.value = null
  
  try {
    // Replace :parentId placeholder in the API path
    const sanitizedBase = props.baseUrl.replace(/\/$/, '')
    let apiPath = props.config.objectApiName.replace(':parentId', props.parentId).replace(/^\/+/, '')
    const isRuntimeObjects = sanitizedBase.endsWith('/runtime/objects')

    // Default runtime object routes expect /:objectApiName/records
    if (isRuntimeObjects && !apiPath.includes('/')) {
      apiPath = `${apiPath}/records`
    }
    
    const findLookupKey = () => {
      if (props.config.lookupFieldApiName) return props.config.lookupFieldApiName

      const parentName = props.config.parentObjectApiName?.toLowerCase()
      const fields = props.config.fields || []

      const parentMatch = fields.find(field => {
        const relation = (field as any).relationObject || (field as any).referenceObject
        return relation && parentName && relation.toLowerCase() === parentName
      })
      if (parentMatch?.apiName) return parentMatch.apiName

      const lookupMatch = fields.find(
        field => (field.type || '').toString().toLowerCase() === 'lookup'
      )
      if (lookupMatch?.apiName) return lookupMatch.apiName

      const idMatch = fields.find(field =>
        field.apiName?.toLowerCase().endsWith('id')
      )
      if (idMatch?.apiName) return idMatch.apiName

      return 'parentId'
    }

    const lookupKey = findLookupKey()

    const response = await api.get(`${sanitizedBase}/${apiPath}`, {
      params: {
        [lookupKey]: props.parentId,
      },
    })
    records.value = response?.data || response || []
  } catch (err: any) {
    console.error('Error fetching related records:', err)
    error.value = err.message || 'Failed to fetch related records'
  } finally {
    loading.value = false
  }
}

const handleCreateNew = () => {
  emit('create', props.config.objectApiName, props.parentId)
}

const handleViewRecord = (recordId: string) => {
  emit('navigate', props.config.objectApiName, recordId)
}

const formatValue = (record: any, field: FieldConfig): string => {
  const value = record?.[field.apiName]
  if (value === null || value === undefined) return '-'
  
  const type = (field.type || '').toString().toLowerCase()

  // Lookup fields: use related object display value when available
  if (type === 'lookup' || type === 'belongsto') {
    const relationName = field.apiName.replace(/Id$/i, '').toLowerCase()
    const related = record?.[relationName]
    if (related && typeof related === 'object') {
      const displayField = (field as any).relationDisplayField || 'name'
      if (related[displayField]) return String(related[displayField])
      // Fallback: first string-ish property or ID
      const firstStringKey = Object.keys(related).find(
        key => typeof related[key] === 'string'
      )
      if (firstStringKey) return String(related[firstStringKey])
      if (related.id) return String(related.id)
    }
    // If no related object, show raw value
  }

  // Handle different field types
  if (type === 'date') {
    return new Date(value).toLocaleDateString()
  }
  if (type === 'datetime' || type === 'date_time' || type === 'date-time') {
    return new Date(value).toLocaleString()
  }
  if (type === 'boolean') {
    return value ? 'Yes' : 'No'
  }
  if (type === 'select' && field.options) {
    const option = field.options.find(opt => opt.value === value)
    return option?.label || value
  }
  
  return String(value)
}

onMounted(() => {
  fetchRelatedRecords()
})
</script>

<template>
  <Card class="related-list">
    <CardHeader>
      <div class="flex items-center justify-between">
        <div>
          <CardTitle>{{ config.title }}</CardTitle>
          <CardDescription v-if="displayRecords.length > 0">
            {{ displayRecords.length }} {{ displayRecords.length === 1 ? 'record' : 'records' }}
          </CardDescription>
        </div>
        <Button
          v-if="config.canCreate !== false"
          size="sm"
          @click="handleCreateNew"
        >
          <Plus class="h-4 w-4 mr-2" />
          New
        </Button>
      </div>
    </CardHeader>
    <CardContent>
      <!-- Loading State -->
      <div v-if="loading" class="flex items-center justify-center py-8">
        <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
      </div>

      <!-- Error State -->
      <div v-else-if="error" class="text-sm text-destructive py-4">
        {{ error }}
      </div>

      <!-- Empty State -->
      <div v-else-if="displayRecords.length === 0" class="text-center py-8 text-muted-foreground">
        <p class="text-sm">No {{ config.title.toLowerCase() }} yet</p>
        <Button
          v-if="config.canCreate !== false"
          variant="outline"
          size="sm"
          class="mt-4"
          @click="handleCreateNew"
        >
          <Plus class="h-4 w-4 mr-2" />
          Create First {{ config.title.slice(0, -1) }}
        </Button>
      </div>

      <!-- Records Table -->
      <div v-else class="rounded-md border">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead v-for="field in config.fields" :key="field.id">
                {{ field.label }}
              </TableHead>
              <TableHead class="w-[80px]">Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            <TableRow v-for="record in displayRecords" :key="record.id">
              <TableCell v-for="field in config.fields" :key="field.id">
                {{ formatValue(record, field) }}
              </TableCell>
              <TableCell>
                <Button
                  variant="ghost"
                  size="sm"
                  @click="handleViewRecord(record.id)"
                >
                  <ExternalLink class="h-4 w-4" />
                </Button>
              </TableCell>
            </TableRow>
          </TableBody>
        </Table>
      </div>
    </CardContent>
  </Card>
</template>

<style scoped>
.related-list {
  margin-top: 1.5rem;
}
</style>
