<script setup>

import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, Dialog, SingleSelect, FormGroup, TextInput } from 'pankow';
import Section from  '../components/Section.vue';
import NetworkModel from  '../models/NetworkModel.js';

const networkModel = NetworkModel.create();

// keep in sync with sysinfo.js
const providers = [
    { name: 'Disabled', value: 'noop' },
    { name: 'Public IP', value: 'generic' },
    { name: 'Static IP Address', value: 'fixed' },
    { name: 'Network Interface', value: 'network-interface' }
];

function prettyIpProviderName(provider) {
  switch (provider) {
    case 'noop': return 'Disabled';
    case 'generic': return 'Public IP';
    case 'fixed': return 'Static IP Address';
    case 'network-interface': return 'Network Interface';
    default: return 'Unknown';
  }
}

const provider = ref('');
const address = ref('');
const detectedAddress = ref('');
const interfaceName = ref('');
const dialog = useTemplateRef('dialog');
const editError = ref({});
const editBusy = ref(false);
const editProvider = ref('');
const editAddress = ref('');
const editInterfaceName = ref('');

const isValid = computed(() => {
  if (editProvider.value === 'fixed' && !editAddress.value) return false;
  if (editProvider.value === 'network-interface' && !editInterfaceName.value) return false;

  return true;
});

async function refresh() {
  let [error, result] = await networkModel.getIpv6Config();
  if (error) return console.error(error);

  provider.value = result.provider;
  address.value = result.ip;
  interfaceName.value = result.ifname;

  [error, result] = await networkModel.getIpv6();
  if (error) return console.error(error);

  detectedAddress.value = result;
}

function onConfigure() {
  editBusy.value = false;
  editError.value = {};
  editProvider.value = provider.value;
  editAddress.value = address.value || '';
  editInterfaceName.value = interfaceName.value || '';

  dialog.value.open();
}

async function onSubmit() {
  if (!isValid.value) return;

  editBusy.value = true;
  editError.value = {};

  const [error] = await networkModel.setIpv6Config(editProvider.value, editAddress.value.trim(), editInterfaceName.value.trim());
  if (error) {
    editBusy.value = false;
    if (error.body && error.body.message === 'invalid IPv6') editError.value.ipv4 = error.body.message;
    else if (error.body && error.body.message.indexOf('No interface named') === 0) editError.value.ifname = error.body.message;
    else editError.value.generic = error.body ? error.body.message : 'Internal error';
    return;
  }

  await refresh();

  dialog.value.close();
  editBusy.value = false;
}

onMounted(async () => {
  await refresh();
});

</script>

<template>
  <div>
    <Dialog ref="dialog"
      :title="$t('network.configureIpv6.title')"
      :confirm-label="$t('main.dialog.save')"
      :confirm-busy="editBusy"
      :confirm-active="isValid"
      :reject-label="$t('main.dialog.cancel')"
       reject-style="secondary"
      @confirm="onSubmit()"
    >
      <div>
        <form novalidate @submit.prevent="onSubmit()" autocomplete="off">
          <fieldset :disabled="editBusy">
            <input style="display: none" type="submit" :disabled="editBusy || !isValid"/>

            <FormGroup>
              <label for="providerInput">{{ $t('network.ip.provider') }} <sup><a href="https://docs.cloudron.io/networking/#ipv4" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
              <SingleSelect id="providerInput" v-model="editProvider" :options="providers" option-key="value" option-label="name"/>
              <div class="error-label" v-show="editError.generic">{{ editError.generic }}</div>
            </FormGroup>

            <p v-show="editProvider === 'generic'">
              {{ $t('network.configureIp.providerGenericDescription') }} <sup><a href="https://ipv4.api.cloudron.io/api/v1/helper/public_ip" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup>
            </p>

            <!-- Fixed -->
            <FormGroup v-show="editProvider === 'fixed'">
              <label for="addressInput">{{ $t('network.ipv6.address') }}</label>
              <TextInput id="addressInput" v-model="editAddress" :required="editProvider === 'fixed'" />
              <div class="error-label" v-show="editError.ipv4">{{ editError.ipv4 }}</div>
            </FormGroup>

            <!-- Network Interface -->
            <FormGroup v-show="editProvider === 'network-interface'">
              <label for="interfaceNameInput">{{ $t('network.ip.interface') }}</label>
              <TextInput id="interfaceNameInput" v-model="editInterfaceName" :required="editProvider === 'network-interface'" />
              <div class="error-label" v-show="editError.ifname">{{ editError.ifname }}</div>
              <p>{{ $t('network.ip.interfaceDescription') }} <code>ip -f inet6 -br addr</code></p>
            </FormGroup>
          </fieldset>
        </form>
      </div>
    </Dialog>

    <Section :title="$t('network.ipv6.title')">
      <p>{{ $t('network.ipv6.description') }}</p>

      <div class="info-row">
        <div class="info-label">{{ $t('network.ip.provider') }}</div>
        <div class="info-value">{{ prettyIpProviderName(provider) }}</div>
      </div>
      <div class="info-row" v-show="provider !== 'noop'">
        <div class="info-label">{{ $t('network.ip.address') }}</div>
        <div class="info-value">{{ address || `${detectedAddress} (${$t('network.ip.detected')})` }}</div>
      </div>
      <div class="info-row" v-show="interfaceName">
        <div class="info-label">{{ $t('network.ip.interface') }}</div>
        <div class="info-value">{{ interfaceName }}</div>
      </div>

      <Button @click="onConfigure()">{{ $t('network.ip.configure') }}</Button>
    </Section>
  </div>
</template>
