<script setup>
import { ref, reactive, computed, onBeforeMount } from 'vue';
import { useRouter, onBeforeRouteUpdate } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import { toCurrency, toDate } from 'src/filters';
import { useAcl } from 'src/composables/useAcl';
import { downloadFile } from 'src/composables/downloadFile';
import { useArrayData } from 'src/composables/useArrayData';
import { usePrintService } from 'composables/usePrintService';
import VnLv from 'src/components/ui/VnLv.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import FetchData from 'src/components/FetchData.vue';
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useCapitalize } from 'src/composables/useCapitalize';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import InvoiceInToBook from '../InvoiceInToBook.vue';

const $props = defineProps({ id: { type: Number, default: null } });

const { push, currentRoute } = useRouter();

const quasar = useQuasar();
const { hasAny } = useAcl();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
const arrayData = useArrayData();

const invoiceIn = computed(() => arrayData.store.data);
const cardDescriptorRef = ref();
const correctionDialogRef = ref();
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
const totalAmount = ref();
const currentAction = ref();
const config = ref();
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceOuts = ref([]);
const invoiceCorrectionTypes = ref([]);
const actions = {
    unbook: {
        title: t('assertAction', { action: t('unbook') }),
        action: toUnbook,
    },
    delete: {
        title: t('assertAction', { action: t('delete') }),
        action: deleteInvoice,
    },
    clone: {
        title: t('assertAction', { action: t('clone') }),
        action: cloneInvoice,
    },
    showPdf: { cb: showPdfInvoice },
    sendPdf: { cb: sendPdfInvoiceConfirmation },
    correct: { cb: () => correctionDialogRef.value.show() },
};
const filter = {
    include: [
        {
            relation: 'supplier',
            scope: {
                include: {
                    relation: 'contacts',
                    scope: {
                        where: {
                            email: { neq: null },
                        },
                    },
                },
            },
        },
        {
            relation: 'invoiceInDueDay',
        },
        {
            relation: 'company',
        },
        {
            relation: 'currency',
        },
    ],
};
const invoiceInCorrection = reactive({ correcting: [], corrected: null });
const routes = reactive({
    getSupplier: (id) => {
        return { name: 'SupplierCard', params: { id } };
    },
    getTickets: (id) => {
        return {
            name: 'InvoiceInList',
            query: {
                params: JSON.stringify({ supplierFk: id }),
            },
        };
    },
    getCorrection: (invoiceInCorrection) => {
        if (invoiceInCorrection.correcting.length > 1) {
            return {
                name: 'InvoiceInList',
                query: {
                    params: JSON.stringify({ correctedFk: entityId.value }),
                },
            };
        }

        return {
            name: 'InvoiceInCard',
            params: {
                id: invoiceInCorrection.corrected ?? invoiceInCorrection.correcting[0],
            },
        };
    },
    getEntry: (id) => {
        return { name: 'EntryCard', params: { id } };
    },
});
const correctionFormData = reactive({
    invoiceReason: 2,
    invoiceType: 2,
    invoiceClass: 6,
});
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));

onBeforeMount(async () => {
    await setInvoiceCorrection(entityId.value);
    const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
    totalAmount.value = data.totalDueDay;
});

onBeforeRouteUpdate(async (to, from) => {
    if (to.params.id !== from.params.id) {
        await setInvoiceCorrection(to.params.id);
        const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`);
        totalAmount.value = data.totalDueDay;
    }
});

async function setInvoiceCorrection(id) {
    invoiceInCorrection.correcting.length = 0;
    invoiceInCorrection.corrected = null;
    const { data: correctingData } = await axios.get('InvoiceInCorrections', {
        params: { filter: { where: { correctingFk: id } } },
    });
    const { data: correctedData } = await axios.get('InvoiceInCorrections', {
        params: { filter: { where: { correctedFk: id } } },
    });

    if (correctingData[0]) invoiceInCorrection.corrected = correctingData[0].correctedFk;

    invoiceInCorrection.correcting = correctedData.map(
        (corrected) => corrected.correctingFk
    );
}

function openDialog() {
    quasar.dialog({
        component: VnConfirm,
        componentProps: {
            title: t(currentAction.value.title),
            promise: currentAction.value.action,
        },
    });
}

async function toUnbook() {
    const { data } = await axios.post(`InvoiceIns/${entityId.value}/toUnbook`);
    const { isLinked, bookEntry, accountingEntries } = data;

    const type = isLinked ? 'warning' : 'positive';
    const message = isLinked
        ? t('isLinked', { bookEntry, accountingEntries })
        : t('isNotLinked', { bookEntry });

    quasar.notify({ type, message });
    if (!isLinked) arrayData.store.data.isBooked = false;
}

async function deleteInvoice() {
    await axios.delete(`InvoiceIns/${entityId.value}`);
    quasar.notify({
        type: 'positive',
        message: t('Invoice deleted'),
    });
    push({ path: '/invoice-in' });
}

async function cloneInvoice() {
    const { data } = await axios.post(`InvoiceIns/${entityId.value}/clone`);
    quasar.notify({
        type: 'positive',
        message: t('Invoice cloned'),
    });
    push({ path: `/invoice-in/${data.id}/summary` });
}

const canEditProp = (props) =>
    hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);

const isAgricultural = () => {
    if (!config.value) return false;
    return (
        invoiceIn.value?.supplier?.sageFarmerWithholdingFk ===
        config?.value[0]?.sageWithholdingFk
    );
};

function showPdfInvoice() {
    if (isAgricultural()) openReport(`InvoiceIns/${entityId.value}/invoice-in-pdf`);
}

function sendPdfInvoiceConfirmation() {
    quasar.dialog({
        component: SendEmailDialog,
        componentProps: {
            data: {
                address: invoiceIn.value.supplier.contacts[0].email,
            },
            promise: sendPdfInvoice,
        },
    });
}

function sendPdfInvoice({ address }) {
    if (!address)
        quasar.notify({
            type: 'negative',
            message: t(`The email can't be empty`),
        });
    else
        return sendEmail(`InvoiceIns/${entityId.value}/invoice-in-email`, {
            recipientId: invoiceIn.value.supplier.id,
            recipient: address,
        });
}

function triggerMenu(type) {
    currentAction.value = actions[type];
    if (currentAction.value.cb) currentAction.value.cb();
    else openDialog(type);
}

const createInvoiceInCorrection = async () => {
    const { data: correctingId } = await axios.post(
        'InvoiceIns/corrective',
        Object.assign(correctionFormData, { id: entityId.value })
    );
    push({ path: `/invoice-in/${correctingId}/summary` });
};
</script>
<template>
    <FetchData
        url="InvoiceInConfigs"
        :where="{ fields: ['sageWithholdingFk'] }"
        auto-load
        @on-fetch="(data) => (config = data)"
    />
    <FetchData
        url="CplusRectificationTypes"
        @on-fetch="(data) => (cplusRectificationTypes = data)"
        auto-load
    />
    <FetchData
        url="SiiTypeInvoiceOuts"
        :where="{ code: { like: 'R%' } }"
        @on-fetch="(data) => (siiTypeInvoiceOuts = data)"
        auto-load
    />
    <FetchData
        url="InvoiceCorrectionTypes"
        @on-fetch="(data) => (invoiceCorrectionTypes = data)"
        auto-load
    />
    <CardDescriptor
        ref="cardDescriptorRef"
        module="InvoiceIn"
        data-key="InvoiceIn"
        :url="`InvoiceIns/${entityId}`"
        :filter="filter"
        title="supplierRef"
    >
        <template #menu="{ entity }">
            <InvoiceInToBook>
                <template #content="{ book }">
                    <QItem
                        v-if="!entity?.isBooked && canEditProp('toBook')"
                        v-ripple
                        clickable
                        @click="book(entityId)"
                    >
                        <QItemSection>{{ t('To book') }}</QItemSection>
                    </QItem>
                </template>
            </InvoiceInToBook>
            <QItem
                v-if="entity?.isBooked && canEditProp('toUnbook')"
                v-ripple
                clickable
                @click="triggerMenu('unbook')"
            >
                <QItemSection>
                    {{ t('To unbook') }}
                </QItemSection>
            </QItem>
            <QItem
                v-if="canEditProp('deleteById')"
                v-ripple
                clickable
                @click="triggerMenu('delete')"
            >
                <QItemSection>{{ t('Delete invoice') }}</QItemSection>
            </QItem>
            <QItem
                v-if="canEditProp('clone')"
                v-ripple
                clickable
                @click="triggerMenu('clone')"
            >
                <QItemSection>{{ t('Clone invoice') }}</QItemSection>
            </QItem>
            <QItem
                v-if="isAgricultural()"
                v-ripple
                clickable
                @click="triggerMenu('showPdf')"
            >
                <QItemSection>{{ t('Show agricultural receipt as PDF') }}</QItemSection>
            </QItem>
            <QItem
                v-if="isAgricultural()"
                v-ripple
                clickable
                @click="triggerMenu('sendPdf')"
            >
                <QItemSection
                    >{{ t('Send agricultural receipt as PDF') }}...</QItemSection
                >
            </QItem>
            <QItem
                v-if="!invoiceInCorrection.corrected"
                v-ripple
                clickable
                @click="triggerMenu('correct')"
            >
                <QItemSection>{{ t('Create rectificative invoice') }}...</QItemSection>
            </QItem>
            <QItem
                v-if="entity.dmsFk"
                v-ripple
                clickable
                @click="downloadFile(entity.dmsFk)"
            >
                <QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
            </QItem>
        </template>
        <template #body="{ entity }">
            <VnLv :label="t('invoiceIn.card.issued')" :value="toDate(entity.issued)" />
            <VnLv :label="t('invoiceIn.summary.booked')" :value="toDate(entity.booked)" />
            <VnLv :label="t('invoiceIn.card.amount')" :value="toCurrency(totalAmount)" />
            <VnLv :label="t('invoiceIn.summary.supplier')">
                <template #value>
                    <span class="link">
                        {{ entity?.supplier?.nickname }}
                        <SupplierDescriptorProxy :id="entity?.supplierFk" />
                    </span>
                </template>
            </VnLv>
        </template>
        <template #actions="{ entity }">
            <QCardActions>
                <QBtn
                    size="md"
                    icon="vn:supplier"
                    color="primary"
                    :to="routes.getSupplier(entity.supplierFk)"
                >
                    <QTooltip>{{ t('invoiceIn.list.supplier') }}</QTooltip>
                </QBtn>
                <QBtn
                    size="md"
                    icon="vn:entry"
                    color="primary"
                    :to="routes.getEntry(entity.entryFk)"
                >
                    <QTooltip>{{ t('Entry') }}</QTooltip>
                </QBtn>
                <QBtn
                    size="md"
                    icon="vn:ticket"
                    color="primary"
                    :to="routes.getTickets(entity.supplierFk)"
                >
                    <QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
                </QBtn>
                <QBtn
                    v-if="
                        invoiceInCorrection.corrected ||
                        invoiceInCorrection.correcting.length
                    "
                    size="md"
                    :icon="
                        invoiceInCorrection.corrected
                            ? 'vn:link-to-corrected'
                            : 'vn:link-to-correcting'
                    "
                    color="primary"
                    :to="routes.getCorrection(invoiceInCorrection)"
                >
                    <QTooltip>{{
                        invoiceInCorrection.corrected
                            ? t('Original invoice')
                            : t('Rectificative invoice')
                    }}</QTooltip>
                </QBtn>
            </QCardActions>
        </template>
    </CardDescriptor>
    <QDialog ref="correctionDialogRef">
        <QCard>
            <QCardSection>
                <QItem class="q-px-none">
                    <span class="text-primary text-h6 full-width">
                        {{ t('Create rectificative invoice') }}
                    </span>
                    <QBtn icon="close" flat round dense v-close-popup />
                </QItem>
            </QCardSection>
            <QCardSection>
                <QItem>
                    <QItemSection>
                        <QInput
                            :label="t('Original invoice')"
                            v-model="entityId"
                            readonly
                        />
                        <VnSelect
                            :label="`${useCapitalize(t('globals.class'))}`"
                            v-model="correctionFormData.invoiceClass"
                            :options="siiTypeInvoiceOuts"
                            option-value="id"
                            option-label="code"
                            :required="true"
                        />
                    </QItemSection>
                    <QItemSection>
                        <VnSelect
                            :label="`${useCapitalize(t('globals.type'))}`"
                            v-model="correctionFormData.invoiceType"
                            :options="cplusRectificationTypes"
                            option-value="id"
                            option-label="description"
                            :required="true"
                        />
                        <VnSelect
                            :label="`${useCapitalize(t('globals.reason'))}`"
                            v-model="correctionFormData.invoiceReason"
                            :options="invoiceCorrectionTypes"
                            option-value="id"
                            option-label="description"
                            :required="true"
                        />
                    </QItemSection>
                </QItem>
            </QCardSection>
            <QCardActions class="justify-end q-mr-sm">
                <QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
                <QBtn
                    :label="t('globals.save')"
                    color="primary"
                    v-close-popup
                    @click="createInvoiceInCorrection"
                    :disable="isNotFilled"
                />
            </QCardActions>
        </QCard>
    </QDialog>
</template>
<style lang="scss" scoped>
.q-dialog {
    .q-card {
        max-width: 45em;
    }
    .q-field:nth-child(1) {
        padding-bottom: 20px;
    }
}

@media (max-width: $breakpoint-xs) {
    .q-dialog {
        .q-card__section:nth-child(2) {
            .q-item,
            .q-item__section {
                flex-direction: column;
            }
        }
    }
}
</style>
<i18n>
en:
    isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries
    isLinked: The entry {bookEntry} has been linked to Sage. Please contact administration for further information
    assertAction: Are you sure you want to {action} this invoice?
es:
    book: asentar
    unbook: desasentar
    delete: eliminar
    clone: clonar
    To book: Contabilizar
    To unbook: Descontabilizar
    Delete invoice: Eliminar factura
    Invoice deleted: Factura eliminada
    Clone invoice: Clonar factura
    Invoice cloned: Factura clonada
    Show agricultural receipt as PDF: Ver recibo agrícola como PDF
    Send agricultural receipt as PDF: Enviar recibo agrícola como PDF
    Are you sure you want to send it?: Estás seguro que quieres enviarlo?
    Send PDF invoice: Enviar factura a PDF
    Create rectificative invoice: Crear factura rectificativa
    Rectificative invoice: Factura rectificativa
    Original invoice: Factura origen
    Entry: entrada
    isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes
    isLinked: El asiento {bookEntry} fue enlazado a Sage, por favor contacta con administración
    assertAction: Estas seguro de querer {action} esta factura?
</i18n>
