<template>
  <div class="relationships-section">
    <div class="section-header">
      <h3 class="section-title">Relationships</h3>
      <button
        v-if="authStore.isAuthenticated"
        class="btn btn-sm btn-primary"
        @click="showAddModal = true"
      >
        Add Relationship
      </button>
    </div>

    <div v-if="loading" class="loading">Loading relationships...</div>

    <div v-else-if="!hasRelationships" class="empty-state">
      No relationships defined.
    </div>

    <template v-else>
      <!-- Symmetric connections: one direction-blind entry per peer -->
      <div v-if="connectedItems.length > 0" class="relationship-group">
        <h4 class="group-title">Connected</h4>
        <div class="relationship-list">
          <div
            v-for="item in connectedItems"
            :key="item.key"
            class="relationship-item"
          >
            <div class="rel-icon"><component :is="getAssetIcon(item.peer?.assettypename || item.peer?.assettype)" :size="16" /></div>
            <div class="rel-content">
              <div class="rel-line">
                <router-link :to="getAssetRoute(item.peer)" class="rel-name">
                  {{ item.peer?.name || item.peer?.assetnumber || 'Unknown' }}
                </router-link>
                <span class="badge" :style="colorStyle(colorForType(item.relationshiptypename))">{{ item.relationshiptypename }}</span>
              </div>
              <div class="rel-meta">
                <span class="rel-type-badge">{{ item.peer?.assettypename || item.peer?.assettype }}</span>
              </div>
              <div v-if="item.notes" class="rel-notes">{{ item.notes }}</div>
            </div>
            <button
              v-if="authStore.isAuthenticated"
              class="btn-icon delete"
              @click="deleteItem(item)"
              title="Remove relationship"
            >
              &times;
            </button>
          </div>
        </div>
      </div>

      <!-- Directional relationships: natural per-row phrasing, no jargon -->
      <div v-if="directionalItems.length > 0" class="relationship-group">
        <div class="relationship-list">
          <div
            v-for="item in directionalItems"
            :key="item.key"
            class="relationship-item"
          >
            <div class="rel-icon"><component :is="getAssetIcon(item.peer?.assettypename || item.peer?.assettype)" :size="16" /></div>
            <div class="rel-content">
              <div class="rel-line">
                <template v-if="item.direction === 'outgoing'">
                  <span class="badge" :style="colorStyle(colorForType(item.relationshiptypename))">{{ item.relationshiptypename }}</span>
                  <span class="rel-arrow">-&gt;</span>
                  <router-link :to="getAssetRoute(item.peer)" class="rel-name">
                    {{ item.peer?.name || item.peer?.assetnumber || 'Unknown' }}
                  </router-link>
                </template>
                <template v-else>
                  <span class="rel-arrow">&lt;-</span>
                  <span class="badge" :style="colorStyle(colorForType(item.relationshiptypename))">{{ item.relationshiptypename }}</span>
                  <span class="rel-from">from</span>
                  <router-link :to="getAssetRoute(item.peer)" class="rel-name">
                    {{ item.peer?.name || item.peer?.assetnumber || 'Unknown' }}
                  </router-link>
                </template>
              </div>
              <div class="rel-meta">
                <span class="rel-type-badge">{{ item.peer?.assettypename || item.peer?.assettype }}</span>
              </div>
              <div v-if="item.notes" class="rel-notes">{{ item.notes }}</div>
            </div>
            <button
              v-if="authStore.isAuthenticated"
              class="btn-icon delete"
              @click="deleteItem(item)"
              title="Remove relationship"
            >
              &times;
            </button>
          </div>
        </div>
      </div>
    </template>

    <!-- Add Relationship Modal -->
    <div v-if="showAddModal" class="modal-overlay">
      <div class="modal-content">
        <div class="modal-header">
          <h3>Add Relationship</h3>
          <button class="btn-icon" @click="closeModal">&times;</button>
        </div>

        <div class="modal-body">
          <div class="form-group">
            <label>Direction</label>
            <select v-model="newRel.direction" class="form-control">
              <option value="outgoing">This asset -> Target asset</option>
              <option value="incoming">Source asset -> This asset</option>
            </select>
          </div>

          <div class="form-group">
            <label>Relationship Type</label>
            <select v-model="newRel.relationshiptypeid" class="form-control" required>
              <option value="">Select type...</option>
              <option
                v-for="t in relationshipTypes"
                :key="t.relationshiptypeid"
                :value="t.relationshiptypeid"
              >
                {{ t.relationshiptype }}
              </option>
            </select>
          </div>

          <div class="form-group">
            <label>{{ newRel.direction === 'outgoing' ? 'Target Asset' : 'Source Asset' }}</label>
            <div class="asset-search">
              <input
                type="text"
                v-model="assetSearchQuery"
                class="form-control"
                placeholder="Search assets..."
                @input="searchAssets"
              />
              <div v-if="assetSearchResults.length > 0" class="search-results">
                <div
                  v-for="asset in assetSearchResults"
                  :key="asset.assetid"
                  class="search-result-item"
                  :class="{ selected: newRel.targetAssetId === asset.assetid }"
                  @click="selectAsset(asset)"
                >
                  <span class="result-icon">{{ getAssetIcon(asset.assettype) }}</span>
                  <span class="result-name">{{ asset.name || asset.assetnumber }}</span>
                  <span class="result-type">{{ asset.assettype }}</span>
                </div>
              </div>
            </div>
            <div v-if="selectedAsset" class="selected-asset">
              <span class="result-icon">{{ getAssetIcon(selectedAsset.assettype) }}</span>
              <span>{{ selectedAsset.name || selectedAsset.assetnumber }}</span>
              <button class="btn-icon" @click="clearSelectedAsset">&times;</button>
            </div>
          </div>

          <div class="form-group">
            <label>Notes (optional)</label>
            <textarea
              v-model="newRel.notes"
              class="form-control"
              rows="2"
              placeholder="Additional notes about this relationship..."
            ></textarea>
          </div>
        </div>

        <div class="modal-footer">
          <button class="btn btn-secondary" @click="closeModal">Cancel</button>
          <button
            class="btn btn-primary"
            :disabled="!canSave"
            @click="saveRelationship"
          >
            Add Relationship
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { Cog, Monitor, Printer, Globe, Package, Ruler } from 'lucide-vue-next'
import { assetsApi, relationshipTypesApi } from '../api'
import { colorStyle } from '@/utils/colorStyle'
import { useAuthStore } from '../stores/auth'
import { useToast } from '../composables/toast'
import { apiError } from '../utils/apiError'
const toast = useToast()

const props = defineProps({
  assetid: {
    type: Number,
    default: null
  },
  // Alternative: lookup by machine/asset number
  machinenumber: {
    type: String,
    default: null
  }
})

const emit = defineEmits(['updated'])

const authStore = useAuthStore()

const loading = ref(true)
const resolvedAssetId = ref(null)
const lookupFailed = ref(false)
const outgoing = ref([])
const incoming = ref([])
const relationshipTypes = ref([])

function colorForType(name) {
  const t = relationshipTypes.value.find(rt => rt.relationshiptype === name)
  return t?.color || null
}
const showAddModal = ref(false)

// New relationship form
const newRel = ref({
  direction: 'outgoing',
  relationshiptypeid: '',
  targetAssetId: null,
  notes: ''
})

const assetSearchQuery = ref('')
const assetSearchResults = ref([])
const selectedAsset = ref(null)
let searchTimeout = null

const hasRelationships = computed(() => outgoing.value.length > 0 || incoming.value.length > 0)

// Symmetric types collapse to one entry per {peer, type} unordered pair. All
// stored direction rows (both directions, plus any legacy duplicates) fold
// into one displayed entry; its rowIds carries every collapsed relationshipid
// so a delete removes them all.
const connectedItems = computed(() => {
  const byPair = new Map()
  const rows = [
    ...outgoing.value.map(rel => ({ rel, peer: rel.targetasset })),
    ...incoming.value.map(rel => ({ rel, peer: rel.sourceasset })),
  ]
  for (const { rel, peer } of rows) {
    if (rel.isdirectional !== false) continue
    const selfid = resolvedAssetId.value
    const peerid = peer?.assetid
    const lo = Math.min(selfid, peerid)
    const hi = Math.max(selfid, peerid)
    const key = `${rel.relationshiptypeid}:${lo}:${hi}`
    const existing = byPair.get(key)
    if (existing) {
      existing.rowIds.push(rel.relationshipid)
      if (!existing.notes && rel.notes) existing.notes = rel.notes
    } else {
      byPair.set(key, {
        key,
        rowIds: [rel.relationshipid],
        peer,
        relationshiptypeid: rel.relationshiptypeid,
        relationshiptypename: rel.relationshiptypename,
        notes: rel.notes || null,
      })
    }
  }
  return Array.from(byPair.values())
})

// Directional types keep one entry per stored row with arrow phrasing.
const directionalItems = computed(() => {
  const items = []
  for (const rel of outgoing.value) {
    if (rel.isdirectional === false) continue
    items.push({
      key: `out-${rel.relationshipid}`,
      rowIds: [rel.relationshipid],
      peer: rel.targetasset,
      direction: 'outgoing',
      relationshiptypeid: rel.relationshiptypeid,
      relationshiptypename: rel.relationshiptypename,
      notes: rel.notes || null,
    })
  }
  for (const rel of incoming.value) {
    if (rel.isdirectional === false) continue
    items.push({
      key: `in-${rel.relationshipid}`,
      rowIds: [rel.relationshipid],
      peer: rel.sourceasset,
      direction: 'incoming',
      relationshiptypeid: rel.relationshiptypeid,
      relationshiptypename: rel.relationshiptypename,
      notes: rel.notes || null,
    })
  }
  return items
})

const canSave = computed(() => {
  return newRel.value.relationshiptypeid && newRel.value.targetAssetId && resolvedAssetId.value
})

onMounted(async () => {
  await resolveAssetId()
  if (resolvedAssetId.value) {
    await Promise.all([loadRelationships(), loadRelationshipTypes()])
  }
})

watch(() => props.assetid, async () => {
  await resolveAssetId()
  if (resolvedAssetId.value) {
    await loadRelationships()
  }
})

watch(() => props.machinenumber, async () => {
  await resolveAssetId()
  if (resolvedAssetId.value) {
    await loadRelationships()
  }
})

async function resolveAssetId() {
  // If assetid is provided directly, use it
  if (props.assetid) {
    resolvedAssetId.value = props.assetid
    lookupFailed.value = false
    return
  }

  // Otherwise, try to look up by machine number
  if (props.machinenumber) {
    try {
      const response = await assetsApi.lookup(props.machinenumber)
      resolvedAssetId.value = response.data.data?.assetid
      lookupFailed.value = !resolvedAssetId.value
    } catch (error) {
      resolvedAssetId.value = null
      lookupFailed.value = true
      loading.value = false
    }
  }
}

async function loadRelationships() {
  if (!resolvedAssetId.value) return

  loading.value = true
  try {
    const response = await assetsApi.getRelationships(resolvedAssetId.value)
    outgoing.value = response.data.data?.outgoing || []
    incoming.value = response.data.data?.incoming || []
  } catch (error) {
    console.error('Failed to load relationships:', error)
  } finally {
    loading.value = false
  }
}

async function loadRelationshipTypes() {
  try {
    const response = await relationshipTypesApi.list()
    relationshipTypes.value = response.data.data || []
  } catch (error) {
    console.error('Failed to load relationship types:', error)
  }
}

function searchAssets() {
  clearTimeout(searchTimeout)
  if (!assetSearchQuery.value || assetSearchQuery.value.length < 2) {
    assetSearchResults.value = []
    return
  }

  searchTimeout = setTimeout(async () => {
    try {
      const response = await assetsApi.search(assetSearchQuery.value, { perpage: 10 })
      // Filter out the current asset
      assetSearchResults.value = (response.data.data || []).filter(
        a => a.assetid !== resolvedAssetId.value
      )
    } catch (error) {
      console.error('Failed to search assets:', error)
    }
  }, 300)
}

function selectAsset(asset) {
  selectedAsset.value = asset
  newRel.value.targetAssetId = asset.assetid
  assetSearchQuery.value = ''
  assetSearchResults.value = []
}

function clearSelectedAsset() {
  selectedAsset.value = null
  newRel.value.targetAssetId = null
}

async function saveRelationship() {
  if (!canSave.value) return

  try {
    const data = {
      relationshiptypeid: parseInt(newRel.value.relationshiptypeid),
      notes: newRel.value.notes || null
    }

    if (newRel.value.direction === 'outgoing') {
      data.sourceassetid = resolvedAssetId.value
      data.targetassetid = newRel.value.targetAssetId
    } else {
      data.sourceassetid = newRel.value.targetAssetId
      data.targetassetid = resolvedAssetId.value
    }

    await assetsApi.createRelationship(data)
    await loadRelationships()
    closeModal()
    emit('updated')
  } catch (error) {
    console.error('Failed to create relationship:', error)
    toast.error(apiError(error, 'Failed to create relationship'))
  }
}

// Delete every collapsed direction row behind a displayed entry.
async function deleteItem(item) {
  if (!confirm('Remove this relationship?')) return

  try {
    await Promise.all(item.rowIds.map(id => assetsApi.deleteRelationship(id)))
    await loadRelationships()
    emit('updated')
  } catch (error) {
    console.error('Failed to delete relationship:', error)
    toast.error('Failed to delete relationship')
  }
}

function closeModal() {
  showAddModal.value = false
  newRel.value = {
    direction: 'outgoing',
    relationshiptypeid: '',
    targetAssetId: null,
    notes: ''
  }
  selectedAsset.value = null
  assetSearchQuery.value = ''
  assetSearchResults.value = []
}

function getAssetIcon(assettype) {
  const icons = {
    'machine': Cog,
    'computer': Monitor,
    'printer': Printer,
    'network_device': Globe,
    'measuring_tool': Ruler
  }
  return icons[assettype] || Package
}

function getAssetRoute(asset) {
  if (!asset) return '#'

  const routeMap = {
    'machine': '/machines',
    'computer': '/pcs',
    'printer': '/printers',
    'network_device': '/network',
    'measuring_tool': '/measuringtools'
  }

  // serializer sends assettypename; old shape used assettype
  const typename = asset.assettypename || asset.assettype
  const basePath = routeMap[typename] || '/assets'

  // pluginid is the extension-table id the detail routes key on
  const id = asset.pluginid
    || asset.typedata?.networkdeviceid
    || asset.typedata?.machineid
    || asset.assetid
  return `${basePath}/${id}`
}
</script>

<style scoped>
.relationships-section {
  background: var(--bg-card);
  border-radius: 8px;
  border: 1px solid var(--border);
  padding: 1.25rem;
  /* Match .section-card spacing so relationships is its own card with a gap
     below (not visually merged with the Notes card) and does not split across
     a multicol break. */
  margin-bottom: 25px;
  break-inside: avoid;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.section-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}

.empty-state {
  color: var(--text-light);
  font-style: italic;
  padding: 1rem 0;
}

.relationship-group {
  margin-bottom: 1.5rem;
}

.relationship-group:last-child {
  margin-bottom: 0;
}

.group-title {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0 0 0.75rem 0;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.relationship-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.relationship-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem;
  background: var(--bg);
  border-radius: 6px;
  border: 1px solid var(--border);
}

.rel-icon {
  font-size: 1.25rem;
  flex-shrink: 0;
}

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

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

.rel-name:hover {
  text-decoration: underline;
}

.rel-line {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.rel-arrow {
  font-family: monospace;
  font-weight: 600;
  color: var(--text-light);
}

.rel-from {
  font-size: 0.8rem;
  color: var(--text-light);
}

.rel-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

.badge-outline {
  background: transparent;
  border: 1px solid var(--primary);
  color: var(--primary);
  font-size: 0.7rem;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
}

.rel-type-badge {
  font-size: 0.75rem;
  color: var(--text-light);
}

.rel-notes {
  font-size: 0.8rem;
  color: var(--text-light);
  margin-top: 0.25rem;
}

.btn-icon.delete {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 1.25rem;
  cursor: pointer;
  padding: 0.25rem;
  line-height: 1;
  opacity: 0.6;
}

.btn-icon.delete:hover {
  opacity: 1;
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: var(--bg-card-solid);
  border-radius: 12px;
  width: 100%;
  max-width: 500px;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  color: var(--text);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.modal-header h3 {
  margin: 0;
  font-size: 1.1rem;
}

.modal-header .btn-icon {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-light);
  line-height: 1;
}

.modal-body {
  padding: 1.25rem;
  overflow-y: auto;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--border);
}

.form-group {
  margin-bottom: 1rem;
}

.form-group:last-child {
  margin-bottom: 0;
}

.form-group label {
  display: block;
  font-weight: 500;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

/* Asset Search */
.asset-search {
  position: relative;
}

.search-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--bg-card-solid);
  border: 1px solid var(--border);
  border-radius: 6px;
  max-height: 200px;
  overflow-y: auto;
  z-index: 10;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.search-result-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}

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

.search-result-item:hover {
  background: var(--bg);
}

.search-result-item.selected {
  background: rgba(65, 129, 255, 0.15);
}

.result-icon {
  font-size: 1rem;
}

.result-name {
  flex: 1;
  font-weight: 500;
}

.result-type {
  font-size: 0.75rem;
  color: var(--text-light);
}

.selected-asset {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: rgba(65, 129, 255, 0.1);
  border: 1px solid var(--primary);
  border-radius: 6px;
}

.selected-asset .btn-icon {
  margin-left: auto;
  background: none;
  border: none;
  font-size: 1rem;
  cursor: pointer;
  color: var(--text-light);
}
</style>
