<script setup>

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

import { ref, onMounted, useTemplateRef, inject } from 'vue';
import { Button, ProgressBar, Checkbox, InputDialog, Dialog, FormGroup, Switch } from '@cloudron/pankow';
import SaveIndicator from '../components/SaveIndicator.vue';
import Section from '../components/Section.vue';
import SettingsItem from '../components/SettingsItem.vue';
import CatchAllSettingsItem from '../components/CatchAllSettingsItem.vue';
import MailRelaySettingsItem from '../components/MailRelaySettingsItem.vue';
import MailDomainStatus from '../components/MailDomainStatus.vue';
import DashboardModel from '../models/DashboardModel.js';
import DomainsModel from '../models/DomainsModel.js';
import MailModel from '../models/MailModel.js';
import ProfileModel from '../models/ProfileModel.js';

const dashboardModel = DashboardModel.create();
const domainsModel = DomainsModel.create();
const mailModel = MailModel.create();
const profileModel = ProfileModel.create();

const features = inject('features');

const inputDialog = useTemplateRef('inputDialog');
const enableIncomingDialog = useTemplateRef('enableIncomingDialog');
const connectionDialog = useTemplateRef('connectionDialog');
const domain = ref('');
const domainProvider = ref('');
const mailConfig = ref({});
const mailFqdn = ref('');
const adminDomain = ref('');
const adminDomainProvider = ref('');
const enableIncomeBusy = ref(false);
const enableIncomingSetupDns = ref(true);
const infoMenu = ref([]);
const busyRefresh = ref(true);
const inboundEnabled = ref(false);
const outboundEnabled = ref(false);

async function onSendTestMail() {
  const [error, result] = await profileModel.get();
  if (error) return console.error(error);

  const address = await inputDialog.value.prompt({
    value: result.email,
    title: t('emails.testMailDialog.title'),
    message: t('emails.testMailDialog.description', { domain: domain.value }),
    confirmLabel: t('emails.testMailDialog.sendAction'),
    rejectLabel: t('main.dialog.cancel'),
    rejectStyle: 'secondary',
  });

  if (!address) return;

  const [sendError] = await mailModel.sendTestMail(domain.value, address);
  if (sendError) {
    window.pankow.notify({ text: sendError.body ? sendError.body.message : 'Failed to send mail', type: 'danger' });
    return console.error(sendError);
  }

  window.pankow.notify({ text: 'Mail sent', type: 'success' });
}


function onShowConnectionDialog() {
  connectionDialog.value.open();
}

async function onAskIncomingToggle(value) {
  if (value) {
    enableIncomeBusy.value = false;
    return enableIncomingDialog.value.open();
  }

  const yes = await inputDialog.value.confirm({
    title: t('email.disableEmailDialog.title'),
    message: t('email.disableEmailDialog.description', { domain: domain.value }),
    confirmStyle: 'danger',
    confirmLabel: t('email.disableEmailDialog.disableAction'),
    rejectLabel: t('main.dialog.cancel'),
    rejectStyle: 'secondary',
  });

  // reset switch
  if (!yes) return inboundEnabled.value = true;

  const [error] = await mailModel.setEnabled(domain.value, false);
  if (error) return console.error(error);

  await onDomainChanged();
}

async function onEnableIncoming() {
  enableIncomeBusy.value = true;

  const [error] = await mailModel.setEnabled(domain.value, true);
  if (error) return console.error(error);

  // FIXME this has to be done in the backend here! reconfigureEmailApps();

  if (enableIncomingSetupDns.value) {
    const [error] = await domainsModel.setDnsRecords({ domain: domain.value, type: 'mail' });
    if (error) console.error(error);
  }

  await onDomainChanged();

  enableIncomingDialog.value.close();
  enableIncomeBusy.value = false;
}


const customFrom = ref(false);
const customFromBusy = ref(false);
const customFromSaveIndicator = useTemplateRef('customFromSaveIndicator');

async function onToggleCustomFrom(value) {
  customFromBusy.value = true;

  const [error] = await mailModel.setMailFromValidation(domain.value, !value); // note: inverted logic between UI switch and API
  if (error) {
    customFrom.value = !value; // revert back old value
    customFromBusy.value = false;
    customFromSaveIndicator.value.error();
    return console.error(error);
  }

  customFromSaveIndicator.value.success();
  customFromBusy.value = false;
}


const signatureDialog = useTemplateRef('signatureDialog');
const signatureBusy = ref(false);
const signatureText = ref('');
const signatureHtml = ref('');

function onShowSignatureDialog() {
  signatureBusy.value = false;
  signatureDialog.value.open();
}

async function onSubmitSignature() {
  signatureBusy.value = true;

  const [error] = await mailModel.setMailBanner(domain.value, signatureText.value, signatureHtml.value);
  if (error) return console.error(error);

  signatureDialog.value.close();
  signatureBusy.value = false;
}

async function onDomainChanged() {
  busyRefresh.value = true;

  let [error, result] = await domainsModel.get(domain.value);
  if (error) return console.error(error);

  domainProvider.value = result.provider;

  [error, result] = await mailModel.config(domain.value);
  if (error) return console.error(error);

  mailConfig.value = result;
  inboundEnabled.value = result.enabled;
  outboundEnabled.value = result.relay?.provider !== 'noop';
  customFrom.value = !result.mailFromValidation; // note: inverted logic between UI switch and API
  signatureText.value = mailConfig.value.banner.text || '';
  signatureHtml.value = mailConfig.value.banner.html || '';

  infoMenu.value = [{
    label: t('app.docsAction'),
    href: 'https://docs.cloudron.io/email/',
    target: '_blank',
  }, {
    label: t('email.config.clientConfiguration'),
    disabled: !mailConfig.value.enabled,
    action: onShowConnectionDialog
  }];

  busyRefresh.value = false;
}

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

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

  domain.value = parts[0];

  let [error, result] = await dashboardModel.config();
  if (error) return console.error(error);

  mailFqdn.value = result.mailFqdn;
  adminDomain.value = result.adminDomain;

  [error, result] = await domainsModel.get(result.adminDomain);
  if (error) return console.error(error);
  adminDomainProvider.value = result.provider;

  [error, result] = await domainsModel.list();
  if (error) return console.error(error);

  await onDomainChanged();
});

</script>

<template>
  <div class="content">
    <InputDialog ref="inputDialog"/>

    <Dialog ref="connectionDialog"
      :title="$t('email.howToConnectInfoModal')"
      :reject-label="$t('main.dialog.close')"
    >
      <div>
        <p v-html="$t('email.incoming.howToConnectDescription', { domain: domain })"></p>

        <p><b>{{ $t('email.incoming.incomingUserInfo') }}</b><br/><i>mailboxname</i>@{{ domain }}</p>
        <p><b>{{ $t('email.incoming.incomingPasswordInfo') }}</b><br/>{{ $t('email.incoming.incomingPasswordUsage') }}</p>
        <p><b>{{ $t('email.incoming.incomingServerInfo') }}</b><br/>{{ $t('email.incoming.server') }}: <span>{{ mailFqdn }}</span><br/>{{ $t('email.incoming.port') }}: 993 (TLS)</p>
        <p><b>{{ $t('email.incoming.outgointServerInfo') }}</b><br/>{{ $t('email.incoming.server') }}: <span>{{ mailFqdn }}</span><br/>{{ $t('email.incoming.port') }}: 587 (STARTTLS) or 465 (TLS)</p>
        <p><b>{{ $t('email.incoming.sieveServerInfo') }}</b><br/>{{ $t('email.incoming.server') }}: <span>{{ mailFqdn }}</span><br/>{{ $t('email.incoming.port') }}: 4190 (STARTTLS)</p>
      </div>
    </Dialog>

    <Dialog ref="enableIncomingDialog"
      :title="$t('email.enableEmailDialog.title')"
      :confirm-label="$t('email.enableEmailDialog.enableAction')"
      :confirm-busy="enableIncomeBusy"
      :reject-label="$t('main.dialog.cancel')"
      :reject-active="!enableIncomeBusy"
       reject-style="secondary"
      @confirm="onEnableIncoming()"
      @reject="inboundEnabled = false"
    >
      <div>
        <p v-html="$t('email.enableEmailDialog.description', { domain: domain, requiredPortsDocsLink: 'https://docs.cloudron.io/email/#firewall' })"></p>
        <div v-if="domainProvider === 'noop' || domainProvider === 'manual'" v-html="$t('email.enableEmailDialog.noProviderInfo')"></div>
        <div v-else>
          <Checkbox v-model="enableIncomingSetupDns" :disabled="enableIncomeBusy" :label="$t('email.enableEmailDialog.setupDnsCheckbox')"/>
          <div v-html="$t('email.enableEmailDialog.setupDnsInfo', { importEmailDocsLink: 'https://docs.cloudron.io/guides/import-email' })"></div>
        </div>
      </div>
    </Dialog>

    <Dialog ref="signatureDialog"
      :title="$t('email.signature.title')"
      :confirm-label="$t('main.dialog.save')"
      :confirm-busy="signatureBusy"
      :reject-label="$t('main.dialog.cancel')"
      :reject-active="!signatureBusy"
       reject-style="secondary"
      @confirm="onSubmitSignature()"
    >
      <p v-html="$t('email.signature.description')"></p>

      <div>
        <form @submit.prevent="onSubmitSignature()" autocomplete="off">
          <fieldset :disabled="signatureBusy">
            <input type="submit" style="display: none"/>

            <FormGroup>
              <label for="sinatureTextInput">{{ $t('email.signature.plainTextFormat') }}</label>
              <textarea id="sinatureTextInput" v-model="signatureText" rows="4"></textarea>
            </FormGroup>

            <FormGroup>
              <label class="sinatureHtmlInput">{{ $t('email.signature.htmlFormat') }}</label>
              <textarea id="sinatureHtmlInput" v-model="signatureHtml" rows="4"></textarea>
            </FormGroup>

          </fieldset>
        </form>
      </div>
    </Dialog>

    <h1 class="view-header">{{ $t('email.config.title', { domain: domain }) }}</h1>

    <ProgressBar mode="indeterminate" v-if="busyRefresh" slim :show-label="false" />

    <Section :title="$t('email.config.sending.title')" v-if="!busyRefresh">
      <template #header-buttons>
        <Button @click="onSendTestMail">{{ $t('emails.domains.testEmailTooltip') }}</Button>
      </template>

      <MailRelaySettingsItem v-if="domain" :domain="domain" :adminDomain="adminDomain"/>

      <SettingsItem>
        <FormGroup>
          <label>{{ $t('email.customFrom.title') }}</label>
          <div v-html="$t('email.customFrom.description')"></div>
        </FormGroup>
        <Switch v-model="customFrom" @change="onToggleCustomFrom" :disabled="customFromBusy"/>
        <SaveIndicator ref="customFromSaveIndicator"/>
      </SettingsItem>

      <SettingsItem>
        <FormGroup>
          <label>{{ $t('email.signature.title') }}</label>
          <div v-if="signatureHtml || signatureText">{{ $t('email.signature.customSignatureSet') }}</div>
          <div v-else>{{ $t('email.signature.noSignatureSet') }}</div>
        </FormGroup>
        <div style="display: flex; align-items: center">
          <Button tool plain @click="onShowSignatureDialog()">{{ $t('main.dialog.edit') }}</Button>
        </div>
      </SettingsItem>
    </Section>

    <Section :title="$t('email.config.receiving.title')" v-if="!busyRefresh" :title-badge="!features.emailServer ? 'Upgrade' : ''">
      <template #header-buttons>
        <Button secondary tool icon="fa-solid fa-book" v-tooltip="$t('app.docsActionTooltip')" :menu="infoMenu" />
      </template>

      <SettingsItem>
        <FormGroup>
          <label>{{ $t('email.incoming.title') }}</label>
          <div>{{ $t('email.incoming.description') }}</div>
        </FormGroup>
        <Switch v-model="inboundEnabled" :disabled="busyRefresh || !features.emailServer" @change="onAskIncomingToggle"/>
      </SettingsItem>

      <CatchAllSettingsItem :domain-config="mailConfig" :disabled="!features.emailServer"/>
    </Section>

    <MailDomainStatus v-if="!busyRefresh && domain" :domain="domain"/>
  </div>
</template>
