<script setup>

import { ref, onMounted, computed } from 'vue';
import { prettyDecimalSize, sleep } from '@cloudron/pankow/utils';
import { prettyRelayProviderName } from '../utils.js';
import { TextInput, ProgressBar } from '@cloudron/pankow';
import Section from '../components/Section.vue';
import StateLED from  '../components/StateLED.vue';
import DomainsModel from '../models/DomainsModel.js';
import MailModel from '../models/MailModel.js';

const domainsModel = DomainsModel.create();
const mailModel = MailModel.create();

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

const searchFilter = ref('');

const filteredDomains = computed(() => {
  if (!searchFilter.value) return domains.value;

  return domains.value.filter(d => {
    const search = searchFilter.value.toLowerCase();

    if (d.domain.toLowerCase().indexOf(search) !== -1) return true;
    if (d.provider.toLowerCase().indexOf(search) !== -1) return true;

    if (d.inboundEnabled && 'inbound'.includes(search)) return true;
    if (d.outboundEnabled && 'outbound'.includes(search)) return true;

    return false;
  });
});


async function refreshStatus() {
  for (const domain of domains.value) {
    const [error, result] = await mailModel.status(domain.domain);
    if (error) {
      console.error(error);
    } else {
      domain.status = Object.keys(result).every((k) => {
        return result[k].status === 'passed' || result[k].status === 'skipped';
      });
      domain.loadingStatus = false;
    }
  }
}

async function refreshUsage() {
  for (const domain of domains.value) {
    let [error, result] = await mailModel.config(domain.domain);
    if (error) return console.error(error);

    domain.inboundEnabled = result.enabled;
    domain.outboundEnabled = result.relay?.provider !== 'noop';
    domain.relayProvider = result.relay ? result.relay.provider : 'unset';

    // do this even if no outbound since people forget to remove mailboxes
    [error, result] = await mailModel.stats(domain.domain);
    if (error) console.error(error);

    domain.mailboxCount = result.mailboxCount;

    // this may temporarily fail while the mail server is restarting
    while (true) {
      const [error, result] = await mailModel.usage(domain.domain);
      if (error && error.status === 424) {
        await sleep(1000);
        continue;
      } else if (error) return console.error(error);

      domain.usage = 0;
      // we used to use quotaValue here but it's quite different wrt diskSize. so choose diskSize consistently
      // also, quotaValue can be missing for deleted mailboxes that are on disk but removed from dovecot/ldap itself
      Object.keys(result).forEach(function (m) { domain.usage += result[m].diskSize; });

      break;
    }

    domain.loadingUsage = false;
  }
}

onMounted(async () => {
  const [error, result] = await domainsModel.list();
  if (error) {
    busy.value = false;
    return console.error(error);
  }

  result.forEach(d => {
    d.loadingStatus = true;
    d.status = {
      state: ''
    };

    d.loadingUsage = true;
    d.mailboxCount = 0;
    d.usage = 0;
    d.inboundEnabled = true;
    d.outboundEnabled = true;
  });

  domains.value = result;
  busy.value = false;

  refreshStatus();
  refreshUsage();
});

</script>

<template>
  <div class="content">
    <Section :title="$t('emails.domains.title')">
      <template #header-title-extra>
        <span style="font-weight: normal; font-size: 14px">({{ busy ? '-' : filteredDomains.length }})</span>
      </template>

      <template #header-buttons>
        <TextInput :placeholder="$t('main.searchPlaceholder')" style="flex-grow: 1;" v-model="searchFilter"/>
      </template>

      <div>
        <ProgressBar v-if="busy" mode="indeterminate" :show-label="false" :slim="true" :show-track="false"/>
        <div v-if="domains.length !== 0 && filteredDomains.length === 0" class="email-placeholder">{{ $t('domains.noMatchesPlaceholder') }}</div>
        <a v-for="domain in filteredDomains" :key="domain.domain" :href="`#/email-domain/${domain.domain}`" class="email-domain">
         <div style="display: flex; align-items: center;">
            <StateLED :busy="domain.loadingStatus" :state="domain.status ? 'success' : 'danger'"/>
          </div>
          <div class="email-domain-details">
            <div><b style="font-size: 16px">{{ domain.domain }}</b></div>
            <div v-if="domain.loadingUsage">
              {{ $t('main.loadingPlaceholder') }} ...
            </div>
            <div v-else>
              <div v-if="domain.inboundEnabled">
                {{ $t('emails.domains.inbound') }}. Relayed via {{ prettyRelayProviderName(domain.relayProvider) }}. {{ $t('emails.domains.stats', { mailboxCount: domain.mailboxCount, usage: prettyDecimalSize(domain.usage) }) }}
              </div>
              <div v-else>
                <span v-if="domain.outboundEnabled">{{ $t('emails.domains.outbound') }}. Relayed via {{ prettyRelayProviderName(domain.relayProvider) }}</span>
                <span v-else>{{ $t('emails.domains.disabled') }}</span>
              </div>
            </div>
          </div>
        </a>
      </div>
    </Section>
  </div>
</template>

<style scoped>

.email-placeholder {
  text-align: center;
  margin-top: 150px;
}

.email-domain {
  display: flex;
  border-radius: var(--pankow-border-radius);
  padding: 10px;
  gap: 10px;
  margin-bottom: 10px;
  color: var(--pankow-text-color);
}

.email-domain:hover {
  background-color: var(--pankow-color-background-hover);
}

.email-domain-details {
  flex-grow: 1;
}

</style>