<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useSemanticModelsStore } from '@/stores/semantic-models'
import { formatDateTime } from '@/lib/utils'
import { toast } from 'vue-sonner'
import ConfirmDialog from '@/components/ConfirmDialog.vue'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import SearchSelect from '@/components/SearchSelect.vue'
import DkuSpinner from '@/components/DkuSpinner.vue'
import type { SemanticModelVersion } from '@/types'

const props = defineProps<{
  open: boolean
  modelId: string
  currentVersionId: string
}>()

const emit = defineEmits<{
  'update:open': [value: boolean]
  select: [versionId: string]
  create: []
}>()

const store = useSemanticModelsStore()
const searchQuery = ref('')
const sortBy = ref<'version' | 'created'>('version')

const sortOptions = [
  { value: 'version', label: 'Version number' },
  { value: 'created', label: 'Recently created' },
]

// Delete confirmation dialog state
const showDeleteDialog = ref(false)
const versionToDelete = ref<SemanticModelVersion | null>(null)

// Load model when modal opens
watch(
  () => props.open,
  async (isOpen) => {
    if (isOpen && props.modelId) {
      searchQuery.value = ''
      await store.loadModel(props.modelId)
    }
  }
)

// Helper to extract numeric portion from version ID (e.g., "v1" -> 1)
function getVersionNumber(versionId: string): number {
  return parseInt(versionId.replace(/\D/g, '') || '0', 10)
}

const sortedVersions = computed(() => {
  if (!store.currentModel?.versions) return []

  let versions = [...store.currentModel.versions]

  // Filter by search query
  if (searchQuery.value.trim()) {
    const query = searchQuery.value.toLowerCase()
    versions = versions.filter(
      (v) =>
        v.description?.toLowerCase().includes(query) ||
        v.id.toLowerCase().includes(query)
    )
  }

  // Sort
  if (sortBy.value === 'version') {
    versions.sort((a, b) => getVersionNumber(b.id) - getVersionNumber(a.id))
  } else {
    versions.sort(
      (a, b) =>
        new Date(b.created?.on || 0).getTime() - new Date(a.created?.on || 0).getTime()
    )
  }

  return versions
})

const hasVersions = computed(() => {
  return (store.currentModel?.versions?.length || 0) > 0
})

function isActiveVersion(versionId: string): boolean {
  return store.isActiveVersion(versionId)
}

function handleSelect(version: SemanticModelVersion) {
  emit('select', version.id)
  emit('update:open', false)
}

async function handleCreate() {
  try {
    const newVersion = await store.createVersion(props.modelId)
    toast.success(`Created ${newVersion.id}`)
    emit('select', newVersion.id)
    emit('update:open', false)
  } catch (e) {
    toast.error('Failed to create version')
  }
}

async function handleDuplicate(version: SemanticModelVersion) {
  try {
    const newVersion = await store.createVersion(props.modelId, {
      fromVersion: version.id,
    })
    toast.success(`Duplicated ${version.id} to ${newVersion.id}`)
    emit('select', newVersion.id)
    emit('update:open', false)
  } catch (e) {
    toast.error('Failed to duplicate version')
  }
}

async function handleSetActive(version: SemanticModelVersion) {
  try {
    await store.setActiveVersion(props.modelId, version.id)
    toast.success(`${version.id} is now active`)
  } catch (e) {
    toast.error('Failed to set active version')
  }
}

function canDeleteVersion(version: SemanticModelVersion): boolean {
  // Cannot delete active version or the last version
  return (
    !store.isActiveVersion(version.id) && sortedVersions.value.length > 1
  )
}

function openDeleteDialog(version: SemanticModelVersion) {
  versionToDelete.value = version
  showDeleteDialog.value = true
}

async function handleConfirmDelete() {
  if (!versionToDelete.value) return

  try {
    const versionId = versionToDelete.value.id
    const wasCurrentVersion = versionId === props.currentVersionId

    await store.deleteVersion(props.modelId, versionId)
    toast.success(`Deleted ${versionId}`)

    // If we deleted the version we were viewing, redirect to another version
    if (wasCurrentVersion && store.currentModel?.versions.length) {
      const targetVersion = store.activeVersion
      if (targetVersion) {
        emit('select', targetVersion.id)
      }
    }
    emit('update:open', false)
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } }
    toast.error(err.response?.data?.error || 'Failed to delete version')
  } finally {
    versionToDelete.value = null
  }
}

function handleClose() {
  emit('update:open', false)
}

function getEntityCount(version: SemanticModelVersion): number | null {
  return Array.isArray(version.entities) ? version.entities.length : null
}

function getRelationshipCount(version: SemanticModelVersion): number | null {
  return Array.isArray(version.relationships) ? version.relationships.length : null
}

function getLastSavedAt(version: SemanticModelVersion): string | null {
  const raw = version.privateEditorData?.lastSavedAt
  if (typeof raw !== 'string' || !raw) return null
  const formatted = formatDateTime(raw)
  return formatted || null
}

function getDuplicateSource(version: SemanticModelVersion): string | null {
  const raw = version.privateEditorData?.duplicatedFromVersionId
  return typeof raw === 'string' && raw ? raw : null
}
</script>

<template>
  <Teleport to="body">
    <div
      v-if="open"
      class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
      @click.self="handleClose"
    >
      <div
        class="flex w-full max-w-2xl flex-col rounded-lg bg-background shadow-lg"
        style="max-height: 85vh"
      >
        <!-- Header -->
        <div class="flex items-center justify-between border-b px-6 py-4">
          <h2 class="title-444">Choose a version</h2>
          <div class="flex items-center gap-2">
            <button
              v-if="hasVersions"
              class="btn-primary inline-flex items-center gap-2"
              @click="handleCreate"
            >
              <i class="dku-icon-plus-16" />
              Create version
            </button>
            <button
              class="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
              @click="handleClose"
            >
              <i class="dku-icon-dismiss-20" />
            </button>
          </div>
        </div>

        <!-- Search & Sort -->
        <div class="flex items-center gap-4 border-b px-6 py-3">
          <div class="relative flex-1">
            <i
              class="dku-icon-search-16 absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground"
            />
            <input
              v-model="searchQuery"
              type="text"
              placeholder="Search a version..."
              class="placeholder-555 h-8 w-full rounded-md border border-input bg-background pl-10 pr-4 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
            />
          </div>
          <div class="flex items-center gap-2 whitespace-nowrap">
            <span class="body-333">Sort by</span>
            <SearchSelect
              :model-value="sortBy"
              :options="sortOptions"
              placeholder="Sort by..."
              search-placeholder="Search..."
              empty-text="No options"
              @update:model-value="(val: string) => sortBy = val as 'version' | 'created'"
            />
          </div>
        </div>

        <!-- Content -->
        <div class="flex-1 overflow-auto p-6">
          <!-- Loading -->
          <div v-if="store.isLoading" class="flex items-center justify-center py-12">
            <DkuSpinner size="xl" />
          </div>

          <!-- Empty state -->
          <div
            v-else-if="sortedVersions.length === 0 && !searchQuery"
            class="flex flex-col items-center justify-center py-12"
          >
            <p class="text-muted-foreground">No versions yet</p>
            <button
              class="btn-primary mt-4 inline-flex items-center gap-2"
              @click="handleCreate"
            >
              <i class="dku-icon-plus-16" />
              Create first version
            </button>
          </div>

          <!-- No search results -->
          <div
            v-else-if="sortedVersions.length === 0 && searchQuery"
            class="flex flex-col items-center justify-center py-12"
          >
            <p class="text-muted-foreground">No versions found for "{{ searchQuery }}"</p>
          </div>

          <!-- Version list -->
          <div v-else class="space-y-3">
            <div
              v-for="version in sortedVersions"
              :key="version.id"
              class="cursor-pointer rounded-lg border-2 bg-card p-4 transition-all hover:border-active"
              :class="{
                'border-active': version.id === currentVersionId,
                'border-transparent': version.id !== currentVersionId,
              }"
              @click="handleSelect(version)"
            >
              <div class="flex items-start justify-between">
                <div class="flex items-start gap-4">
                  <!-- Version badge -->
                  <div
                    class="flex h-12 w-12 items-center justify-center rounded-lg bg-primary/10"
                  >
                    <span class="text-lg font-bold text-primary"
                      >{{ version.id }}</span
                    >
                  </div>

                  <div>
                    <div class="flex items-center gap-2">
                      <h3 class="tile-title-222">
                        {{ `Version ${version.id}` }}
                      </h3>

                      <!-- Active badge -->
                      <span
                        v-if="isActiveVersion(version.id)"
                        class="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary"
                      >
                        <i class="dku-icon-checkmark-circle-12" />
                        Active
                      </span>
                    </div>

                    <p
                      v-if="version.description"
                      class="subs-333 mt-1"
                    >
                      {{ version.description }}
                    </p>

                    <div
                      class="subs-333 mt-2 flex items-center gap-4"
                    >
                      <span v-if="version.created?.on">Created {{ formatDateTime(version.created.on) }}</span>
                      <span v-if="version.created?.by">by {{ version.created.by }}</span>
                      <span v-if="getDuplicateSource(version)">Duplicated from {{ getDuplicateSource(version) }}</span>
                      <span v-if="getLastSavedAt(version)">Last saved {{ getLastSavedAt(version) }}</span>
                      <span
                        v-if="getEntityCount(version) !== null && getRelationshipCount(version) !== null"
                        >{{ getEntityCount(version) }} entities &bull;
                        {{ getRelationshipCount(version) }} relationships</span
                      >
                    </div>
                  </div>
                </div>

                <!-- Actions -->
                <div class="flex items-center gap-1" @click.stop>
                  <!-- Duplicate -->
                  <Tooltip>
                    <TooltipTrigger as-child>
                      <button
                        class="rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-foreground"
                        @click="handleDuplicate(version)"
                      >
                        <i class="dku-icon-copy-16" />
                      </button>
                    </TooltipTrigger>
                    <TooltipContent>Duplicate version</TooltipContent>
                  </Tooltip>

                  <!-- Set Active -->
                  <Tooltip v-if="!isActiveVersion(version.id)">
                    <TooltipTrigger as-child>
                      <button
                        class="rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-foreground"
                        @click="handleSetActive(version)"
                      >
                        <i class="dku-icon-checkmark-circle-outline-16" />
                      </button>
                    </TooltipTrigger>
                    <TooltipContent>Set as active</TooltipContent>
                  </Tooltip>

                  <!-- Delete -->
                  <Tooltip v-if="canDeleteVersion(version)">
                    <TooltipTrigger as-child>
                      <button
                        class="rounded-md p-2 text-destructive hover:bg-destructive/10"
                        @click="openDeleteDialog(version)"
                      >
                        <i class="dku-icon-trash-16" />
                      </button>
                    </TooltipTrigger>
                    <TooltipContent>Delete version</TooltipContent>
                  </Tooltip>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Delete Confirmation Dialog -->
    <ConfirmDialog
      v-model:open="showDeleteDialog"
      title="Delete Version"
      :description="`Are you sure you want to delete version ${versionToDelete?.id}? This action cannot be undone.`"
      confirm-text="Delete"
      cancel-text="Cancel"
      variant="destructive"
      @confirm="handleConfirmDelete"
    />
  </Teleport>
</template>
