<template>
  <UModal :open="open" :title="$t('versions.compare')" @update:open="$emit('update:open', $event)">
    <template #header>
      <h3 class="text-lg font-semibold">{{ $t('versions.comparisonTitle', { number: versionNumber }) }}</h3>
    </template>

    <template #body>
      <div v-if="loading" class="flex justify-center py-8">
        <UIcon name="i-lucide-loader-circle" class="animate-spin h-8 w-8" />
      </div>

      <div v-else-if="error" class="text-red-500">{{ $t('versions.comparisonError') }}: {{ error }}</div>

      <div v-else-if="valueDiff && hasChanges" class="space-y-4">
        <!-- Summary Alert -->
        <UAlert
          :title="$t('versions.changesSummary', { count: totalChanges })"
          :icon="totalChanges > 0 ? 'i-lucide-file-diff' : 'i-lucide-check'"
          color="info"
          variant="subtle"
        />

        <!-- Changes grouped by section -->
        <UAccordion
          v-if="sectionChanges.length > 0"
          :items="accordionItems"
          type="multiple"
          :default-value="accordionItems.map((_, i) => String(i))"
        >
          <template #body="{ item }">
            <div class="space-y-3">
              <div
                v-for="(change, changeIdx) in item.changes"
                :key="changeIdx"
                class="rounded-lg border border-default bg-elevated/50 p-3"
              >
                <!-- Element title with type indicator -->
                <div class="flex items-center gap-2 mb-2">
                  <UIcon v-if="change.elementType === 'TABLE'" name="i-lucide-table" class="h-4 w-4 text-muted" />
                  <span class="font-medium text-sm">{{
                    change.elementTitle || $t('versions.elementWithoutTitle')
                  }}</span>

                  <!-- Change type badge -->
                  <UBadge v-if="isNewAnswer(change)" color="success" variant="subtle" size="xs">
                    {{ $t('versions.newAnswer') }}
                  </UBadge>
                  <UBadge v-else-if="isClearedAnswer(change)" color="warning" variant="subtle" size="xs">
                    {{ $t('versions.clearedAnswer') }}
                  </UBadge>
                  <UBadge v-else color="info" variant="subtle" size="xs">
                    {{ $t('versions.changedAnswer') }}
                  </UBadge>
                </div>

                <!-- Table diff display -->
                <div v-if="change.elementType === 'TABLE' && change.tableDiff" class="mt-3">
                  <!-- Table summary -->
                  <div class="flex items-center gap-4 text-xs text-muted mb-2">
                    <span v-if="change.tableDiff.addedCount > 0" class="text-success">
                      +{{ change.tableDiff.addedCount }} {{ $t('versions.tableRowsAdded') }}
                    </span>
                    <span v-if="change.tableDiff.removedCount > 0" class="text-error">
                      -{{ change.tableDiff.removedCount }} {{ $t('versions.tableRowsRemoved') }}
                    </span>
                    <span v-if="change.tableDiff.modifiedCount > 0" class="text-warning">
                      ~{{ change.tableDiff.modifiedCount }} {{ $t('versions.tableRowsModified') }}
                    </span>
                  </div>

                  <!-- Scrollable table container -->
                  <div class="overflow-x-auto border border-default rounded-lg">
                    <table class="min-w-full text-xs">
                      <thead class="bg-elevated">
                        <tr>
                          <th
                            class="px-3 py-2 text-left font-medium text-muted whitespace-nowrap left-0 bg-elevated z-10"
                          >
                            #
                          </th>
                          <th
                            class="px-3 py-2 text-left font-medium text-muted whitespace-nowrap left-8 bg-elevated z-10"
                          >
                            {{ $t('versions.tableStatus') }}
                          </th>
                          <th
                            v-for="col in change.tableDiff.columns"
                            :key="col"
                            class="px-3 py-2 text-left font-medium text-muted whitespace-nowrap"
                          >
                            {{ col }}
                          </th>
                        </tr>
                      </thead>
                      <tbody class="divide-y divide-default">
                        <template v-for="row in change.tableDiff.rows" :key="row.rowIndex">
                          <!-- Show only changed rows (added, removed, modified) -->
                          <tr v-if="row.changeType !== 'unchanged'" :class="getRowClass(row.changeType)">
                            <td
                              class="px-3 py-2 text-muted whitespace-nowrap left-0 z-10"
                              :class="getRowBgClass(row.changeType)"
                            >
                              {{ row.rowIndex + 1 }}
                            </td>
                            <td class="px-3 py-2 whitespace-nowrap left-8 z-10" :class="getRowBgClass(row.changeType)">
                              <UBadge :color="getStatusBadgeColor(row.changeType)" variant="subtle" size="xs">
                                {{ getStatusLabel(row.changeType) }}
                              </UBadge>
                            </td>
                            <td v-for="col in change.tableDiff.columns" :key="col" class="px-3 py-2 whitespace-nowrap">
                              <template v-if="row.changeType === 'added'">
                                <span class="text-success">{{ row.currentValues[col] || '-' }}</span>
                              </template>
                              <template v-else-if="row.changeType === 'removed'">
                                <span class="text-error line-through">{{ row.previousValues[col] || '-' }}</span>
                              </template>
                              <template v-else-if="row.changeType === 'modified'">
                                <div v-if="row.previousValues[col] !== row.currentValues[col]" class="space-y-0.5">
                                  <div class="text-error line-through text-[10px]">
                                    {{ row.previousValues[col] || '-' }}
                                  </div>
                                  <div class="text-success">{{ row.currentValues[col] || '-' }}</div>
                                </div>
                                <span v-else class="text-muted">{{ row.currentValues[col] || '-' }}</span>
                              </template>
                            </td>
                          </tr>
                        </template>
                      </tbody>
                    </table>
                  </div>
                </div>

                <!-- Non-table Before/After display -->
                <div v-else class="space-y-2 text-sm">
                  <!-- Previous value -->
                  <div class="flex items-start gap-2">
                    <div class="flex items-center gap-1.5 text-muted min-w-[60px] shrink-0">
                      <UIcon name="i-lucide-circle" class="h-3 w-3 text-muted" />
                      <span>{{ $t('versions.before') }}:</span>
                    </div>
                    <span :class="change.previousLabel ? 'text-default' : 'text-muted italic'">
                      {{ change.previousLabel || $t('versions.noValue') }}
                    </span>
                  </div>

                  <!-- Arrow indicator -->
                  <div class="flex items-center gap-2 pl-1">
                    <UIcon name="i-lucide-arrow-down" class="h-3 w-3 text-muted" />
                  </div>

                  <!-- Current value -->
                  <div class="flex items-start gap-2">
                    <div class="flex items-center gap-1.5 text-primary min-w-[60px] shrink-0">
                      <UIcon name="i-lucide-circle-dot" class="h-3 w-3" />
                      <span>{{ $t('versions.after') }}:</span>
                    </div>
                    <span :class="change.currentLabel ? 'text-default font-medium' : 'text-muted italic'">
                      {{ change.currentLabel || $t('versions.noValue') }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </UAccordion>
      </div>

      <div v-else class="text-center py-8">
        <UIcon name="i-lucide-check-circle" class="h-12 w-12 text-success mx-auto mb-3" />
        <p class="text-muted">{{ $t('versions.noChanges') }}</p>
      </div>
    </template>

    <template #footer>
      <div class="flex justify-end">
        <UButton :label="$t('common.close')" color="neutral" variant="outline" @click="$emit('update:open', false)" />
      </div>
    </template>
  </UModal>
</template>

<script setup lang="ts">
import type { AccordionItem } from '@nuxt/ui'
import type { ApplicationFormDto, ApplicationFormVersionDto } from '~~/.api-client'
import type { FormValueDiff, ValueChange, SectionChanges, TableRowDiff } from '~~/types/formDiff'
import { compareApplicationFormValues, groupChangesBySection } from '~/utils/formDiff'

const props = defineProps<{
  open: boolean
  currentForm: ApplicationFormDto
  versionNumber: number
  applicationFormId: string
}>()

defineEmits<{
  (e: 'update:open', value: boolean): void
}>()

const { getVersion } = useApplicationFormVersion()
const { t: $t } = useI18n()

const loading = ref(false)
const error = ref<string | null>(null)
const valueDiff = ref<FormValueDiff | null>(null)
const versionData = ref<ApplicationFormVersionDto | null>(null)

const sectionChanges = computed<SectionChanges[]>(() => {
  if (!valueDiff.value) return []
  return groupChangesBySection(valueDiff.value)
})

const totalChanges = computed(() => {
  if (!valueDiff.value) return 0
  return (
    valueDiff.value.newAnswers.length + valueDiff.value.changedAnswers.length + valueDiff.value.clearedAnswers.length
  )
})

const hasChanges = computed(() => totalChanges.value > 0)

interface AccordionItemWithChanges extends AccordionItem {
  changes: ValueChange[]
}

const accordionItems = computed<AccordionItemWithChanges[]>(() => {
  return sectionChanges.value.map((section, index) => ({
    label: `${section.sectionTitle} (${$t('versions.changesCount', { count: section.changes.length })})`,
    icon: 'i-lucide-folder',
    value: String(index),
    changes: section.changes
  }))
})

function isNewAnswer(change: ValueChange): boolean {
  return !change.previousLabel && !!change.currentLabel
}

function isClearedAnswer(change: ValueChange): boolean {
  return !!change.previousLabel && !change.currentLabel
}

function getRowClass(changeType: TableRowDiff['changeType']): string {
  switch (changeType) {
    case 'added':
      return 'bg-success/5'
    case 'removed':
      return 'bg-error/5'
    case 'modified':
      return 'bg-warning/5'
    default:
      return ''
  }
}

function getRowBgClass(changeType: TableRowDiff['changeType']): string {
  switch (changeType) {
    case 'added':
      return 'bg-success/10'
    case 'removed':
      return 'bg-error/10'
    case 'modified':
      return 'bg-warning/10'
    default:
      return 'bg-elevated'
  }
}

function getStatusBadgeColor(changeType: TableRowDiff['changeType']): 'success' | 'error' | 'warning' | 'neutral' {
  switch (changeType) {
    case 'added':
      return 'success'
    case 'removed':
      return 'error'
    case 'modified':
      return 'warning'
    default:
      return 'neutral'
  }
}

function getStatusLabel(changeType: TableRowDiff['changeType']): string {
  switch (changeType) {
    case 'added':
      return $t('versions.rowAdded')
    case 'removed':
      return $t('versions.rowRemoved')
    case 'modified':
      return $t('versions.rowModified')
    default:
      return ''
  }
}

// Track which version was loaded to detect when we need to reload
const loadedVersionNumber = ref<number | null>(null)

watch(
  () => props.open,
  async (isOpen) => {
    if (isOpen) {
      // Always load if version changed or no data loaded yet
      if (loadedVersionNumber.value !== props.versionNumber || !versionData.value) {
        await loadVersionAndCompare()
      }
    }
  },
  { immediate: true }
)

// Also reload when version number changes while modal is open
watch(
  () => props.versionNumber,
  async (newVersion, oldVersion) => {
    if (newVersion !== oldVersion && props.open) {
      await loadVersionAndCompare()
    }
  }
)

async function loadVersionAndCompare() {
  loading.value = true
  error.value = null
  valueDiff.value = null // Reset diff while loading
  try {
    versionData.value = await getVersion(props.applicationFormId, props.versionNumber)
    valueDiff.value = compareApplicationFormValues(props.currentForm, versionData.value.snapshot)
    loadedVersionNumber.value = props.versionNumber
  } catch (e: unknown) {
    error.value = e instanceof Error ? e.message : $t('versions.unknownError')
  } finally {
    loading.value = false
  }
}
</script>
