<template>
  <div class="min-h-screen bg-background">
    <NuxtLayout name="default">
      <main class="container mx-auto px-4 py-8">
        <div v-if="loading" class="text-center py-12">Loading...</div>
        <div v-else-if="error" class="text-destructive">Error: {{ error }}</div>
        <div v-else-if="object">
          <div class="mb-6">
            <NuxtLink to="/setup/objects" class="text-sm text-primary hover:underline">
              ← Back to Objects
            </NuxtLink>
          </div>

          <h1 class="text-3xl font-bold mb-6">{{ object.label }}</h1>

          <!-- Tabs -->
          <div class="mb-8">
            <Tabs v-model="activeTab" default-value="fields" class="w-full">
              <TabsList class="grid w-full grid-cols-3 max-w-2xl">
                <TabsTrigger value="fields">Fields</TabsTrigger>
                <TabsTrigger value="access">Access</TabsTrigger>
                <TabsTrigger value="layouts">Page Layouts</TabsTrigger>
              </TabsList>

              <!-- Fields Tab -->
              <TabsContent value="fields" class="mt-6">
                <div class="space-y-4">
                  <div class="flex justify-between items-center mb-4">
                    <h2 class="text-xl font-semibold">Fields</h2>
                    <Button @click="openFieldDialog('create')">
                      <Plus class="w-4 h-4 mr-2" />
                      New Field
                    </Button>
                  </div>

                  <div v-if="!object.fields || object.fields.length === 0" class="text-center py-8 text-muted-foreground">
                    No fields defined yet. Create one to get started.
                  </div>

                  <div v-else class="space-y-2">
                    <div
                      v-for="field in object.fields"
                      :key="field.id"
                      class="p-4 border rounded-lg bg-card hover:border-primary transition-colors"
                    >
                      <div class="flex items-center justify-between">
                        <div class="flex-1">
                          <h3 class="font-semibold">{{ field.label }}</h3>
                          <p class="text-sm text-muted-foreground">
                            Type: <span class="font-medium">{{ formatFieldType(field.type) }}</span> | API Name: <span class="font-mono">{{ field.apiName }}</span>
                          </p>
                          <p v-if="field.description" class="text-sm text-muted-foreground mt-1">
                            {{ field.description }}
                          </p>
                        </div>
                        <div class="flex items-center gap-3">
                          <div class="flex gap-2 text-xs">
                            <span
                              v-if="field.isRequired"
                              class="px-2 py-1 bg-destructive/10 text-destructive rounded"
                            >
                              Required
                            </span>
                            <span
                              v-if="field.isUnique"
                              class="px-2 py-1 bg-primary/10 text-primary rounded"
                            >
                              Unique
                            </span>
                            <span
                              v-if="field.isSystem"
                              class="px-2 py-1 bg-gray-200 text-gray-700 rounded text-xs"
                            >
                              System
                            </span>
                          </div>
                          <div class="flex gap-2">
                            <Button
                              v-if="!field.isSystem"
                              variant="ghost"
                              size="sm"
                              @click="openFieldDialog('edit', field)"
                              title="Edit field"
                            >
                              ✏️
                            </Button>
                            <Button
                              v-if="!field.isSystem"
                              variant="ghost"
                              size="sm"
                              class="text-destructive hover:text-destructive"
                              @click="deleteField(field)"
                              title="Delete field"
                            >
                              <Trash2 class="w-4 h-4" />
                            </Button>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </TabsContent>

              <!-- Access Tab -->
              <TabsContent value="access" class="mt-6">
                <ObjectAccessSettings
                  :object-api-name="object.apiName"
                  :object-id="object.id"
                  :org-wide-default="object.orgWideDefault"
                  :fields="object.fields"
                  @update="handleAccessUpdate"
                />
              </TabsContent>

              <!-- Page Layouts Tab -->
              <TabsContent value="layouts" class="mt-6">
                <div v-if="!selectedLayout" class="space-y-4">
                  <div class="flex justify-between items-center mb-4">
                    <h2 class="text-xl font-semibold">Page Layouts</h2>
                    <Button @click="handleCreateLayout">
                      <Plus class="w-4 h-4 mr-2" />
                      New Layout
                    </Button>
                  </div>

                  <div v-if="loadingLayouts" class="text-center py-8">
                    Loading layouts...
                  </div>
                  
                  <div v-else-if="layouts.length === 0" class="text-center py-8 text-muted-foreground">
                    No page layouts yet. Create one to get started.
                  </div>

                  <div v-else class="space-y-2">
                    <div
                      v-for="layout in layouts"
                      :key="layout.id"
                      class="p-4 border rounded-lg bg-card hover:border-primary cursor-pointer transition-colors"
                      @click="handleSelectLayout(layout)"
                    >
                      <div class="flex items-center justify-between">
                        <div>
                          <h3 class="font-semibold">{{ layout.name }}</h3>
                          <p v-if="layout.description" class="text-sm text-muted-foreground">
                            {{ layout.description }}
                          </p>
                        </div>
                        <div class="flex items-center gap-2">
                          <span
                            v-if="layout.isDefault"
                            class="px-2 py-1 bg-primary/10 text-primary rounded text-xs"
                          >
                            Default
                          </span>
                          <Button
                            variant="ghost"
                            size="sm"
                            @click.stop="handleDeleteLayout(layout.id)"
                          >
                            <Trash2 class="w-4 h-4" />
                          </Button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- Layout Editor -->
                <div v-else>
                  <div class="mb-4">
                    <Button variant="outline" @click="selectedLayout = null">
                      <ArrowLeft class="w-4 h-4 mr-2" />
                      Back to Layouts
                    </Button>
                  </div>

                  <PageLayoutEditor
                    :fields="object.fields"
                    :initial-layout="(selectedLayout.layoutConfig || selectedLayout.layout_config)?.fields || []"
                    :layout-name="selectedLayout.name"
                    @save="handleSaveLayout"
                  />
                </div>
              </TabsContent>
            </Tabs>
          </div>
        </div>
      </main>

      <!-- Field Management Dialog -->
      <div v-if="showFieldDialog" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
        <div class="bg-white rounded-lg shadow-lg max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
          <div class="sticky top-0 bg-white border-b p-6 flex items-center justify-between">
            <h2 class="text-2xl font-bold">
              {{ fieldDialogMode === 'create' ? 'Create New Field' : 'Edit Field' }}
            </h2>
            <button
              @click="closeFieldDialog"
              class="text-gray-500 hover:text-gray-700 text-2xl font-bold"
            >
              ×
            </button>
          </div>

          <div class="p-6 space-y-6">
            <!-- Field Type Selection (only for creation) -->
            <div v-if="fieldDialogMode === 'create'">
              <FieldTypeSelector
                v-model="fieldForm.type"
              />
            </div>

            <!-- Common Attributes -->
            <div v-if="fieldForm.type">
              <h3 class="text-lg font-semibold mb-4">Basic Properties</h3>
              <FieldAttributesCommon
                :label="fieldForm.label"
                :api-name="fieldForm.apiName"
                :description="fieldForm.description"
                :placeholder="fieldForm.placeholder"
                :help-text="fieldForm.helpText"
                :display-order="fieldForm.displayOrder"
                :is-required="fieldForm.isRequired"
                :is-unique="fieldForm.isUnique"
                :default-value="fieldForm.defaultValue"
                :is-editing="fieldDialogMode === 'edit'"
                :has-data="fieldForm.hasData"
                @update="updateCommonAttributes"
              />
            </div>

            <!-- Type-Specific Attributes -->
            <div v-if="fieldForm.type">
              <h3 class="text-lg font-semibold mb-4">Type-Specific Settings</h3>
              <FieldAttributesType
                :field-type="fieldForm.type"
                :attributes="fieldForm.typeAttributes"
                @update="updateTypeAttributes"
              />
            </div>

            <!-- Lookup Field Selection -->
            <div v-if="(fieldForm.type === 'lookup' || fieldForm.type === 'belongsTo') && fieldDialogMode === 'create'">
              <h3 class="text-lg font-semibold mb-4">Related Object</h3>
              <div class="grid grid-cols-4 gap-4">
                <label class="text-sm font-medium leading-8">Select Object</label>
                <div class="col-span-3">
                  <select
                    v-model="fieldForm.referenceObject"
                    class="w-full px-3 py-2 border rounded-md text-sm"
                  >
                    <option value="">-- Select an object --</option>
                    <option
                      v-for="obj in availableObjects"
                      :key="obj.id"
                      :value="obj.apiName"
                    >
                      {{ obj.label }} ({{ obj.apiName }})
                    </option>
                  </select>
                </div>
              </div>
            </div>

            <!-- Error Message -->
            <div v-if="fieldDialogError" class="p-3 bg-red-100 text-red-800 rounded-md text-sm">
              {{ fieldDialogError }}
            </div>

            <!-- Action Buttons -->
            <div class="flex gap-3 justify-end pt-4">
              <Button variant="outline" @click="closeFieldDialog">
                Cancel
              </Button>
              <Button
                :disabled="!fieldForm.label || !fieldForm.apiName || !fieldForm.type"
                @click="saveField"
              >
                {{ fieldDialogMode === 'create' ? 'Create Field' : 'Update Field' }}
              </Button>
            </div>
          </div>
        </div>
      </div>
    </NuxtLayout>
  </div>
</template>

<script setup lang="ts">
import { Plus, Trash2, ArrowLeft } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import PageLayoutEditor from '@/components/PageLayoutEditor.vue'
import ObjectAccessSettings from '@/components/ObjectAccessSettings.vue'
import FieldTypeSelector from '@/components/fields/FieldTypeSelector.vue'
import FieldAttributesCommon from '@/components/fields/FieldAttributesCommon.vue'
import FieldAttributesType from '@/components/fields/FieldAttributesType.vue'
import type { PageLayout, FieldLayoutItem } from '~/types/page-layout'

const route = useRoute()
const { api } = useApi()
const { getPageLayouts, createPageLayout, updatePageLayout, deletePageLayout } = usePageLayouts()
const { toast } = useToast()

const object = ref<any>(null)
const loading = ref(true)
const error = ref<string | null>(null)
const activeTab = ref('fields')

// Page layouts state
const layouts = ref<PageLayout[]>([])
const loadingLayouts = ref(false)
const selectedLayout = ref<PageLayout | null>(null)

// Field management state
const showFieldDialog = ref(false)
const fieldDialogMode = ref<'create' | 'edit'>('create')
const fieldDialogError = ref<string | null>(null)
const availableObjects = ref<any[]>([])
const fieldForm = ref({
  id: '',
  label: '',
  apiName: '',
  type: '',
  description: '',
  placeholder: '',
  helpText: '',
  displayOrder: 0,
  isRequired: false,
  isUnique: false,
  defaultValue: '',
  referenceObject: '',
  typeAttributes: {},
  hasData: false,
})

// Helper to format field type names
const formatFieldType = (type: string): string => {
  const typeNames: Record<string, string> = {
    'TEXT': 'Text',
    'LONG_TEXT': 'Textarea',
    'EMAIL': 'Email',
    'PHONE': 'Phone',
    'NUMBER': 'Number',
    'CURRENCY': 'Currency',
    'PERCENT': 'Percent',
    'PICKLIST': 'Picklist',
    'MULTI_PICKLIST': 'Multi-select',
    'BOOLEAN': 'Checkbox',
    'DATE': 'Date',
    'DATE_TIME': 'DateTime',
    'TIME': 'Time',
    'URL': 'URL',
    'LOOKUP': 'Lookup',
    'FILE': 'File',
    'IMAGE': 'Image',
    'JSON': 'JSON',
  }
  return typeNames[type] || type
}

const convertFrontendToBackendType = (frontendType: string): string => {
  const typeMap: Record<string, string> = {
    'text': 'TEXT',
    'textarea': 'LONG_TEXT',
    'password': 'TEXT',
    'email': 'EMAIL',
    'number': 'NUMBER',
    'currency': 'CURRENCY',
    'percent': 'PERCENT',
    'select': 'PICKLIST',
    'multiSelect': 'MULTI_PICKLIST',
    'boolean': 'BOOLEAN',
    'date': 'DATE',
    'datetime': 'DATE_TIME',
    'time': 'TIME',
    'url': 'URL',
    'color': 'TEXT',
    'json': 'JSON',
    'lookup': 'LOOKUP',
    'belongsTo': 'LOOKUP',
    'markdown': 'LONG_TEXT',
    'code': 'LONG_TEXT',
    'file': 'FILE',
    'image': 'IMAGE',
  }
  return typeMap[frontendType] || 'TEXT'
}

const fetchObject = async () => {
  try {
    loading.value = true
    const apiName = route.params.apiName as string
    object.value = await api.get(`/setup/objects/${apiName}`)
  } catch (e: any) {
    error.value = e.message
  } finally {
    loading.value = false
  }
}

const fetchAvailableObjects = async () => {
  try {
    availableObjects.value = await api.get('/setup/objects')
  } catch (e: any) {
    console.error('Error fetching available objects:', e)
  }
}

const fetchLayouts = async () => {
  if (!object.value) return
  
  try {
    loadingLayouts.value = true
    layouts.value = await getPageLayouts(object.value.id)
  } catch (e: any) {
    console.error('Error fetching layouts:', e)
    toast.error('Failed to load page layouts')
  } finally {
    loadingLayouts.value = false
  }
}

const openFieldDialog = async (mode: 'create' | 'edit', field?: any) => {
  fieldDialogMode.value = mode
  fieldDialogError.value = null

  if (mode === 'create') {
    await fetchAvailableObjects()
    fieldForm.value = {
      id: '',
      label: '',
      apiName: '',
      type: '',
      description: '',
      placeholder: '',
      helpText: '',
      displayOrder: (object.value?.fields?.length || 0) + 1,
      isRequired: false,
      isUnique: false,
      defaultValue: '',
      referenceObject: '',
      typeAttributes: {},
      hasData: false,
    }
  } else if (field) {
    // Load field data for editing
    const uiMetadata = field.ui_metadata ? JSON.parse(field.ui_metadata) : {}
    fieldForm.value = {
      id: field.id,
      label: field.label,
      apiName: field.apiName,
      type: convertBackendToFrontendType(field.type),
      description: field.description || '',
      placeholder: uiMetadata.placeholder || '',
      helpText: uiMetadata.helpText || '',
      displayOrder: field.displayOrder || 0,
      isRequired: field.isRequired || false,
      isUnique: field.isUnique || false,
      defaultValue: field.defaultValue || '',
      referenceObject: field.referenceObject || '',
      typeAttributes: extractTypeAttributes(field, uiMetadata),
      hasData: false, // Would need to fetch this from backend
    }
  }

  showFieldDialog.value = true
}

const convertBackendToFrontendType = (backendType: string): string => {
  const typeMap: Record<string, string> = {
    'TEXT': 'text',
    'LONG_TEXT': 'textarea',
    'EMAIL': 'email',
    'PHONE': 'phone',
    'NUMBER': 'number',
    'CURRENCY': 'currency',
    'PERCENT': 'percent',
    'PICKLIST': 'select',
    'MULTI_PICKLIST': 'multiSelect',
    'BOOLEAN': 'boolean',
    'DATE': 'date',
    'DATE_TIME': 'datetime',
    'TIME': 'time',
    'URL': 'url',
    'LOOKUP': 'lookup',
    'FILE': 'file',
    'IMAGE': 'image',
    'JSON': 'json',
  }
  return typeMap[backendType] || 'text'
}

const extractTypeAttributes = (field: any, uiMetadata: any): any => {
  const attrs: any = {}

  if (field.type === 'PICKLIST' || field.type === 'MULTI_PICKLIST') {
    attrs.options = uiMetadata.options || []
  }

  if (field.type === 'NUMBER' || field.type === 'CURRENCY') {
    attrs.scale = field.scale || 0
    attrs.min = uiMetadata.min
    attrs.max = uiMetadata.max
    if (field.type === 'CURRENCY') {
      attrs.prefix = uiMetadata.prefix || '$'
    }
  }

  if (field.type === 'TEXT' && field.length) {
    attrs.maxLength = field.length
  }

  if (field.type === 'LONG_TEXT' && uiMetadata.rows) {
    attrs.rows = uiMetadata.rows
  }

  if (field.type === 'LOOKUP') {
    attrs.relationObject = field.referenceObject
    attrs.relationDisplayField = uiMetadata.relationDisplayField || 'name'
  }

  return attrs
}

const closeFieldDialog = () => {
  showFieldDialog.value = false
  fieldDialogError.value = null
}

const updateCommonAttributes = (data: any) => {
  Object.assign(fieldForm.value, data)
}

const updateTypeAttributes = (data: any) => {
  fieldForm.value.typeAttributes = data
}

const saveField = async () => {
  fieldDialogError.value = null

  try {
    // Validate
    if (!fieldForm.value.label || !fieldForm.value.apiName || !fieldForm.value.type) {
      fieldDialogError.value = 'Please fill in all required fields'
      return
    }

    const apiName = route.params.apiName as string

    // Prepare payload
    const payload: any = {
      label: fieldForm.value.label,
      apiName: fieldForm.value.apiName,
      type: fieldForm.value.type, // Use frontend type, backend will convert
      description: fieldForm.value.description,
      isRequired: fieldForm.value.isRequired,
      isUnique: fieldForm.value.isUnique,
      defaultValue: fieldForm.value.defaultValue,
    }

    // Extract type-specific database fields
    const typeAttrs = fieldForm.value.typeAttributes || {}
    
    // For text fields
    if (fieldForm.value.type === 'text' && typeAttrs.maxLength) {
      payload.length = typeAttrs.maxLength
    }

    // For number and currency fields
    if ((fieldForm.value.type === 'number' || fieldForm.value.type === 'currency') && typeAttrs.scale !== undefined) {
      payload.scale = typeAttrs.scale
      if (typeAttrs.scale > 0) {
        payload.precision = 10 // Default precision for decimals
      }
    }

    // Merge UI metadata
    const uiMetadata: any = {
      placeholder: fieldForm.value.placeholder,
      helpText: fieldForm.value.helpText,
    }

    // Add type-specific attributes to UI metadata
    if (fieldForm.value.typeAttributes) {
      Object.assign(uiMetadata, fieldForm.value.typeAttributes)
    }

    payload.uiMetadata = uiMetadata

    if (fieldForm.value.referenceObject) {
      payload.relationObject = fieldForm.value.referenceObject
      payload.relationDisplayField = fieldForm.value.typeAttributes.relationDisplayField || 'name'
    }

    let result
    if (fieldDialogMode.value === 'create') {
      result = await api.post(`/setup/objects/${apiName}/fields`, payload)
    } else {
      // For updates, only send fields that changed
      const updatePayload: any = {}
      if (fieldForm.value.label) updatePayload.label = fieldForm.value.label
      if (fieldForm.value.description) updatePayload.description = fieldForm.value.description
      if (fieldForm.value.placeholder) updatePayload.placeholder = fieldForm.value.placeholder
      if (fieldForm.value.helpText) updatePayload.helpText = fieldForm.value.helpText
      updatePayload.isRequired = fieldForm.value.isRequired
      updatePayload.isUnique = fieldForm.value.isUnique
      updatePayload.displayOrder = fieldForm.value.displayOrder
      if (Object.keys(uiMetadata).length > 0) {
        updatePayload.uiMetadata = uiMetadata
      }

      result = await api.put(
        `/setup/objects/${apiName}/fields/${fieldForm.value.apiName}`,
        updatePayload,
      )
    }

    // Update the object with new field
    if (fieldDialogMode.value === 'create') {
      object.value.fields.push(result)
    } else {
      const index = object.value.fields.findIndex((f: any) => f.id === fieldForm.value.id)
      if (index !== -1) {
        object.value.fields[index] = result
      }
    }

    toast.success(
      fieldDialogMode.value === 'create'
        ? 'Field created successfully'
        : 'Field updated successfully',
    )

    closeFieldDialog()
  } catch (e: any) {
    fieldDialogError.value = e.message || 'An error occurred while saving the field'
    console.error('Error saving field:', e)
  }
}

const deleteField = async (field: any) => {
  if (!confirm(`Are you sure you want to delete the field "${field.label}"? This action cannot be undone.`)) {
    return
  }

  try {
    const apiName = route.params.apiName as string
    await api.delete(`/setup/objects/${apiName}/fields/${field.apiName}`)

    // Remove from the list
    object.value.fields = object.value.fields.filter((f: any) => f.id !== field.id)

    // Also remove from page layouts
    for (const layout of layouts.value) {
      const layoutConfig = layout.layoutConfig || layout.layout_config || { fields: [] }
      if (layoutConfig.fields) {
        layoutConfig.fields = layoutConfig.fields.filter(
          (f: any) => f.fieldId !== field.id,
        )
      }
    }

    toast.success('Field deleted successfully')
  } catch (e: any) {
    toast.error(`Failed to delete field: ${e.message}`)
    console.error('Error deleting field:', e)
  }
}

const handleCreateLayout = async () => {
  const name = prompt('Enter a name for the new layout:')
  if (!name) return

  try {
    const newLayout = await createPageLayout({
      name,
      objectId: object.value.id,
      isDefault: layouts.value.length === 0,
      layoutConfig: { fields: [] },
    })
    
    layouts.value.push(newLayout)
    selectedLayout.value = newLayout
    toast.success('Layout created successfully')
  } catch (e: any) {
    console.error('Error creating layout:', e)
    toast.error('Failed to create layout')
  }
}

const handleSelectLayout = (layout: PageLayout) => {
  selectedLayout.value = layout
}

const handleSaveLayout = async (fields: FieldLayoutItem[]) => {
  if (!selectedLayout.value) return

  try {
    const updated = await updatePageLayout(selectedLayout.value.id, {
      layoutConfig: { fields },
    })
    
    // Update the layout in the list
    const index = layouts.value.findIndex(l => l.id === selectedLayout.value!.id)
    if (index !== -1) {
      layouts.value[index] = updated
    }
    
    selectedLayout.value = updated
    toast.success('Layout saved successfully')
  } catch (e: any) {
    console.error('Error saving layout:', e)
    toast.error('Failed to save layout')
  }
}

const handleDeleteLayout = async (layoutId: string) => {
  if (!confirm('Are you sure you want to delete this layout?')) return

  try {
    await deletePageLayout(layoutId)
    layouts.value = layouts.value.filter(l => l.id !== layoutId)
    toast.success('Layout deleted successfully')
  } catch (e: any) {
    console.error('Error deleting layout:', e)
    toast.error('Failed to delete layout')
  }
}

const handleAccessUpdate = (orgWideDefault: string) => {
  if (object.value) {
    object.value.orgWideDefault = orgWideDefault
  }
}

// Watch for tab changes to load layouts
watch(activeTab, (newTab) => {
  if (newTab === 'layouts' && layouts.value.length === 0 && !loadingLayouts.value) {
    fetchLayouts()
  }
})

onMounted(async () => {
  await fetchObject()
  // If we start on layouts tab, load them
  if (activeTab.value === 'layouts') {
    await fetchLayouts()
  }
})
</script>
