<template>
  <div class="box">
    <div
      v-for="(mapping, mapIndex) in localMappings"
      :key="mapIndex"
      class="mb-5 p-4 border"
    >
      <div class="level">
        <div class="level-left">
          <h5 class="title is-5">Mapping {{ mapIndex + 1 }}: {{ mapping.alias }}</h5>
        </div>
        <div class="level-right">
          <button
            class="button is-danger is-small"
            @click="removeMapping(mapIndex)"
          >
            <span class="icon is-small">
              <SvgIcon v-bind="{ name: 'bin1.svg', type: 'white', size: 16 }"></SvgIcon>
            </span>
          </button>
        </div>
      </div>

      <div class="columns is-multiline">
        <div class="column is-6">
          <div class="field">
            <label class="label">Alias</label>
            <div class="control">
              <input
                class="input"
                type="text"
                v-model="mapping.alias"
                @input="update"
              />
            </div>
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Model</label>
            <div class="control">
              <input
                class="input"
                type="text"
                v-model="mapping.model"
                @input="update"
                placeholder="e.g., app.Transaction"
              />
            </div>
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Lookup Field</label>
            <div class="control">
              <input
                class="input"
                type="text"
                v-model="mapping.lookup_field"
                @input="update"
                placeholder="e.g., id"
              />
            </div>
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Lookup Value From</label>
            <div class="control">
              <input
                class="input"
                type="text"
                v-model="mapping.lookup_value_from"
                @input="update"
                placeholder="e.g., transaction_id or transaction.customer.id"
              />
            </div>
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Type</label>
            <div class="control">
              <div class="select is-fullwidth">
                <select
                  v-model="mapping.type"
                  @change="update"
                >
                  <option value="object">Object</option>
                  <option value="list">List</option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Is Trigger Object?</label>
            <div class="control">
              <label class="checkbox">
                <input
                  type="checkbox"
                  v-model="mapping.is_trigger_object"
                  @change="update"
                />
                Yes
              </label>
            </div>
          </div>
        </div>
      </div>

      <hr />
      <h6 class="title is-6">Fields</h6>
      <div
        v-for="(field, fieldIndex) in mapping.fields"
        :key="fieldIndex"
        class="field has-addons"
      >
        <div class="control">
          <input
            class="input"
            type="text"
            v-model="field.placeholder"
            @input="update"
            placeholder="[placeholder]"
          />
        </div>
        <div class="control is-expanded">
          <input
            class="input"
            type="text"
            v-model="field.source"
            @input="update"
            placeholder="source.field.name"
          />
        </div>
        <div class="control">
          <button
            class="button is-danger is-light"
            @click="removeField(mapIndex, fieldIndex as number)"
          >
            <SvgIcon v-bind="{ name: 'bin1.svg', type: 'primary' }"></SvgIcon>
          </button>
        </div>
      </div>
      <button
        class="button is-small is-light"
        @click="addField(mapIndex)"
      >
        <span class="icon is-small">+</span>
        <span>Add Field</span>
      </button>
    </div>

    <button
      class="button is-primary"
      @click="addMapping"
    >
      <SvgIcon
        class="mr-2"
        v-bind="{ name: 'add4.svg', type: 'white', size: 18 }"
      />
      Add Mapping
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";

const props = defineProps({
  mappings: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits(["update:mappings"]);

// Use a local ref to manage mappings to handle the object-to-array transformation for fields
const localMappings = ref<any[]>([]);

// Helper to transform fields object to array for v-for
const transformMappings = (sourceMappings: any[]) => {
  return sourceMappings.map((m) => ({
    ...m,
    fields: m.fields
      ? Object.entries(m.fields).map(([placeholder, source]) => ({
          placeholder,
          source: typeof source === "object" ? JSON.stringify(source) : source,
        }))
      : [],
  }));
};

// Helper to transform fields array back to object for emission
const reformatMappingsForEmit = () => {
  return localMappings.value.map((m) => {
    const newFields = m.fields.reduce((obj: any, item: any) => {
      try {
        // Attempt to parse if it's a JSON string for format objects
        obj[item.placeholder] = JSON.parse(item.source);
      } catch (e) {
        obj[item.placeholder] = item.source;
      }
      return obj;
    }, {});
    return { ...m, fields: newFields };
  });
};

watch(
  () => props.mappings,
  (newMappings) => {
    localMappings.value = transformMappings(newMappings || []);
  },
  { immediate: true, deep: true },
);

const addMapping = () => {
  localMappings.value.push({
    alias: "",
    model: "",
    lookup_field: "id",
    lookup_value_from: "",
    type: "object",
    is_trigger_object: false,
    fields: [],
  });
  update();
};

const removeMapping = (index: number) => {
  localMappings.value.splice(index, 1);
  update();
};

const addField = (mapIndex: number) => {
  if (!localMappings.value[mapIndex].fields) {
    localMappings.value[mapIndex].fields = [];
  }
  localMappings.value[mapIndex].fields.push({ placeholder: "", source: "" });
  update();
};

const removeField = (mapIndex: number, fieldIndex: number) => {
  localMappings.value[mapIndex].fields.splice(fieldIndex, 1);
  update();
};

const update = () => {
  emit("update:mappings", reformatMappingsForEmit());
};
</script>

<style scoped>
.box {
  padding: 1.5rem;
}
.border {
  border: 1px solid #dbdbdb;
  border-radius: 4px;
}
</style>
