<script setup>

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

import { ref, onMounted, useTemplateRef, computed } from 'vue';
import { Button, TableView, Dialog, TextInput } from '@cloudron/pankow';
import { eachLimit } from 'async';
import ActionBar from '../components/ActionBar.vue';
import Section from '../components/Section.vue';
import MailinglistDialog from '../components/MailinglistDialog.vue';
import DomainsModel from '../models/DomainsModel.js';
import MailinglistsModel from '../models/MailinglistsModel.js';

const domainsModel = DomainsModel.create();
const mailinglistsModel = MailinglistsModel.create();

const columns = {
  membersOnly: {},
  fullName: {
    label: t('email.incoming.mailinglists.name'),
    sort: true
  },
  members: {
    label: t('email.incoming.mailinglists.members'),
    sort: true,
    hideMobile: true,
  },
  actions: {
    width: '100px'
  }
};

function createActionMenu(mailinglist) {
  return [{
    icon: 'fa-solid fa-pencil-alt',
    label: t('main.action.edit'),
    quickAction: true,
    action: onAddOrEdit.bind(null, mailinglist),
  }, {
    icon: 'fa-solid fa-trash-alt',
    label: t('main.action.remove'),
    quickAction: true,
    action: onRemove.bind(null, mailinglist),
  }];
}

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

const searchFilter = ref('');

const filteredMailinglists = computed(() => {
  if (!searchFilter.value) return mailinglists.value;

  return mailinglists.value.filter(m => {
    const search = searchFilter.value.toLowerCase();

    if (m.fullName.includes(search)) return true;
    if (m.members.find(a => a.toLowerCase().indexOf(search) !== -1)) return true;

    return false;
  });
});

const mailinglistDialog = useTemplateRef('mailinglistDialog');

async function onAddOrEdit(mailinglist = null) {
  mailinglistDialog.value.open(mailinglist);
}

const removeDialog = useTemplateRef('removeDialog');
const removeBusy = ref(false);
const removeError = ref('');
const removeMailinglist = ref({});

function onRemove(mailinglist) {
  removeBusy.value = false;
  removeError.value = '';
  removeMailinglist.value = mailinglist;

  removeDialog.value.open();
}

async function onSubmitRemove() {
  removeBusy.value = true;
  removeError.value = '';

  const [error] = await mailinglistsModel.remove(removeMailinglist.value.domain, removeMailinglist.value.name);
  if (error) {
    removeBusy.value = false;
    removeError.value = error.body ? error.body.message : 'Internal error';
    return console.error(error);
  }

  await refresh();
  removeDialog.value.close();

  removeBusy.value = false;
}

async function refresh() {
  let tmp = [];
  async function refreshForDomain(domain) {
    const [error, result] = await mailinglistsModel.list(domain);
    if (error) throw error;

    result.forEach((m) => {
      m.fullName = m.name + '@' + m.domain;
    });

    tmp = tmp.concat(result);
  }

  try {
    await eachLimit(domains.value.map(d => d.domain), 10, refreshForDomain);
  } catch (error) {
    return console.error(error);
  }

  mailinglists.value = tmp;
}

onMounted(async () => {
  busy.value = true;

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

  domains.value = result;

  await refresh();

  busy.value = false;
});

</script>

<template>
  <div class="content">
    <Dialog ref="removeDialog"
      :title="$t('email.deleteMailinglistDialog.title')"
      :confirm-label="$t('email.deleteMailinglistDialog.deleteAction')"
      :confirm-busy="removeBusy"
      :confirm-active="!removeBusy"
       confirm-style="danger"
      :reject-label="$t('main.dialog.cancel')"
      :reject-active="!removeBusy"
       reject-style="secondary"
      @confirm="onSubmitRemove()"
    >
      <div>
        <div class="text-danger" v-if="removeError">{{ removeError }}</div>
        <div v-html="$t('email.deleteMailinglistDialog.description', { name: removeMailinglist.name, domain: removeMailinglist.domain })"></div>
      </div>
    </Dialog>

    <MailinglistDialog ref="mailinglistDialog" :domains="domains" @success="refresh()"/>

    <Section :title="$t('email.incoming.mailinglists.title')">
      <template #header-title-extra>
        <span style="font-weight: normal; font-size: 14px">({{ busy ? '-' : filteredMailinglists.length }})</span>
      </template>

      <template #header-buttons>
        <TextInput :placeholder="$t('main.searchPlaceholder')" style="flex-grow: 1;" v-model="searchFilter"/>
        <Button @click="onAddOrEdit()">{{ $t('email.incoming.mailboxes.addAction') }}</Button>
      </template>

      <TableView :columns="columns" :model="filteredMailinglists" :busy="busy" :placeholder="$t(searchFilter ? 'email.incoming.mailinglists.noMatchesPlaceholder' : 'email.incoming.mailinglists.emptyPlaceholder')">
        <template #membersOnly="{ item:mailinglist }">
          <i class="fas" :class="{ 'fa-door-closed': mailinglist.membersOnly, 'fa-door-open': !mailinglist.membersOnly }" v-tooltip="$t(mailinglist.membersOnly ? 'email.incoming.mailinglists.everyoneTooltip' : 'email.incoming.mailinglists.membersOnlyTooltip')"></i>
        </template>
        <template #members="{ item:mailinglist }">
          {{ mailinglist.members.length }}
        </template>
        <template #actions="{ item:mailinglist }">
          <ActionBar :actions="createActionMenu(mailinglist)"/>
        </template>
      </TableView>
    </Section>
  </div>
</template>
