<template>
  <BaseModal
    :open="open"
    title="Variable Studio"
    eyebrow="PSADT + POSHMANAGER"
    description="Browse built-in PSADT session variables, insert POSHManager runtime values, and maintain custom variables for deployment scripts."
    wide
    @close="$emit('close')"
  >
    <div class="variable-studio">
      <div class="variable-toolbar">
        <div class="tabs variable-tabs">
          <button :class="{ active: tab === 'catalog' }" type="button" @click="tab = 'catalog'"><BookOpenText :size="15" />Catalog</button>
          <button :class="{ active: tab === 'custom' }" type="button" @click="tab = 'custom'"><SlidersHorizontal :size="15" />Custom</button>
        </div>
        <label class="search-control">
          <Search :size="15" />
          <input v-model="query" placeholder="Search variables..." />
        </label>
      </div>

      <div v-if="tab === 'catalog'" class="variable-catalog-layout">
        <aside class="variable-category-list">
          <button
            v-for="category in categories"
            :key="category"
            :class="{ active: activeCategory === category }"
            type="button"
            @click="activeCategory = category"
          >
            <span>{{ category }}</span>
            <strong>{{ categoryCount(category) }}</strong>
          </button>
        </aside>
        <div class="variable-list">
          <article v-for="variable in filteredCatalog" :key="variable.id" class="variable-row">
            <div>
              <strong>{{ variable.syntax }}</strong>
              <span>{{ variable.category }}</span>
              <p>{{ variable.description }}</p>
            </div>
            <div class="variable-actions">
              <button class="ghost-button compact" type="button" @click="$emit('insert', variable.token)">Token</button>
              <button class="primary-action compact" type="button" @click="$emit('insert', variable.syntax)"><Plus :size="14" />Insert</button>
            </div>
          </article>
          <p v-if="!filteredCatalog.length" class="widget-empty">No catalog variables match the current filter.</p>
        </div>
      </div>

      <div v-else class="custom-variable-layout">
        <section class="custom-variable-list">
          <header>
            <div>
              <strong>Custom variables</strong>
              <span>{{ catalog.custom?.length || 0 }} saved values</span>
            </div>
            <button class="primary-action compact" type="button" @click="resetForm"><Plus :size="14" />New variable</button>
          </header>
          <article v-for="variable in filteredCustom" :key="variable.id" :class="{ active: form.id === variable.id }" @click="editCustom(variable)">
            <div>
              <strong>{{ variable.syntax }}</strong>
              <span>{{ variable.category }} · {{ variable.visibility }}</span>
              <p>{{ variable.description || 'No description' }}</p>
            </div>
            <button class="ghost-button compact" type="button" @click.stop="$emit('insert', variable.syntax)">Insert</button>
          </article>
          <p v-if="!filteredCustom.length" class="widget-empty">No custom variables match the current filter.</p>
        </section>

        <form class="custom-variable-form" @submit.prevent="saveCustom">
          <div class="form-grid">
            <label><span>Name</span><input v-model="form.name" required placeholder="CompanyName" /></label>
            <label><span>Category</span><input v-model="form.category" placeholder="Deployment" /></label>
            <label>
              <span>Value type</span>
              <select v-model="form.valueType">
                <option value="string">String</option>
                <option value="number">Number</option>
                <option value="boolean">Boolean</option>
                <option value="json">JSON</option>
              </select>
            </label>
            <label>
              <span>Visibility</span>
              <select v-model="form.visibility">
                <option value="personal">Personal</option>
                <option value="shared">Shared</option>
                <option value="group">Group</option>
              </select>
            </label>
            <label v-if="form.visibility === 'group'">
              <span>Group</span>
              <select v-model="form.groupId">
                <option :value="null">Choose group</option>
                <option v-for="group in groups" :key="group.id" :value="group.id">{{ group.name }}</option>
              </select>
            </label>
            <label class="toggle modal-toggle">
              <input v-model="form.sensitive" type="checkbox" />
              <span><strong>Sensitive value</strong><small>Hide the value in API/UI reads after save.</small></span>
            </label>
            <label class="full"><span>Description</span><textarea v-model="form.description" rows="3" placeholder="Used by install/uninstall scripts" /></label>
            <label class="full">
              <span>{{ form.id && form.sensitive ? 'Replace value' : 'Value' }}</span>
              <textarea v-model="form.value" rows="4" :placeholder="form.sensitive && form.id ? 'Leave blank to keep current encrypted value' : 'Contoso'" />
            </label>
          </div>
          <div class="custom-variable-preview">
            <code>${{ form.name || 'VariableName' }}</code>
            <code>{{ previewToken }}</code>
          </div>
          <div class="form-actions modal-actions">
            <button v-if="form.id" class="ghost-button danger-text" type="button" @click="$emit('delete-custom', form.id)"><Trash2 :size="15" />Delete</button>
            <button class="ghost-button" type="button" @click="resetForm">Reset</button>
            <button class="primary-action" type="submit"><Save :size="16" />Save variable</button>
          </div>
        </form>
      </div>
    </div>
  </BaseModal>
</template>

<script setup>
import { computed, reactive, ref, watch } from 'vue';
import { BookOpenText, Plus, Save, Search, SlidersHorizontal, Trash2 } from '@lucide/vue';
import BaseModal from '../ui/BaseModal.vue';

const props = defineProps({
  open: Boolean,
  catalog: { type: Object, default: () => ({ builtIns: [], psadt: [], custom: [] }) },
  groups: { type: Array, default: () => [] }
});

const tab = ref('catalog');
const query = ref('');
const activeCategory = ref('All');
const form = reactive(emptyForm());

const catalogRows = computed(() => [
  ...(props.catalog.builtIns || []),
  ...(props.catalog.psadt || [])
]);

const categories = computed(() => ['All', ...new Set(catalogRows.value.map((variable) => variable.category))]);

const filteredCatalog = computed(() => filterVariables(
  catalogRows.value.filter((variable) => activeCategory.value === 'All' || variable.category === activeCategory.value)
));

const filteredCustom = computed(() => filterVariables(props.catalog.custom || []));
const previewToken = computed(() => `{{${form.name || 'VariableName'}}}`);

watch(() => props.open, (open) => {
  if (open) {
    tab.value = 'catalog';
    query.value = '';
  }
});

watch(categories, (next) => {
  if (!next.includes(activeCategory.value)) activeCategory.value = 'All';
});

function filterVariables(rows) {
  const needle = query.value.trim().toLowerCase();
  if (!needle) return rows;
  return rows.filter((variable) => [
    variable.name,
    variable.syntax,
    variable.token,
    variable.category,
    variable.description,
    variable.visibility
  ].filter(Boolean).join(' ').toLowerCase().includes(needle));
}

function categoryCount(category) {
  return category === 'All'
    ? catalogRows.value.length
    : catalogRows.value.filter((variable) => variable.category === category).length;
}

function editCustom(variable) {
  Object.assign(form, {
    id: variable.id,
    name: variable.name,
    description: variable.description || '',
    category: variable.category || 'Custom',
    value: variable.sensitive ? '' : variable.value || '',
    valueType: variable.valueType || 'string',
    sensitive: Boolean(variable.sensitive),
    visibility: variable.visibility || 'personal',
    groupId: variable.groupId || null
  });
}

function resetForm() {
  Object.assign(form, emptyForm());
}

function saveCustom() {
  const payload = { ...form };
  if (payload.id && payload.sensitive && !payload.value) delete payload.value;
  emit('save-custom', payload);
}

function emptyForm() {
  return {
    id: null,
    name: '',
    description: '',
    category: 'Custom',
    value: '',
    valueType: 'string',
    sensitive: false,
    visibility: 'personal',
    groupId: null
  };
}

const emit = defineEmits(['close', 'insert', 'save-custom', 'delete-custom']);
</script>
