<script setup lang="ts">
import { watch } from 'vue';
import useShape from '../../ng-mock/js-land/frontendAdapters/vue/useShape';
import { deepComputed } from '../../ng-mock/js-land/frontendAdapters/vue/deepComputed';
import flattenObject from '../utils/flattenObject';

// Acquire deep signal object (proxy) for a shape; scope second arg left empty string for parity
const shapeObj = useShape('TestShape', '');

// Expose for devtools exploration
// @ts-ignore
window.vueState = shapeObj;

// Helpers to read / write nested properties given a dot path produced by flattenObject
function getNestedValue(obj: any, path: string) {
  return path.split('.').reduce((cur, k) => (cur == null ? cur : cur[k]), obj);
}
function setNestedValue(obj: any, path: string, value: any) {
  const keys = path.split('.');
  let cur = obj;
  for (let i = 0; i < keys.length - 1; i++) {
    cur = cur[keys[i]];
    if (cur == null) return;
  }
  cur[keys[keys.length - 1]] = value;
}

// Reactive flattened entries built via deepComputed bridging deepSignal dependencies to Vue.
const flatEntries = deepComputed(() => (shapeObj ? flattenObject(shapeObj.value as any) : []));

// log flatEntries
watch(flatEntries, (newVal) => {
  console.log('flatEntries changed:', newVal);
}, { deep: true });
</script>


<template>
  <div class="vue">
    <p>Rendered in Vue</p>
    <template v-if="shapeObj">

      <table border="1" cellpadding="5" style="margin-top:1rem; max-width:100%; font-size:0.9rem;">
        <thead>
          <tr>
            <th>Key</th>
            <th>Value</th>
            <th>Edit</th>
          </tr>
        </thead>

        <tbody>
          <tr v-for="([key, value]) in flatEntries" :key="key">
            <!-- Key-->
            <td style="white-space:nowrap;">{{ key }}</td>

            <!-- Value -->
            <td>
              <template v-if="value instanceof Set">
                {{ Array.from(value).join(', ') }}
              </template>
              <template v-else-if="Array.isArray(value)">
                [{{ value.join(', ') }}]
              </template>
              <template v-else>
                {{ JSON.stringify(value) }}
              </template>
            </td>

            <!-- Edit -->
            <td>
              <!-- String editing -->
              <template v-if="typeof value === 'string'">
                <template v-if="key.indexOf('.') === -1">
                  <input type="text" v-model="(shapeObj)[key]" />
                </template>
                <template v-else>
                  <input type="text" v-bind:value="value" />
                </template>
              </template>
              <!-- Number editing -->
              <template v-else-if="typeof value === 'number'">
                <template v-if="key.indexOf('.') === -1">
                  <input type="number" v-model.number="(shapeObj)[key]" />
                </template>
                <template v-else>
                  <input type="number" v-bind:value="value" />
                </template>
              </template>
              <!-- Boolean editing -->
              <template v-else-if="typeof value === 'boolean'">
                <template v-if="key.indexOf('.') === -1">
                  <input type="checkbox" v-model="(shapeObj as any)[key]" />
                </template>
                <template v-else>
                  <input type="checkbox" v-bind:value="value" />
                </template>
              </template>
              <!-- Array editing -->
              <template v-else-if="Array.isArray(value)">
                <div style="display:flex; gap:.5rem;">
                  <button
                    @click="() => { const current = getNestedValue(shapeObj, key) || []; setNestedValue(shapeObj, key, [...current, current.length + 1]); }">Add</button>
                  <button
                    @click="() => { const current = getNestedValue(shapeObj, key) || []; if (current.length) setNestedValue(shapeObj, key, current.slice(0, -1)); }">Remove</button>
                </div>
              </template>
              <!-- Set editing -->
              <template v-else-if="value instanceof Set">
                <div style="display:flex; gap:.5rem;">
                  <button
                    @click="() => { const currentSet: Set<any> = getNestedValue(shapeObj, key); currentSet.add(`item${currentSet.size + 1}`); }">Add</button>
                  <button
                    @click="() => { const currentSet: Set<any> = getNestedValue(shapeObj, key); const last = Array.from(currentSet).pop(); if (last !== undefined) currentSet.delete(last); }">Remove</button>
                </div>
              </template>
              <template v-else>
                N/A
              </template>
            </td>
          </tr>
        </tbody>
      </table>
    </template>
    <template v-else>
      <p>Loading state</p>
    </template>
  </div>
</template>