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

interface Props {
  config: EditViewConfig
  data?: any
  loading?: boolean
  saving?: boolean
}

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

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

// 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 })

// 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(Boolean)
  
  return fields
}

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 'email':
          if (value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
            return rule.message || `${field.label} must be a valid email`
          }
          break
        case 'url':
          if (value && !/^https?:\/\/.+/.test(value)) {
            return rule.message || `${field.label} must be a valid URL`
          }
          break
        case 'pattern':
          if (value && !new RegExp(rule.value).test(value)) {
            return rule.message || `${field.label} has invalid format`
          }
          break
      }
    }
  }
  
  return null
}

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

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

const handleCancel = () => {
  formData.value = { ...props.data }
  errors.value = {}
  emit('cancel')
}

const updateFieldValue = (apiName: string, value: any) => {
  formData.value[apiName] = value
  // Clear error for this field when user starts editing
  if (errors.value[apiName]) {
    delete errors.value[apiName]
  }
}
</script>

<template>
  <div class="edit-view 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' : 'Create' }} {{ config.objectApiName }}
          </h2>
        </div>
      </div>

      <div class="flex items-center gap-2">
        <Button variant="outline" @click="handleCancel" :disabled="saving">
          <X class="h-4 w-4 mr-2" />
          {{ config.cancelLabel || 'Cancel' }}
        </Button>
        <Button @click="handleSave" :disabled="saving">
          <Save class="h-4 w-4 mr-2" />
          {{ config.submitLabel || 'Save' }}
        </Button>
      </div>
    </div>

    <!-- Loading State -->
    <div v-if="loading" 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>

    <!-- Form Sections -->
    <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"
                  class="space-y-1"
                >
                  <FieldRenderer
                    :field="field"
                    :model-value="formData[field.apiName]"
                    :mode="ViewMode.EDIT"
                    @update:model-value="updateFieldValue(field.apiName, $event)"
                  />
                  <p v-if="errors[field.apiName]" class="text-sm text-destructive">
                    {{ errors[field.apiName] }}
                  </p>
                </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"
                class="space-y-1"
              >
                <FieldRenderer
                  :field="field"
                  :model-value="formData[field.apiName]"
                  :mode="ViewMode.EDIT"
                  @update:model-value="updateFieldValue(field.apiName, $event)"
                />
                <p v-if="errors[field.apiName]" class="text-sm text-destructive">
                  {{ errors[field.apiName] }}
                </p>
              </div>
            </div>
          </CardContent>
        </template>
      </Card>

      <!-- Hidden submit button for form submission -->
      <button type="submit" class="hidden" />
    </form>

    <!-- Save indicator -->
    <div v-if="saving" class="fixed bottom-4 right-4 bg-primary text-primary-foreground px-4 py-2 rounded-lg shadow-lg flex items-center gap-2">
      <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-primary-foreground"></div>
      <span>Saving...</span>
    </div>
  </div>
</template>

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