<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import FieldRenderer from '@/components/fields/FieldRenderer.vue'
import PageLayoutRenderer from '@/components/PageLayoutRenderer.vue'
import { EditViewConfig, ViewMode, FieldSection, FieldConfig } from '@/types/field-types'
import { Save, X, ArrowLeft } from 'lucide-vue-next'
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@/components/ui/collapsible'
import type { PageLayoutConfig } from '~/types/page-layout'

interface Props {
  config: EditViewConfig
  data?: any
  loading?: boolean
  saving?: boolean
  objectId?: string // For fetching page layout
}

const props = withDefaults(defineProps<Props>(), {
  data: () => ({}),
  loading: false,
  saving: false,
})

const emit = defineEmits<{
  'save': [data: any]
  'cancel': []
  'back': []
}>()

const { getDefaultPageLayout } = usePageLayouts()
const pageLayout = ref<PageLayoutConfig | null>(null)
const loadingLayout = ref(false)

// Form data
const formData = ref<Record<string, any>>({ ...props.data })
const errors = ref<Record<string, string>>({})

// Watch for data changes (useful for edit mode)
watch(() => props.data, (newData) => {
  formData.value = { ...newData }
}, { deep: true })

// Fetch page layout if objectId is provided
onMounted(async () => {
  if (props.objectId) {
    try {
      loadingLayout.value = true
      const layout = await getDefaultPageLayout(props.objectId)
      if (layout) {
        // Handle both camelCase and snake_case
        pageLayout.value = layout.layoutConfig || layout.layout_config
      }
    } catch (error) {
      console.error('Error loading page layout:', error)
    } finally {
      loadingLayout.value = false
    }
  }
})

// Organize fields into sections
const sections = computed<FieldSection[]>(() => {
  if (props.config.sections && props.config.sections.length > 0) {
    return props.config.sections
  }
  
  // Default section with all visible fields
  const visibleFields = props.config.fields
    .filter(f => f.showOnEdit !== false)
    .map(f => f.apiName)
  
  return [{
    title: 'Details',
    fields: visibleFields,
  }]
})

const getFieldsBySection = (section: FieldSection) => {
  const fields = section.fields
    .map(apiName => props.config.fields.find(f => f.apiName === apiName))
    .filter((field): field is FieldConfig => field !== undefined)
  
  return fields
}

// Use page layout if available, otherwise fall back to sections
const usePageLayout = computed(() => {
  return pageLayout.value && pageLayout.value.fields && pageLayout.value.fields.length > 0
})

const validateField = (field: any): string | null => {
  const value = formData.value[field.apiName]
  
  // Required validation
  if (field.isRequired && (value === null || value === undefined || value === '')) {
    return `${field.label} is required`
  }
  
  // Custom validation rules
  if (field.validationRules) {
    for (const rule of field.validationRules) {
      switch (rule.type) {
        case 'required':
          if (value === null || value === undefined || value === '') {
            return rule.message || `${field.label} is required`
          }
          break
        case 'min':
          if (typeof value === 'number' && value < rule.value) {
            return rule.message || `${field.label} must be at least ${rule.value}`
          }
          if (typeof value === 'string' && value.length < rule.value) {
            return rule.message || `${field.label} must be at least ${rule.value} characters`
          }
          break
        case 'max':
          if (typeof value === 'number' && value > rule.value) {
            return rule.message || `${field.label} must be at most ${rule.value}`
          }
          if (typeof value === 'string' && value.length > rule.value) {
            return rule.message || `${field.label} must be at most ${rule.value} characters`
          }
          break
        case 'pattern':
          if (value && !new RegExp(rule.value).test(value)) {
            return rule.message || `${field.label} format is invalid`
          }
          break
      }
    }
  }
  
  return null
}

const validateForm = (): boolean => {
  errors.value = {}
  let isValid = true
  
  for (const field of props.config.fields) {
    if (field.showOnEdit === false) continue
    
    const error = validateField(field)
    if (error) {
      errors.value[field.apiName] = error
      isValid = false
    }
  }
  
  return isValid
}

const handleSave = () => {
  if (validateForm()) {
    emit('save', formData.value)
  }
}

const handleFieldUpdate = (fieldName: string, value: any) => {
  formData.value[fieldName] = value
  // Clear error for this field when user makes changes
  if (errors.value[fieldName]) {
    delete errors.value[fieldName]
  }
}
</script>

<template>
  <div class="edit-view-enhanced space-y-6">
    <!-- Header -->
    <div class="flex items-center justify-between">
      <div class="flex items-center gap-4">
        <Button variant="ghost" size="sm" @click="emit('back')">
          <ArrowLeft class="h-4 w-4 mr-2" />
          Back
        </Button>
        <div>
          <h2 class="text-2xl font-bold tracking-tight">
            {{ data?.id ? `Edit ${config.objectApiName}` : `New ${config.objectApiName}` }}
          </h2>
        </div>
      </div>

      <div class="flex items-center gap-2">
        <Button variant="outline" @click="emit('cancel')" :disabled="saving">
          <X class="h-4 w-4 mr-2" />
          Cancel
        </Button>
        <Button @click="handleSave" :disabled="saving || loading || loadingLayout">
          <Save class="h-4 w-4 mr-2" />
          {{ saving ? 'Saving...' : 'Save' }}
        </Button>
      </div>
    </div>

    <!-- Loading State -->
    <div v-if="loading || loadingLayout" class="flex items-center justify-center py-12">
      <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
    </div>

    <!-- Content with Page Layout -->
    <Card v-else-if="usePageLayout">
      <CardHeader>
        <CardTitle>{{ data?.id ? 'Edit Details' : 'New Record' }}</CardTitle>
      </CardHeader>
      <CardContent>
        <PageLayoutRenderer
          :fields="config.fields"
          :layout="pageLayout"
          :model-value="formData"
          :readonly="false"
          @update:model-value="formData = $event"
        />
        
        <!-- Display validation errors -->
        <div v-if="Object.keys(errors).length > 0" class="mt-4 p-4 bg-destructive/10 text-destructive rounded-md">
          <p class="font-semibold mb-2">Please fix the following errors:</p>
          <ul class="list-disc list-inside space-y-1">
            <li v-for="(error, field) in errors" :key="field">{{ error }}</li>
          </ul>
        </div>
      </CardContent>
    </Card>

    <!-- Traditional Section-based Layout -->
    <form v-else @submit.prevent="handleSave" class="space-y-6">
      <Card v-for="(section, idx) in sections" :key="idx">
        <Collapsible
          v-if="section.collapsible"
          :default-open="!section.defaultCollapsed"
        >
          <CardHeader>
            <CollapsibleTrigger class="flex items-center justify-between w-full hover:bg-muted/50 -m-2 p-2 rounded">
              <div>
                <CardTitle v-if="section.title">{{ section.title }}</CardTitle>
                <CardDescription v-if="section.description">
                  {{ section.description }}
                </CardDescription>
              </div>
            </CollapsibleTrigger>
          </CardHeader>
          <CollapsibleContent>
            <CardContent>
              <div class="grid gap-6 md:grid-cols-2">
                <div v-for="field in getFieldsBySection(section)" :key="field.id">
                  <FieldRenderer
                    :field="field"
                    :model-value="formData[field.apiName]"
                    :mode="ViewMode.EDIT"
                    :error="errors[field.apiName]"
                    @update:model-value="handleFieldUpdate(field.apiName, $event)"
                  />
                </div>
              </div>
            </CardContent>
          </CollapsibleContent>
        </Collapsible>

        <template v-else>
          <CardHeader v-if="section.title || section.description">
            <CardTitle v-if="section.title">{{ section.title }}</CardTitle>
            <CardDescription v-if="section.description">
              {{ section.description }}
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div class="grid gap-6 md:grid-cols-2">
              <div v-for="field in getFieldsBySection(section)" :key="field?.id">
                <FieldRenderer
                  :field="field"
                  :model-value="formData[field.apiName]"
                  :mode="ViewMode.EDIT"
                  :error="errors[field.apiName]"
                  @update:model-value="handleFieldUpdate(field.apiName, $event)"
                />
              </div>
            </div>
          </CardContent>
        </template>
      </Card>

      <!-- Display validation errors -->
      <div v-if="Object.keys(errors).length > 0" class="p-4 bg-destructive/10 text-destructive rounded-md">
        <p class="font-semibold mb-2">Please fix the following errors:</p>
        <ul class="list-disc list-inside space-y-1">
          <li v-for="(error, field) in errors" :key="field">{{ error }}</li>
        </ul>
      </div>
    </form>
  </div>
</template>

<style scoped>
.edit-view-enhanced {
  width: 100%;
}
</style>
