<template>
  <div>
    <v-row>
      <v-col cols="12">
        <h1 class="text-h3 mb-4">Schema Refs</h1>
        <p class="text-subtitle-1 text-grey mb-4">
          View and manage different versions of your federated GraphQL schemas
        </p>
      </v-col>
    </v-row>

    <v-row v-if="!auth0.isAuthenticated.value">
      <v-col cols="12">
        <v-alert type="info" variant="tonal">
          Please log in to view schema refs.
        </v-alert>
      </v-col>
    </v-row>

    <v-row v-else-if="loading?.value">
      <v-col cols="12" class="text-center">
        <v-progress-circular indeterminate size="64" />
        <p class="mt-4">Loading refs...</p>
      </v-col>
    </v-row>

    <v-row v-else-if="error?.value">
      <v-col cols="12">
        <v-alert type="error" variant="tonal">
          Error loading refs: {{ error?.value?.message }}
        </v-alert>
      </v-col>
    </v-row>

    <v-row v-else-if="refs.length === 0">
      <v-col cols="12" class="text-center py-12">
        <v-icon icon="mdi-source-branch" size="64" class="mb-4 text-grey" />
        <p class="text-h6 text-grey">No refs found</p>
        <p class="text-grey">Create an API key with refs to get started</p>
      </v-col>
    </v-row>

    <v-row v-else>
      <v-col
        v-for="ref in refs"
        :key="ref.name"
        cols="12"
        md="6"
        lg="4"
      >
        <v-card hover>
          <v-card-title class="d-flex align-center">
            <v-icon icon="mdi-source-branch" class="mr-2" />
            {{ ref.name }}
          </v-card-title>
          <v-card-text>
            <v-list density="compact">
              <v-list-item>
                <v-list-item-title>Subgraphs</v-list-item-title>
                <v-list-item-subtitle>{{ ref.subgraphCount }}</v-list-item-subtitle>
              </v-list-item>
              <v-list-item>
                <v-list-item-title>Last Updated</v-list-item-title>
                <v-list-item-subtitle>{{ ref.lastUpdate }}</v-list-item-subtitle>
              </v-list-item>
              <v-list-item>
                <v-list-item-title>Status</v-list-item-title>
                <template #append>
                  <v-chip :color="ref.status === 'healthy' ? 'success' : 'warning'" size="small">
                    {{ ref.status }}
                  </v-chip>
                </template>
              </v-list-item>
            </v-list>
          </v-card-text>
          <v-card-actions>
            <v-btn variant="text" color="primary" @click="viewSupergraph(ref.name)">
              View Supergraph
            </v-btn>
            <v-spacer />
            <v-btn icon="mdi-download" variant="text" @click="downloadSupergraph(ref.name)" />
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>

    <v-dialog v-model="dialog" max-width="900">
      <v-card>
        <v-card-title class="d-flex justify-space-between align-center">
          <span>Supergraph - {{ selectedRef }}</span>
          <v-btn icon="mdi-close" variant="text" @click="dialog = false" />
        </v-card-title>
        <v-card-text>
          <pre class="sdl-viewer"><code>{{ supergraph }}</code></pre>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn
            prepend-icon="mdi-content-copy"
            variant="text"
            @click="copySupergraph"
          >
            Copy
          </v-btn>
          <v-btn
            prepend-icon="mdi-download"
            variant="text"
            color="primary"
            @click="downloadSupergraph(selectedRef)"
          >
            Download
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-snackbar v-model="snackbar" :timeout="2000">
      {{ snackbarText }}
    </v-snackbar>
  </div>
</template>

<script setup lang="ts">
import { useAuth0 } from '@auth0/auth0-vue'

import { useOrganizationSelector } from '~/composables/useOrganizationSelector'
import {
  useLatestSchemaQuery,
  useSupergraphQuery,
} from '~/graphql/generated'

const auth0 = useAuth0()
const { selectedOrganization, loading, error } = useOrganizationSelector()

const dialog = ref(false)
const selectedRef = ref<string | null>(null)
const supergraph = ref('')
const snackbar = ref(false)
const snackbarText = ref('')

// Supergraph query - only runs when selectedRef is set
const supergraphQuery = useSupergraphQuery(() => ({
  ref: selectedRef.value || '',
  isAfter: null,
}), () => ({
  skip: !selectedRef.value,
}))

// Watch for supergraph query results
watch(() => supergraphQuery.result.value, (data) => {
  if (data?.supergraph) {
    if (data.supergraph.__typename === 'SubGraphs') {
      supergraph.value = data.supergraph.sdl || '# No supergraph available'
    } else if (data.supergraph.__typename === 'Unchanged') {
      supergraph.value = `# Supergraph unchanged (ID: ${data.supergraph.id})\n# Please retry after ${data.supergraph.minDelaySeconds} seconds`
    }
  }
})

// Watch for supergraph query errors
watch(() => supergraphQuery.error.value, (err) => {
  if (err) {
    supergraph.value = `# Error loading supergraph\n# ${err.message || 'Unknown error'}`
    snackbarText.value = 'Failed to load supergraph'
    snackbar.value = true
  }
})

// Get available refs from the selected organization
const refNames = computed(() => {
  if (!selectedOrganization.value) return []

  const allRefs = new Set<string>()
  selectedOrganization.value.apiKeys?.forEach(key => {
    key.refs?.forEach(ref => allRefs.add(ref))
  })

  return Array.from(allRefs)
})

// Create reactive queries for each ref
const refQueries = computed(() => {
  if (!auth0.isAuthenticated.value) return {}

  const queries: Record<string, any> = {}
  refNames.value.forEach(ref => {
    queries[ref] = useLatestSchemaQuery(() => ({
      ref,
    }), () => ({
      skip: !auth0.isAuthenticated.value,
    }))
  })
  return queries
})

const refs = computed(() => {
  return refNames.value.map(refName => {
    const query = refQueries.value[refName]
    const latestSchema = query?.result?.value?.latestSchema

    return {
      name: refName,
      subgraphCount: latestSchema?.subGraphs?.length || 0,
      lastUpdate: latestSchema?.subGraphs?.[0]?.changedAt
        ? new Date(latestSchema.subGraphs[0].changedAt).toLocaleString()
        : 'N/A',
      status: query?.loading?.value ? 'loading' : (query?.error?.value ? 'error' : 'healthy'),
    }
  })
})

const viewSupergraph = (refName: string) => {
  selectedRef.value = refName
  supergraph.value = '# Loading...'
  dialog.value = true
}

const downloadSupergraph = (refName: string) => {
  const blob = new Blob([supergraph.value || '# Loading...'], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `supergraph-${refName}.graphql`
  a.click()
  URL.revokeObjectURL(url)

  snackbarText.value = 'Supergraph downloaded'
  snackbar.value = true
}

const copySupergraph = async () => {
  try {
    await navigator.clipboard.writeText(supergraph.value)
    snackbarText.value = 'Supergraph copied to clipboard'
    snackbar.value = true
  } catch (_err) {
    snackbarText.value = 'Failed to copy'
    snackbar.value = true
  }
}
</script>

<style scoped>
.sdl-viewer {
  background: #f5f5f5;
  padding: 16px;
  border-radius: 4px;
  overflow-x: auto;
  font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
  font-size: 14px;
  line-height: 1.5;
  max-height: 60vh;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
</style>
