<script setup>

import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;

import { ref, onMounted, useTemplateRef } from 'vue';
import { TableView, InputDialog } from '@cloudron/pankow';
import { prettyLongDate } from '@cloudron/pankow/utils';
import { API_ORIGIN } from '../constants.js';
import AppRestoreDialog from  '../components/AppRestoreDialog.vue';
import ActionBar from  '../components/ActionBar.vue';
import Section from  '../components/Section.vue';
import ArchivesModel from '../models/ArchivesModel.js';
import { download } from '../utils.js';
import BackupSitesModel from '../models/BackupSitesModel.js';

const archivesModel = ArchivesModel.create();
const backupSitesModel = BackupSitesModel.create();

const columns = {
  icon: {}, // archived
  location: {
    label: t('app.location.location'),
    sort: true
  },
  info: {
    label: t('backups.archives.info'),
    sort: false,
    hideMobile: true,
  },
  creationTime: {
    label: t('main.table.created'),
    sort: true,
    hideMobile: true,
  },
  actions: {
    width: '100px',
  }
};

function createActionMenu(archive) {
  return [{
    icon: 'fa-solid fa-history',
    label: t('backups.restoreArchiveDialog.restoreAction'),
    quickAction: true,
    action: onRestore.bind(null, archive),
  }, {
    separator: true,
  },{
    icon: 'fa-solid fa-file-alt',
    label: t('backups.listing.tooltipDownloadBackupConfig'),
    action: onDownloadConfig.bind(null, archive),
  }, {
    separator: true,
  },{
    icon: 'fa-solid fa-trash-alt',
    label: t('main.action.remove'),
    action: onRemove.bind(null, archive),
  }];
}

const busy = ref(true);
const archives = ref([]);

async function refreshArchives() {
  const [error, result] = await archivesModel.list();
  if (error) return console.error(error);

  // ensure we use the full api oprigin
  result.forEach(a => {
    a.iconUrl = API_ORIGIN + a.iconUrl;
  });

  archives.value = result;
}

const inputDialog = useTemplateRef('inputDialog');
async function onRemove(archive) {
  const yes = await inputDialog.value.confirm({
    title: t('backups.deleteArchiveDialog.title'),
    message: t('backups.deleteArchiveDialog.description', { appTitle: archive.appConfig?.manifest?.title, appFqdn: archive.appConfig?.fqdn }),
    confirmStyle: 'danger',
    confirmLabel: t('backups.deleteArchive.deleteAction'),
    rejectLabel: t('main.dialog.cancel'),
    rejectStyle: 'secondary'
  });

  if (!yes) return;

  const [error] = await archivesModel.remove(archive.id);
  if (error) return console.error(error);

  await refreshArchives();
}

const restoreDialog = useTemplateRef('restoreDialog');

async function onRestore(archive) {
  restoreDialog.value.open(archive);
}

async function onDownloadConfig(archive) {
  const [backupConfigError, backupConfig] = await backupSitesModel.generateBackupConfig(archive);
  if (backupConfigError) return console.error(backupConfigError);

  const filename = `${archive.appConfig.fqdn}-archive-config-${(new Date(archive.creationTime)).toISOString().split('T')[0]}.json`;
  download(filename, JSON.stringify(backupConfig, null, 4));
}

onMounted(async () => {
  await refreshArchives();
  busy.value = false;
});

</script>

<template>
  <div class="content">
    <Section :title="$t('backups.archives.title')">
      <InputDialog ref="inputDialog"/>
      <AppRestoreDialog ref="restoreDialog"/>

      <div>{{ $t('archives.description') }}</div>
      <br/>

      <TableView :columns="columns" :model="archives" :busy="busy" :placeholder="$t('archives.listing.placeholder')">
        <template #icon="{ item:archive }">
          <img :src="archive.iconUrl || 'img/appicon_fallback.png'" v-fallback-image="API_ORIGIN + '/img/appicon_fallback.png'" height="24" width="24"/>
        </template>

        <!-- for pre-8.2 backups, appConfig can be null -->
        <template #location="{ item:archive }">{{ archive.appConfig ? archive.appConfig.fqdn : '-' }}</template>

        <template #info="{ item:archive }">
          <span v-tooltip="`${archive.manifest.id}@${archive.manifest.version}`">{{ archive.manifest.title }}</span>
        </template>

        <template #creationTime="{ item:archive }">{{ prettyLongDate(archive.creationTime) }}</template>

        <template #actions="{ item:archive }">
          <ActionBar :actions="createActionMenu(archive)"/>
        </template>
      </TableView>
    </Section>
  </div>
</template>
