<script setup>

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

const networkModel = NetworkModel.create();

const blocklistLength = ref(0);
const blocklist = ref('');
const blocklistDialog = useTemplateRef('blocklistDialog');
const editBlocklistError = ref('');
const editBlocklistBusy = ref(false);
const editBlocklist = ref('');
const isBlocklistValid = computed(() => {
  return true;
});

async function refreshBlocklist() {
  const [error, result] = await networkModel.getBlocklist();
  if (error) return console.error(error);

  blocklist.value = result;
  blocklistLength.value = result.split('\n').filter(function (l) { return l.length !== 0 && l[0] !== '#'; }).length;
}

function onBlocklistConfigure() {
  editBlocklistBusy.value = false;
  editBlocklistError.value = '';
  editBlocklist.value = blocklist.value;

  blocklistDialog.value.open();
}

async function onBlocklistSubmit() {
  if (!isBlocklistValid.value) return;

  editBlocklistBusy.value = true;
  const [error] = await networkModel.setBlocklist(editBlocklist.value);
  if (error) {
    editBlocklistBusy.value = false;
    editBlocklistError.value = error.body ? error.body.message : 'Internal error';
    return;
  }

  await refreshBlocklist();

  blocklistDialog.value.close();
  editBlocklistBusy.value = false;
}

const trustedIpsLength = ref(0);
const trustedIps = ref('');
const trustedIpsDialog = useTemplateRef('trustedIpsDialog');
const editTrustedIpsError = ref('');
const editTrustedIpsBusy = ref(false);
const editTrustedIps = ref('');
const isTrustedIpsValid = computed(() => {
  return true;
});

function onTrustedIpsConfigure() {
  editTrustedIpsError.value = '';
  editTrustedIpsBusy.value = false;
  editTrustedIps.value = trustedIps.value;

  trustedIpsDialog.value.open();
}

async function onTrustedIpsSubmit() {
  if (!isTrustedIpsValid.value) return;

  editTrustedIpsBusy.value = true;
  const [error] = await networkModel.setTrustedIps(editTrustedIps.value);
  if (error) {
    editTrustedIpsBusy.value = false;
    editTrustedIpsError.value = error.body ? error.body.message : 'Internal error';
    return;
  }

  await refreshTrustedIps();

  trustedIpsDialog.value.close();
  editTrustedIpsBusy.value = false;
}

async function refreshTrustedIps() {
  const [error, result] = await networkModel.getTrustedIps();
  if (error) return console.error(error);

  trustedIps.value = result;
  trustedIpsLength.value = result.split('\n').filter(function (l) { return l.length !== 0 && l[0] !== '#'; }).length;
}

onMounted(async () => {
  await refreshBlocklist();
  await refreshTrustedIps();
});

</script>

<template>
  <div>
    <Dialog ref="blocklistDialog"
      :title="$t('network.firewall.configure.title')"
      :confirm-label="$t('main.dialog.save')"
      :confirm-busy="editBlocklistBusy"
      :confirm-active="!editBlocklistBusy && isBlocklistValid"
      :reject-label="$t('main.dialog.cancel')"
       reject-style="secondary"
      @confirm="onBlocklistSubmit()"
    >
      <div>
        <div class="small">{{ $t('network.firewall.configure.description') }}</div>
        <br/>
        <form novalidate @submit.prevent="onBlocklistSubmit()" autocomplete="off">
          <fieldset :disabled="editBlocklistBusy">
            <input style="display: none" type="submit" :disabled="editBlocklistBusy || !isBlocklistValid"/>
            <FormGroup>
              <label for="blocklistInput">{{ $t('network.firewall.blockedIpRanges') }}</label>
              <div description>{{ $t('network.firewall.configure.blocklistPlaceholder') }}</div>
              <div class="has-error" v-show="editBlocklistError">{{ editBlocklistError }}</div>
              <textarea id="blocklistInput" v-model="editBlocklist" rows="4"></textarea>
            </FormGroup>
          </fieldset>
        </form>
      </div>
    </Dialog>

    <Dialog ref="trustedIpsDialog"
      :title="$t('network.trustedIps.title')"
      :confirm-label="$t('main.dialog.save')"
      :confirm-busy="editTrustedIpsBusy"
      :confirm-active="!editTrustedIpsBusy && isTrustedIpsValid"
      :reject-label="$t('main.dialog.cancel')"
       reject-style="secondary"
      @confirm="onTrustedIpsSubmit()"
    >
      <div>
        <div class="small">{{ $t('network.trustedIps.description') }}</div>
        <br/>
        <form novalidate @submit.prevent="onTrustedIpsSubmit()" autocomplete="off">
          <fieldset :disabled="editTrustedIpsBusy">
            <input style="display: none;" type="submit" :disabled="editTrustedIpsBusy || !isTrustedIpsValid"/>
            <FormGroup>
              <label for="">{{ $t('network.trustedIpRanges') }}</label>
              <div description>{{ $t('network.firewall.configure.blocklistPlaceholder') }}</div>
              <div class="has-error" v-show="editTrustedIpsError">{{ editTrustedIpsError }}</div>
              <textarea v-model="editTrustedIps" rows="4"></textarea>
            </FormGroup>
          </fieldset>
        </form>
      </div>
    </Dialog>

    <Section :title="$t('network.firewall.title')">
      <SettingsItem>
        <FormGroup>
          <label>{{ $t('network.firewall.blockedIpRanges') }}</label>
          <div>{{ $t('network.firewall.blocklist', { blockCount: blocklistLength }) }}</div>
        </FormGroup>
        <div style="display: flex; align-items: center">
          <Button tool plain @click="onBlocklistConfigure()">{{ $t('main.dialog.edit') }}</Button>
        </div>
      </SettingsItem>

      <SettingsItem>
        <FormGroup>
          <label>{{ $t('network.trustedIpRanges') }}</label>
          <div>{{ $t('network.trustedIps.summary', { trustCount: trustedIpsLength }) }}</div>
        </FormGroup>
        <div style="display: flex; align-items: center">
          <Button tool plain @click="onTrustedIpsConfigure()">{{ $t('main.dialog.edit') }}</Button>
        </div>
      </SettingsItem>
    </Section>
  </div>
</template>
