<script setup>
import { useQuasar } from "quasar";
import { computed, ref, reactive } from "vue";
import { q, m } from "#imports";
import * as Diff2Html from "diff2html";
import "diff2html/bundles/css/diff2html.min.css";
const quasar = useQuasar();
const props = defineProps({
  modelId: {
    type: String,
    required: true
  },
  modelClass: {
    type: String,
    required: true
  }
});
const { revisionsByModel } = await q({
  "revisionsByModel": {
    __args: {
      model_id: parseInt(props.modelId),
      model_class: props.modelClass
    },
    revision_id: true,
    revisionBy: true,
    createdTime: true,
    content: true,
    delta: true,
    diff: true
  }
});
const num_of_revisions = computed(() => {
  return revisionsByModel.length;
});
const showDialog = ref(false);
const selectedRevision = ref(null);
const onClick = (revision) => {
  selectedRevision.value = revision;
  showDialog.value = true;
};
const onRestore = () => {
  quasar.dialog({
    title: "Restore",
    message: "Are you sure you want to restore selected fields?",
    ok: "Yes",
    cancel: "No"
  }).onOk(async () => {
    if (await m("restoreRevision", {
      revision_id: selectedRevision.value.revision_id,
      fields: restore_fields.value
    })) {
      quasar.notify({
        message: "Restored successfully",
        color: "positive"
      });
      window.location.reload();
    }
  });
};
const restore_fields = ref([]);
const onToggleAll = () => {
  if (restore_fields.value.length === 0) {
    restore_fields.value = Object.keys(getFilteredContent.value);
  } else {
    restore_fields.value = [];
  }
};
const isCheckedAll = computed(() => {
  return restore_fields.value.length === Object.keys(getFilteredContent.value).length;
});
const isAllowRestore = computed(() => {
  return restore_fields.value.length > 0;
});
const showOnlyDelta = ref(false);
const getFilteredContent = computed(() => {
  if (showOnlyDelta.value) {
    const contents = {};
    for (const key in selectedRevision.value.delta) {
      contents[key] = selectedRevision.value.content[key];
    }
    return contents;
  } else {
    return selectedRevision.value.content;
  }
});
const outputFormat = ref("side-by-side");
const getDiffHtml = (diffs) => {
  if (!diffs) {
    return "";
  }
  return Diff2Html.html(diffs, {
    drawFileList: false,
    matching: "lines",
    outputFormat: outputFormat.value,
    highlight: true
  });
};
</script>

<template>
    <div>

        <q-dialog v-model="showDialog" full-height full-width>
            <q-card>
                <q-toolbar>
                    <l-btn label="Restore" icon="sym_o_restore" permission="revision.restore" @click="onRestore"
                        :disabled="!isAllowRestore" />

                    <q-checkbox label="Show changed only" v-model="showOnlyDelta"></q-checkbox>

                    <q-btn-toggle class="q-mx-md" v-model="outputFormat" toggle-color="primary" :options="[
                        { label: 'side-by-side', value: 'side-by-side' }, { label: 'line-by-line', value: 'line-by-line' }
                    ]" />
                    <q-space />
                    <q-btn flat round dense icon="close" @click="showDialog = false" />
                </q-toolbar>

                <div class="q-pa-md">

                    <div class="text-h6 q-mb-md">
                        Revision by: {{ selectedRevision.revisionBy }} <br>
                        Created at: {{ selectedRevision.createdTime }}

                    </div>

                    <q-markup-table dense separator="cell" flat bordered>
                        <thead>
                            <tr>
                                <th width="48px">
                                    <q-checkbox @click="onToggleAll" v-model="isCheckedAll" :></q-checkbox>
                                </th>
                                <th>Field</th>
                                <th>Value</th>
                                <th>Changed</th>
                            </tr>
                        </thead>
                        <tbody>
                            <template v-for="(value, key) in getFilteredContent" :key="key">

                                <tr>

                                    <td><q-checkbox v-model="restore_fields" :val="key"></q-checkbox>
                                    </td>
                                    <td :class="{ 'bg-yellow-3': selectedRevision.delta[key] != undefined }">{{ key }}
                                    </td>
                                    <td>
                                        <pre>{{ value }}</pre>
                                    </td>
                                    <td>
                                        <pre>{{ selectedRevision.delta[key] }}</pre>
                                    </td>

                                </tr>

                                <tr v-if="getDiffHtml(selectedRevision.diff[key])">
                                    <td colspan="4">
                                        <div v-html="getDiffHtml(selectedRevision.diff[key])"></div>
                                    </td>
                                </tr>
                            </template>
                        </tbody>

                    </q-markup-table>

                </div>

            </q-card>
        </q-dialog>

        <l-card>
            <q-list>
                <q-expansion-item :label="`Revisions: ${num_of_revisions}`" icon="sym_o_history" expand-separator>

                    <q-list>
                        <q-item v-for="revision in revisionsByModel" :key="revision.revision_id"
                            @click="onClick(revision)" clickable>
                            <q-item-section>
                                <q-item-label>Revision by: {{ revision.revisionBy }}</q-item-label>
                                <q-item-label caption>{{ revision.createdTime }}</q-item-label>

                            </q-item-section>
                        </q-item>
                    </q-list>

                </q-expansion-item>

            </q-list>
        </l-card>
    </div>
</template>
