<script setup>

const API_ORIGIN = import.meta.env.VITE_API_ORIGIN || window.location.origin;

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

import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
import { Button, ButtonGroup } from 'pankow';
import Info from '../components/app/Info.vue';
import Security from '../components/app/Security.vue';
import Cron from '../components/app/Cron.vue';
import Eventlog from '../components/app/Eventlog.vue';
import Updates from '../components/app/Updates.vue';
import Uninstall from '../components/app/Uninstall.vue';
import AppsModel from '../models/AppsModel.js';
import { APP_TYPES, ISTATES, RSTATES, HSTATES } from '../constants.js';

const appsModel = AppsModel.create();

const id = ref('');
const app = ref({});
const view = ref('');
const link = ref('');
const infoMenu = ref([]);
const hasLocalStorage = ref(false);

const isAppStopped = computed(() => {
  return appsModel.isStopped(app.value);
});

function onSetView(newView) {
  view.value = newView;
  window.location.hash = `/app/${id.value}/${newView}`;
}

async function onToggleRunState() {
  if (isAppStopped.value) {
    const [error] = await appsModel.start(app.value.id);
    if (error) return console.error(error);
  } else {
    const [error] = await appsModel.stop(app.value.id);
    if (error) return console.error(error);
  }
}

let refreshTimer = null;
async function refresh() {
  const [error, result] = await appsModel.get(id.value);
  if (error) return console.error(error);

  app.value = result;

  link.value = (result.installationState !== ISTATES.INSTALLED || result.health !== HSTATES.HEALTHY || result.runState === RSTATES.STOPPED) ? '' : result.fqdn;
  hasLocalStorage.value = result.manifest && result.manifest.addons && result.manifest.addons.localstorage;

  // TODO info menu will likely not change during polling
  infoMenu.value = [];
  infoMenu.value.push({
    label: t('app.docsAction'),
    disabled: !result.manifest?.documentationUrl,
    // TODO support real href links
    action: () => { window.location.href = result.manifest.documentationUrl; }
  });

  if (result.manifest?.postInstallMessage) {
    infoMenu.value.push({
      label: t('app.firstTimeSetupAction'),
      // TODO action
    });
  }

  if (result.manifest?.configurePath) {
    infoMenu.value.push({
      label: t('app.adminPageAction'),
      // TODO support real href links
      action: () => { window.location.href = link.value + result.manifest.configurePath; }
    });
  }

  if (result.manifest?.addons?.localstorage?.ftp) {
    infoMenu.value.push({
      label: t('app.sftpInfoAction'),
      // TODO action
    });
  }

  infoMenu.value.push({ separator: true });
  infoMenu.value.push({
    label: t('app.forumUrlAction'),
    disabled: !result.manifest?.forumUrl,
    // TODO support real href links
    action: () => { window.location.href = result.manifest.forumUrl; }
  });
  infoMenu.value.push({ separator: true });
  infoMenu.value.push({
    label: t('app.projectWebsiteAction'),
    disabled: !result.manifest?.website,
    // TODO support real href links
    action: () => { window.location.href = result.manifest.website; }
  });

  refreshTimer = setTimeout(refresh, 2000);
}

onMounted(async () => {
  const tmp = window.location.hash.slice('#/app/'.length);
  if (!tmp) return;

  const parts = tmp.split('/');
  if (parts.length !== 2) return;

  id.value = parts[0];

  await refresh();

  onSetView(parts[1] || 'info');
});

onBeforeUnmount(() => {
  if (refreshTimer) clearTimeout(refreshTimer);
});

</script>

<template>
  <div class="configure-outer">
    <div class="configure-inner">
      <div class="titlebar">
        <a class="applink" :href="link || null" target="_blank">
          <img :src="API_ORIGIN + app.iconUrl" v-fallback-image="API_ORIGIN + '/img/appicon_fallback.png'" style="width: 64px; margin-right: 10px;"/>
          <h2>{{ app.label || app.fqdn }}</h2>
        </a>

        <div style="display: flex; gap: 10px; align-items: center;">
          <Button secondary tool
            @click="onToggleRunState()"
            :disabled="app.taskId || app.error || app.installationState === 'pending_start' || app.installationState === 'pending_stop'"
            v-tooltip="$t(isAppStopped ? 'app.uninstall.startStop.startAction' : 'app.uninstall.startStop.stopAction')"
            :loading="app.installationState === 'pending_start' || app.installationState === 'pending_stop'"
            :icon="isAppStopped ? 'fa-solid fa-play' : 'fa-solid fa-power-off'"
          />
          <ButtonGroup>
            <Button secondary tool :href="`/logs.html?appId=${app.id}`" target="_blank" v-tooltip="$t('app.logsActionTooltip')" icon="fa-solid fa-align-left" />
            <Button secondary tool v-if="app.type !== APP_TYPES.PROXIED" :href="`/terminal.html?id=${app.id}`" target="_blank" v-tooltip="$t('app.terminalActionTooltip')" icon="fa fa-terminal" />
            <Button secondary tool v-if="hasLocalStorage" :href="`/filemanager.html#/home/app/${app.id}`" target="_blank" v-tooltip="$t('app.filemanagerActionTooltip')" icon="fas fa-folder" />
          </ButtonGroup>

          <Button secondary tool icon="fa-solid fa-book" v-tooltip="$t('app.docsActionTooltip')" :menu="infoMenu" />
        </div>
      </div>

      <div class="configure-body">
        <div class="configure-menu">
          <div class="configure-menu-item" @click="onSetView('info')" :active="view === 'info' ? true : null">{{ $t('app.infoTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('display')" :active="view === 'display' ? true : null">{{ $t('app.displayTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('location')" :active="view === 'location' ? true : null">{{ $t('app.locationTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('proxy')" :active="view === 'proxy' ? true : null">Proxy</div>
          <div class="configure-menu-item" @click="onSetView('access')" :active="view === 'access' ? true : null">{{ $t('app.accessControlTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('resources')" :active="view === 'resources' ? true : null">{{ $t('app.resourcesTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('services')" :active="view === 'services' ? true : null">{{ $t('app.servicesTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('storage')" :active="view === 'storage' ? true : null">{{ $t('app.storageTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('graphs')" :active="view === 'graphs' ? true : null">{{ $t('app.graphsTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('security')" :active="view === 'security' ? true : null">{{ $t('app.securityTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('email')" :active="view === 'email' ? true : null">{{ $t('app.emailTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('cron')" :active="view === 'cron' ? true : null">{{ $t('app.cronTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('updates')" :active="view === 'updates' ? true : null">{{ $t('app.updatesTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('backups')" :active="view === 'backups' ? true : null">{{ $t('app.backupsTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('repair')" :active="view === 'repair' ? true : null">{{ $t('app.repairTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('eventlog')" :active="view === 'eventlog' ? true : null">{{ $t('app.eventlogTabTitle') }}</div>
          <div class="configure-menu-item" @click="onSetView('uninstall')" :active="view === 'uninstall' ? true : null">{{ $t('app.uninstallTabTitle') }}</div>
        </div>
        <div class="configure-content">
          <Info v-if="view === 'info'" :app="app"/>
          <div v-if="view === 'display'"></div>
          <div v-if="view === 'location'"></div>
          <div v-if="view === 'proxy'"></div>
          <div v-if="view === 'access'"></div>
          <div v-if="view === 'resources'"></div>
          <div v-if="view === 'services'"></div>
          <div v-if="view === 'storage'"></div>
          <div v-if="view === 'graphs'"></div>
          <Security :app="app" v-if="view === 'security'"/>
          <div v-if="view === 'email'"></div>
          <Cron :app="app" v-if="view === 'cron'"/>
          <Updates :app="app" v-if="view === 'updates'"/>
          <div v-if="view === 'backups'"></div>
          <div v-if="view === 'repair'"></div>
          <Eventlog :app="app" v-if="view === 'eventlog'"/>
          <Uninstall :app="app" v-if="view === 'uninstall'"/>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>

.applink {
  display: flex;
  color: var(--pankow-text-color);
}

.applink:not([href]) {
  cursor: not-allowed;
}

.configure-outer {
  width: 100%;
  margin: auto;
}

.configure-inner {
  width: 100%;
  max-width: 1200px;
  margin: auto;
  padding-right: 15px;
}

.titlebar {
  display: flex;
  margin-bottom: 20px;
  justify-content: space-between;
  background-color: var(--pankow-body-background-color);
}

.configure-body {
  display: flex;
}

.configure-menu-item {
  white-space: nowrap;
  cursor: pointer;
  padding: 4px 60px 4px 4px;
}

.configure-menu-item[active] {
  color: var(--pankow-color-primary-active);
  font-weight: bold;
}

.configure-menu-item:hover {
  color: var(--pankow-color-primary-hover);
}

.configure-content {
  flex-grow: 1;
}

</style>
