<script setup lang="ts">
import { computed, ref, watch, onMounted } from 'vue'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { Switch } from '@/components/ui/switch'
import { DatePicker } from '@/components/ui/date-picker'
import { Badge } from '@/components/ui/badge'
import { FieldConfig, FieldType, ViewMode } from '@/types/field-types'
import { Label } from '@/components/ui/label'
import LookupField from '@/components/fields/LookupField.vue'

interface Props {
  field: FieldConfig
  modelValue: any
  mode: ViewMode
  readonly?: boolean
  baseUrl?: string // Base URL for API calls
  recordData?: any // Full record data to access related objects
}

const props = withDefaults(defineProps<Props>(), {
  // Default to runtime objects endpoint; override when consuming central entities
  baseUrl: '/runtime/objects',
})

const emit = defineEmits<{
  'update:modelValue': [value: any]
  'update:relatedFields': [value: Record<string, any>]
}>()

const { api } = useApi()

const value = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val),
})

const isReadOnly = computed(() => props.readonly || props.field.isReadOnly || props.mode === ViewMode.DETAIL)
const isEditMode = computed(() => props.mode === ViewMode.EDIT)
const isListMode = computed(() => props.mode === ViewMode.LIST)
const isDetailMode = computed(() => props.mode === ViewMode.DETAIL)
const relationTypeValue = computed(() => {
  if (!props.field.relationTypeField) return null
  return props.recordData?.[props.field.relationTypeField] ?? null
})

// Check if field is a relationship field
const isRelationshipField = computed(() => {
  return [FieldType.BELONGS_TO].includes(props.field.type)
})

// Get relation object name from field apiName (e.g., 'ownerId' -> 'owner')
const getRelationPropertyName = () => {
  // Backend attaches related object using field apiName without 'Id' suffix, lowercase
  // e.g., ownerId -> owner, accountId -> account
  return props.field.apiName.replace(/Id$/, '').toLowerCase()
}

// Display value for relationship fields
const relationshipDisplayValue = computed(() => {
  if (!isRelationshipField.value) return props.modelValue || '-'

  // First, check if the parent record data includes the related object
  // This happens when backend uses .withGraphFetched()
  if (props.recordData) {
    const relationPropertyName = getRelationPropertyName()
    const relatedObject = props.recordData[relationPropertyName]

    if (relatedObject && typeof relatedObject === 'object') {
      const displayField = props.field.relationDisplayField || 'name'
      return relatedObject[displayField] || relatedObject.id || props.modelValue
    }
  }
  
  // If no related object found in recordData, just show the ID
  // (The fetch mechanism is removed to avoid N+1 queries)
  return props.modelValue || '-'
})

const formatValue = (val: any): string => {
  if (val === null || val === undefined) return '-'
  switch (props.field.type) {
    case FieldType.BELONGS_TO:
      return relationshipDisplayValue.value
    case FieldType.DATE:
      try {
        const date = val instanceof Date ? val : new Date(val)
        return date.toLocaleDateString(undefined, { 
          year: 'numeric', 
          month: '2-digit', 
          day: '2-digit' 
        })
      } catch {
        return String(val)
      }
    case FieldType.DATETIME:
      try {
        const date = val instanceof Date ? val : new Date(val)
        return date.toLocaleString(undefined, { 
          year: 'numeric', 
          month: '2-digit', 
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          hour12: false
        })
      } catch {
        return String(val)
      }
    case FieldType.BOOLEAN:
      return val ? 'Yes' : 'No'
    case FieldType.CURRENCY:
      return `${props.field.prefix || '$'}${Number(val).toFixed(2)}${props.field.suffix || ''}`
    case FieldType.SELECT:
      const option = props.field.options?.find(opt => opt.value === val)
      return option?.label || val
    case FieldType.MULTI_SELECT:
      if (!Array.isArray(val)) return '-'
      return val.map(v => {
        const opt = props.field.options?.find(o => o.value === v)
        return opt?.label || v
      }).join(', ')
    default:
      return String(val)
  }
}

const handleRelationTypeUpdate = (value: string | null) => {
  if (!props.field.relationTypeField) return
  emit('update:relatedFields', {
    [props.field.relationTypeField]: value,
  })
}
</script>

<template>
  <div class="field-renderer space-y-2">
    <!-- Label (shown in edit and detail modes) -->
    <Label v-if="!isListMode" :for="field.id" class="flex items-center gap-2">
      {{ field.label }}
      <span v-if="field.isRequired && isEditMode" class="text-destructive">*</span>
    </Label>
    
    <!-- Help Text -->
    <p v-if="field.helpText && !isListMode" class="text-sm text-muted-foreground">
      {{ field.helpText }}
    </p>

    <!-- List View - Simple text display -->
    <div v-if="isListMode" class="text-sm truncate">
      <Badge v-if="field.type === FieldType.BOOLEAN" :variant="value ? 'default' : 'secondary'">
        {{ formatValue(value) }}
      </Badge>
      <template v-else>

        {{ formatValue(value) }}
      </template>
    </div>

    <!-- Detail View - Formatted display -->
    <div v-else-if="isDetailMode" class="space-y-1">
      <div v-if="field.type === FieldType.BOOLEAN" class="flex items-center gap-2">
        <Checkbox :checked="value" disabled />
        <span class="text-sm">{{ formatValue(value) }}</span>
      </div>
      <div v-else-if="field.type === FieldType.MULTI_SELECT" class="flex flex-wrap gap-2">
        <Badge v-for="(item, idx) in value" :key="idx" variant="secondary">
          {{ props.field.options?.find(opt => opt.value === item)?.label || item }}
        </Badge>
      </div>
      <div v-else-if="field.type === FieldType.URL && value" class="text-sm">
        <a :href="value" target="_blank" class="text-primary hover:underline">
          {{ value }}
        </a>
      </div>
      <div v-else-if="field.type === FieldType.EMAIL && value" class="text-sm">
        <a :href="`mailto:${value}`" class="text-primary hover:underline">
          {{ value }}
        </a>
      </div>
      <div v-else-if="field.type === FieldType.MARKDOWN && value" class="prose prose-sm">
        <div v-html="value" />
      </div>
      <div v-else class="text-sm font-medium">
        {{ formatValue(value) }}
      </div>
    </div>

    <!-- Edit View - Input components -->
    <div v-else-if="isEditMode && !isReadOnly">
      <!-- Relationship Field - Lookup -->
      <LookupField
        v-if="field.type === FieldType.BELONGS_TO"
        :field="field"
        v-model="value"
        :relation-type-value="relationTypeValue"
        :base-url="baseUrl"
        @update:relation-type-value="handleRelationTypeUpdate"
      />

      <!-- Text Input -->
      <Input
        v-else-if="[FieldType.TEXT, FieldType.EMAIL, FieldType.URL, FieldType.PASSWORD].includes(field.type)"
        :id="field.id"
        v-model="value"
        :type="field.type === FieldType.PASSWORD ? 'password' : field.type === FieldType.EMAIL ? 'email' : field.type === FieldType.URL ? 'url' : 'text'"
        :placeholder="field.placeholder"
        :required="field.isRequired"
        :disabled="field.isReadOnly"
      />

      <!-- Textarea -->
      <Textarea
        v-else-if="field.type === FieldType.TEXTAREA || field.type === FieldType.MARKDOWN"
        :id="field.id"
        v-model="value"
        :placeholder="field.placeholder"
        :rows="field.rows || 4"
        :required="field.isRequired"
        :disabled="field.isReadOnly"
      />

      <!-- Number Input -->
      <Input
        v-else-if="[FieldType.NUMBER, FieldType.CURRENCY].includes(field.type)"
        :id="field.id"
        v-model.number="value"
        type="number"
        :placeholder="field.placeholder"
        :min="field.min"
        :max="field.max"
        :step="field.step || (field.type === FieldType.CURRENCY ? 0.01 : 1)"
        :required="field.isRequired"
        :disabled="field.isReadOnly"
      />

      <!-- Select -->
      <Select v-else-if="field.type === FieldType.SELECT" v-model="value">
        <SelectTrigger :id="field.id">
          <SelectValue :placeholder="field.placeholder || 'Select an option'" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem v-for="option in field.options" :key="String(option.value)" :value="String(option.value)">
            {{ option.label }}
          </SelectItem>
        </SelectContent>
      </Select>

      <!-- Boolean - Checkbox -->
      <div v-else-if="field.type === FieldType.BOOLEAN" class="flex items-center gap-2">
        <Checkbox :id="field.id" v-model:checked="value" :disabled="field.isReadOnly" />
        <Label :for="field.id" class="text-sm font-normal cursor-pointer">
          {{ field.placeholder || field.label }}
        </Label>
      </div>

      <!-- Date Picker -->
      <DatePicker
        v-else-if="[FieldType.DATE, FieldType.DATETIME].includes(field.type)"
        v-model="value"
        :placeholder="field.placeholder"
        :disabled="field.isReadOnly"
      />

      <!-- Fallback -->
      <Input
        v-else
        :id="field.id"
        v-model="value"
        :placeholder="field.placeholder"
        :required="field.isRequired"
        :disabled="field.isReadOnly"
      />
    </div>

    <!-- Read-only Edit View -->
    <div v-else-if="isEditMode && isReadOnly" class="text-sm text-muted-foreground">
      {{ formatValue(value) }}
    </div>
  </div>
</template>

<style scoped>
.field-renderer {
  width: 100%;
}
</style>
