<script setup>

import { ref, useTemplateRef } from 'vue';
import { Dialog, FormGroup, SingleSelect, TextInput } from 'pankow';
import { prettyDate } from 'pankow/utils';
import { ISTATES } from '../constants.js';
import { taskNameFromInstallationState } from '../utils.js';
import AppsModel from '../models/AppsModel.js';

const appsModel = AppsModel.create();

const emit = defineEmits([ 'success' ]);

const dialog = useTemplateRef('dialog');

const busy = ref(false);
const formError = ref('');
const id = ref('');
const fqdn = ref('');
const appError = ref(null);
const backups = ref([]);
const backupId = ref('');

async function onSubmit() {
  busy.value = true;
  formError.value = '';

  const errorState = (appError.value && appError.value.installationState) || ISTATES.PENDING_CONFIGURE;
  const data = {};

  let repairFunc;
  switch (errorState) {
    case ISTATES.PENDING_INSTALL:
    case ISTATES.PENDING_CLONE: // if manifest or bad image, use CLI to provide new manifest
      repairFunc = appsModel.repair.bind(null, id.value, {}); // this will trigger a re-install
      break;

    // case ISTATES.PENDING_LOCATION_CHANGE:
    //   data.subdomain = $scope.repair.subdomain;
    //   data.domain = $scope.repair.domain.domain;
    //   data.aliasDomains = $scope.repair.aliasDomains.filter(function (a) { return a.enabled; })
    //     .map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
    //   data.redirectDomains = $scope.repair.redirectDomains.filter(function (a) { return a.enabled; })
    //     .map(function (d) { return { subdomain: d.subdomain, domain: d.domain.domain }; });
    //   data.overwriteDns = true; // always overwriteDns. user can anyway check and uncheck above
    //   repairFunc = Client.configureApp.bind(null, $scope.app.id, 'location', data);
    //   break;

    case ISTATES.PENDING_DATA_DIR_MIGRATION:
      repairFunc = appsModel.configure.bind(null, id.value, 'storage', { storageVolumeId: null, storageVolumePrefix: null });
      break;

    // this also happens for import faliures. this UI can only show backup listing. use CLI for arbit id/config
    case ISTATES.PENDING_RESTORE:
    case ISTATES.PENDING_IMPORT:
      if (backups.value.length === 0) { // this can happen when you give some invalid backup via CLI and restore via UI
        repairFunc = appsModel.repair.bind(null, id.value, {}); // this will trigger a re-install
      } else {
        repairFunc = appsModel.restore.bind(null, id.value, backupId.value);
      }
      break;

    case ISTATES.PENDING_UNINSTALL:
      repairFunc = appsModel.uninstall.bind(null, id.value);
      break;

    case ISTATES.PENDING_START:
    case ISTATES.PENDING_STOP:
    case ISTATES.PENDING_RESTART:
    case ISTATES.PENDING_RESIZE:
    case ISTATES.PENDING_DEBUG:
    case ISTATES.PENDING_RECREATE_CONTAINER:
    case ISTATES.PENDING_CONFIGURE:
    case ISTATES.PENDING_BACKUP: // can happen if the backup task was killed/rebooted
    case ISTATES.PENDING_UPDATE: // when update failed, just bring it back to current state and user can click update again
    default:
      repairFunc = appsModel.repair.bind(null, id.value, {});
      break;
  }

  const [error] = await repairFunc();
  if (error) {
    busy.value = false;
    return console.error(error);
  }

  emit('success');
  dialog.value.close();
  busy.value = false;
}

defineExpose({
  async open(app) {
    id.value = app.id;
    fqdn.value = app.fqdn;
    appError.value = app.error || null;

    const errorState = (app.error && app.error.installationState) || ISTATES.PENDING_CONFIGURE;

    if (errorState === ISTATES.PENDING_RESTORE || errorState === ISTATES.PENDING_IMPORT) {
      const [error, result] = await appsModel.backups(app.id);
      if (error) return console.error(error);

      result.forEach(b => {
        b.label = prettyDate(b.creationTime) + ` - v${b.packageVersion}`;
      });
      backups.value = result;
      backupId.value = '';
    }

    dialog.value.open();
  }
});

</script>

<template>
  <div>
    <Dialog ref="dialog" :title="$t('app.repairDialog.title', { app: fqdn })"
     :confirm-label="$t('app.repairDialog.retryAction', { task: taskNameFromInstallationState(appError ? appError.installationState : '') })"
     :confirm-active="!busy"
     :confirm-busy="busy"
     :reject-label="busy ? '' : $t('main.dialog.cancel')"
      reject-style="secondary"
     @confirm="onSubmit()"
    >
      <div>
        <div class="text-danger" v-if="formError">{{ formError }}</div>

        <div v-if="appError">
          <p v-html="$t('app.repairDialog.taskError', { task: taskNameFromInstallationState(appError ? appError.installationState : '') })"></p>
          <p class="text-danger">{{ appError.reason + ': ' + appError.message }}</p>
        </div>
        <div v-else>
          <p>{{ $t('app.repairDialog.description') }}</p>
        </div>

        <form @submit.prevent="onSubmit()" autocomplete="off">
          <fieldset :disabled="busy">
            <FormGroup v-if="backups.length">
              <label for="backupInput">{{ $t('app.repairDialog.fromBackup') }}</label>
              <SingleSelect :options="backups" v-model="backupId" option-key="id" option-label="label"/>
            </FormGroup>
<!--
        <div class="form-group" ng-show="repair.subdomain && repair.domain">
          <p>{{ 'app.repairDialog.domainDescription' | tr }}</p>
          <label class="control-label">{{ 'app.repairDialog.location' | tr }}</label>
          <div class="input-group form-inline">
            <input type="text" class="form-control" ng-model="repair.subdomain" name="location" placeholder="{{ 'Leave empty to use bare domain' }}">

            <div class="input-group-btn">
              <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
                <span>{{ '.' + repair.domain.domain }}</span>
                <span class="caret"></span>
              </button>
              <ul class="dropdown-menu dropdown-menu-right" role="menu">
                <li ng-repeat="domain in domains">
                  <a href="" ng-click="repair.domain = domain">{{ domain.domain }}</a>
                </li>
              </ul>
            </div>
          </div>
        </div>

        <div ng-show="repair.aliasDomains.length">
          <p ng-repeat="aliasDomain in repair.aliasDomains">
            <label class="control-label"><input type="checkbox" ng-model="aliasDomain.enabled">
               {{ aliasDomain.subdomain + (!aliasDomain.subdomain ? '' : '.') + aliasDomain.domain.domain }}
              </label>
          </p>
        </div>

        <div ng-show="repair.redirectDomains.length">
          <p ng-repeat="redirectDomain in repair.redirectDomains">
            <label class="control-label"><input type="checkbox" ng-model="redirectDomain.enabled">
               {{ redirectDomain.subdomain + (!redirectDomain.subdomain ? '' : '.') + redirectDomain.domain.domain }}
              </label>
          </p>
        </div>
-->
          </fieldset>
        </form>
      </div>
    </Dialog>
  </div>
</template>

