<template>
  <div class="search-results">
    <div class="page-header">
      <h2>Search Results</h2>
      <span v-if="results.length" class="results-count">
        {{ totalAll || results.length }} result{{ (totalAll || results.length) !== 1 ? 's' : '' }} for "{{ query }}"
      </span>
    </div>

    <div class="search-box">
      <input
        v-model="searchInput"
        type="text"
        class="form-control"
        placeholder="Search machines, applications, knowledge base, IPs, hostnames..."
        @keyup.enter="performSearch"
      />
      <button class="btn btn-primary" @click="performSearch">Search</button>
    </div>

    <div v-if="results.length" class="filter-buttons">
      <button
        v-for="filter in filterList"
        :key="filter.key"
        class="filter-btn"
        :class="{ active: activeFilter === filter.key }"
        @click="activeFilter = filter.key"
      >
        {{ filter.label }}
        <span class="filter-count">{{ getFilterCount(filter.key) }}</span>
      </button>
    </div>

    <div class="card">
      <div v-if="loading" class="loading">Searching...</div>

      <template v-else-if="query">
        <div v-if="filteredResults.length === 0 && results.length > 0" class="no-results">
          No {{ activeFilter }} results for "{{ query }}"
          <button class="btn btn-secondary" style="margin-top: 0.5rem;" @click="activeFilter = 'all'">Show all results</button>
        </div>

        <div v-else-if="results.length === 0" class="no-results">
          No results found for "{{ query }}"
          <SearchSuggestion :suggestion="suggestion" @pick="applySuggestion" />
        </div>

        <div v-else class="results-list">
          <div
            v-for="result in filteredResults"
            :key="`${result.type}-${result.id}`"
            :id="`result-${result.type}-${result.id}`"
            class="result-item"
            :class="{ highlighted: highlightId === `${result.type}-${result.id}` }"
          >
            <span class="result-type" :class="result.type">{{ typeLabel(result.type) }}</span>
            <div class="result-content">
              <router-link v-if="result.type !== 'knowledgebase'" :to="result.url" class="result-title">
                {{ result.title }}
              </router-link>
              <a
                v-else
                href="#"
                class="result-title"
                @click.prevent="openKBArticle(result)"
              >
                {{ result.title }}
              </a>
              <div class="result-meta">
                <span v-if="result.subtitle" class="result-subtitle">{{ result.subtitle }}</span>
                <span v-if="result.location" class="result-location">{{ result.location }}</span>
                <span v-if="result.ticketnumber" class="result-ticket">{{ result.ticketnumber }}</span>
                <span v-if="result.iscurrent" class="badge badge-success">Active</span>
              </div>
            </div>
            <button
              class="share-btn"
              @click="shareResult(result)"
              :title="copiedId === `${result.type}-${result.id}` ? 'Copied!' : 'Copy link'"
            >
              {{ copiedId === `${result.type}-${result.id}` ? 'Copied' : 'Share' }}
            </button>
          </div>
        </div>
      </template>

      <div v-else class="no-results">
        Enter a search term to find machines, applications, printers, knowledge base articles, IPs, and more.
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { searchApi, knowledgebaseApi } from '../api'
import SearchSuggestion from '../components/SearchSuggestion.vue'

const route = useRoute()
const router = useRouter()

const loading = ref(false)
const results = ref([])
const suggestion = ref(null)
const query = ref('')
const searchInput = ref('')
const activeFilter = ref('all')
const typeCounts = ref({})
const totalAll = ref(0)
const highlightId = ref(null)
const copiedId = ref(null)

const typeLabels = {
  machine: 'Machine',
  pc: 'PC',
  computer: 'PC',
  application: 'App',
  knowledgebase: 'KB',
  printer: 'Printer',
  network_device: 'Network',
  measuring_tool: 'Measuring Tool',
  employee: 'Employee',
  notification: 'Notice',
  subnet: 'Subnet',
  usb_device: 'USB',
  printed_item: 'Printed Part'
}

const filterTypeMap = {
  all: null,
  machines: ['machine'],
  computers: ['computer'],
  printers: ['printer'],
  network: ['network_device', 'subnet'],
  measuringtools: ['measuring_tool'],
  applications: ['application'],
  knowledgebase: ['knowledgebase'],
  notifications: ['notification'],
  employees: ['employee'],
  usb: ['usb_device'],
  printedparts: ['printed_item']
}

const filterList = [
  { key: 'all', label: 'All' },
  { key: 'machines', label: 'Machines' },
  { key: 'computers', label: 'PCs' },
  { key: 'printers', label: 'Printers' },
  { key: 'network', label: 'Network' },
  { key: 'measuringtools', label: 'Measuring Tools' },
  { key: 'applications', label: 'Apps' },
  { key: 'knowledgebase', label: 'KB' },
  { key: 'notifications', label: 'Notices' },
  { key: 'employees', label: 'Employees' },
  { key: 'usb', label: 'USB' },
  { key: 'printedparts', label: 'Printed Parts' }
]

function typeLabel(type) {
  return typeLabels[type] || type
}

function getFilterCount(filterKey) {
  if (filterKey === 'all') return totalAll.value || results.value.length
  const types = filterTypeMap[filterKey]
  if (!types) return 0
  return types.reduce((sum, t) => sum + (typeCounts.value[t] || 0), 0)
}

const filteredResults = computed(() => {
  if (activeFilter.value === 'all') return results.value
  const types = filterTypeMap[activeFilter.value]
  if (!types) return results.value
  return results.value.filter(r => types.includes(r.type))
})

async function search(q) {
  if (!q || q.length < 2) {
    results.value = []
    suggestion.value = null
    return
  }

  loading.value = true
  activeFilter.value = 'all'

  try {
    const response = await searchApi.search(q)
    const data = response.data.data
    // The global endpoint carries the suggestion with the results, so no second
    // call is needed here. A list page that has no such key uses the
    // useSearchSuggestion composable against /search/suggest instead.
    suggestion.value = data?.suggestion || null

    // Handle ServiceNOW redirect
    if (data?.redirect?.type === 'servicenow') {
      window.open(data.redirect.url, '_blank')
      query.value = q
      results.value = []
      loading.value = false
      return
    }

    // Smart redirect - auto-navigate to exact match
    if (data?.redirect) {
      router.replace(data.redirect.url)
      return
    }

    results.value = data?.results || []
    typeCounts.value = data?.counts || {}
    totalAll.value = data?.total_all || results.value.length
    query.value = q
  } catch (error) {
    console.error('Search error:', error)
    results.value = []
  } finally {
    loading.value = false
  }
}

// Take the offered spelling: put it in the box and search it, so the person
// sees what was searched rather than results for a word they did not type.
function applySuggestion(word) {
  searchInput.value = word
  suggestion.value = null
  performSearch()
}

function performSearch() {
  const term = searchInput.value.trim()
  if (!term) return
  // Searching a term that is ALREADY in the URL is a duplicate navigation: the
  // router aborts it, so the route watcher never fires and the button does
  // nothing at all. Re-run the query directly in that case. The sidebar box
  // never hits this, because it is always navigating from somewhere else -
  // which is why the two search boxes appeared to behave differently.
  if (term === route.query.q) {
    search(term)
    return
  }
  router.push({ path: '/search', query: { q: term } })
}

async function openKBArticle(result) {
  try {
    await knowledgebaseApi.trackClick(result.id)
    if (result.linkurl) {
      window.open(result.linkurl, '_blank')
    } else {
      router.push(result.url)
    }
  } catch (error) {
    console.error('Error tracking click:', error)
    if (result.linkurl) {
      window.open(result.linkurl, '_blank')
    } else {
      router.push(result.url)
    }
  }
}

function shareResult(result) {
  const url = new URL(window.location.href)
  url.searchParams.set('highlight', `${result.type}-${result.id}`)
  navigator.clipboard.writeText(url.toString()).then(() => {
    copiedId.value = `${result.type}-${result.id}`
    setTimeout(() => { copiedId.value = null }, 2000)
  })
}

function scrollToHighlight() {
  if (highlightId.value) {
    nextTick(() => {
      const el = document.getElementById(`result-${highlightId.value}`)
      if (el) {
        el.scrollIntoView({ behavior: 'smooth', block: 'center' })
        setTimeout(() => { highlightId.value = null }, 3000)
      }
    })
  }
}

onMounted(() => {
  const q = route.query.q
  const hl = route.query.highlight
  if (hl) highlightId.value = hl
  if (q) {
    searchInput.value = q
    search(q)
  }
})

watch(() => route.query.q, (newQ) => {
  if (newQ) {
    searchInput.value = newQ
    const hl = route.query.highlight
    if (hl) highlightId.value = hl
    search(newQ)
  }
})

watch(results, () => {
  scrollToHighlight()
})
</script>

<style scoped>
.page-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.page-header h2 {
  margin: 0;
}

.results-count {
  color: var(--text-light);
  font-size: 0.9rem;
}

.search-box {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.search-box input {
  flex: 1;
}

.filter-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-bottom: 1rem;
}

.filter-btn {
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  font-size: 0.8rem;
  display: flex;
  align-items: center;
  gap: 0.3rem;
}

.filter-btn.active {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

.filter-btn:hover:not(.active) {
  border-color: var(--primary);
}

.filter-count {
  background: rgba(128, 128, 128, 0.15);
  padding: 0.1rem 0.35rem;
  border-radius: 8px;
  font-size: 0.75rem;
  min-width: 1.25rem;
  text-align: center;
}

.filter-btn.active .filter-count {
  background: rgba(255, 255, 255, 0.25);
}

.no-results {
  text-align: center;
  color: var(--text-light);
  padding: 2rem;
}

.results-list {
  display: flex;
  flex-direction: column;
}

.result-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.75rem;
  border-bottom: 1px solid var(--border);
  transition: background 0.3s ease;
}

.result-item:last-child {
  border-bottom: none;
}

.result-item.highlighted {
  background: rgba(65, 129, 255, 0.08);
  border-left: 3px solid var(--primary);
}

.result-type {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  min-width: 65px;
  text-align: center;
  flex-shrink: 0;
}

/* Per-domain badge palette. Values live in CSS variables on the container so
   the dark theme overrides them in one place (below) instead of restating
   every selector. Each badge rule just references its pair. */
.search-results {
  --rt-machine-bg: #e3f2fd;        --rt-machine-fg: #1565c0;
  --rt-computer-bg: #e8f5e9;       --rt-computer-fg: #2e7d32;
  --rt-application-bg: #fff3e0;    --rt-application-fg: #e65100;
  --rt-knowledgebase-bg: #f3e5f5;  --rt-knowledgebase-fg: #7b1fa2;
  --rt-printer-bg: #fce4ec;        --rt-printer-fg: #c2185b;
  --rt-network-bg: #fff8e1;        --rt-network-fg: #f57f17;
  --rt-measuring-bg: #e0f7fa;      --rt-measuring-fg: #00838f;
  --rt-employee-bg: #e0f2f1;       --rt-employee-fg: #00695c;
  --rt-notification-bg: #e8eaf6;   --rt-notification-fg: #283593;
  --rt-subnet-bg: #fbe9e7;         --rt-subnet-fg: #bf360c;
}

.result-type.machine { background: var(--rt-machine-bg); color: var(--rt-machine-fg); }
.result-type.pc,
.result-type.computer { background: var(--rt-computer-bg); color: var(--rt-computer-fg); }
.result-type.application { background: var(--rt-application-bg); color: var(--rt-application-fg); }
.result-type.knowledgebase { background: var(--rt-knowledgebase-bg); color: var(--rt-knowledgebase-fg); }
.result-type.printer { background: var(--rt-printer-bg); color: var(--rt-printer-fg); }
.result-type.network_device { background: var(--rt-network-bg); color: var(--rt-network-fg); }
.result-type.measuring_tool { background: var(--rt-measuring-bg); color: var(--rt-measuring-fg); }
.result-type.employee { background: var(--rt-employee-bg); color: var(--rt-employee-fg); }
.result-type.notification { background: var(--rt-notification-bg); color: var(--rt-notification-fg); }
.result-type.subnet { background: var(--rt-subnet-bg); color: var(--rt-subnet-fg); }

.result-content {
  flex: 1;
  min-width: 0;
}

.result-title {
  color: var(--link);
  text-decoration: none;
  font-weight: 500;
}

.result-title:hover {
  text-decoration: underline;
}

.result-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--text-light);
}

.result-subtitle {
  color: var(--text-light);
}

.result-ticket {
  font-family: monospace;
  font-size: 0.75rem;
}

.share-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-light);
  font-size: 0.7rem;
  padding: 0.2rem 0.4rem;
  flex-shrink: 0;
}

.share-btn:hover {
  color: var(--primary);
  border-color: var(--primary);
}

@media (prefers-color-scheme: dark) {
  .search-results {
    --rt-machine-bg: rgba(21, 101, 192, 0.2);       --rt-machine-fg: #64b5f6;
    --rt-computer-bg: rgba(46, 125, 50, 0.2);        --rt-computer-fg: #81c784;
    --rt-application-bg: rgba(230, 81, 0, 0.2);      --rt-application-fg: #ffb74d;
    --rt-knowledgebase-bg: rgba(123, 31, 162, 0.2);  --rt-knowledgebase-fg: #ce93d8;
    --rt-printer-bg: rgba(194, 24, 91, 0.2);         --rt-printer-fg: #f48fb1;
    --rt-network-bg: rgba(245, 127, 23, 0.2);        --rt-network-fg: #ffd54f;
    --rt-measuring-bg: rgba(0, 131, 143, 0.2);       --rt-measuring-fg: #80deea;
    --rt-employee-bg: rgba(0, 105, 92, 0.2);         --rt-employee-fg: #80cbc4;
    --rt-notification-bg: rgba(40, 53, 147, 0.2);    --rt-notification-fg: #9fa8da;
    --rt-subnet-bg: rgba(191, 54, 12, 0.2);          --rt-subnet-fg: #ffab91;
  }
}
</style>
