<script setup>
import { ref, reactive, computed, onBeforeMount, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import { toCurrency, toDate } from 'src/filters';
import { useRole } from 'src/composables/useRole';
import useCardDescription from 'src/composables/useCardDescription';
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 VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import { useCapitalize } from 'src/composables/useCapitalize';

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

const route = useRoute();
const router = useRouter();
const quasar = useQuasar();
const { hasAny } = useRole();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
const arrayData = useArrayData('InvoiceIn');

const invoiceIn = computed(() => arrayData.store.data);
const cardDescriptorRef = ref();
const correctionDialogRef = ref();
const entityId = computed(() => $props.id || +route.params.id);
const totalAmount = ref();
const currentAction = ref();
const config = ref();
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceOuts = ref([]);
const invoiceCorrectionTypes = ref([]);
const actions = {
    book: {
        title: 'Are you sure you want to book this invoice?',
        cb: checkToBook,
        action: toBook,
    },
    delete: {
        title: 'Are you sure you want to delete this invoice?',
        action: deleteInvoice,
    },
    clone: {
        title: 'Are you sure you want to clone this invoice?',
        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 data = ref(useCardDescription());
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));

watch(
    () => route.params.id,
    async (newId) => {
        invoiceInCorrection.correcting.length = 0;
        invoiceInCorrection.corrected = null;
        if (newId) await setInvoiceCorrection(entityId.value);
    }
);

async function setInvoiceCorrection(id) {
    const [{ data: correctingData }, { data: correctedData }] = await Promise.all([
        axios.get('InvoiceInCorrections', {
            params: {
                filter: {
                    where: {
                        correctingFk: id,
                    },
                },
            },
        }),
        axios.get('InvoiceInCorrections', {
            params: {
                filter: {
                    where: {
                        correctedFk: id,
                    },
                },
            },
        }),
    ]);

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

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

async function setData(entity) {
    data.value = useCardDescription(entity.supplierRef, entity.id);
    const { totalDueDay } = await getTotals();
    totalAmount.value = totalDueDay;
}

async function getTotals() {
    const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
    return data;
}

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

async function checkToBook() {
    let directBooking = true;

    const totals = await getTotals();
    const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase;
    const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat;

    if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) directBooking = false;

    const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', {
        where: {
            invoiceInFk: entityId.value,
            dueDated: { gte: Date.vnNew() },
        },
    });

    if (dueDaysCount) directBooking = false;

    if (!directBooking) openDialog();
    else toBook();
}

async function toBook() {
    await axios.post(`InvoiceIns/${entityId.value}/toBook`);

    quasar.notify({
        type: 'positive',
        message: t('globals.dataSaved'),
    });

    await cardDescriptorRef.value.getData();
    setTimeout(() => location.reload(), 500);
}

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

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

const requiredFieldRule = (val) => val || t('globals.requiredField');

const isAdministrative = () => hasAny(['administrative']);

const isAgricultural = () =>
    invoiceIn.value.supplier.sageWithholdingFk == 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 })
    );
    router.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"
        :url="`InvoiceIns/${entityId}`"
        :filter="filter"
        :title="data.title"
        :subtitle="data.subtitle"
        @on-fetch="setData"
        data-key="invoiceInData"
    >
        <template #menu="{ entity }">
            <QItem
                v-if="!entity.isBooked && isAdministrative()"
                v-ripple
                clickable
                @click="triggerMenu('book')"
            >
                <QItemSection>{{ t('To book') }}</QItemSection>
            </QItem>
            <QItem
                v-if="isAdministrative()"
                v-ripple
                clickable
                @click="triggerMenu('delete')"
            >
                <QItemSection>{{ t('Delete invoice') }}</QItemSection>
            </QItem>
            <QItem
                v-if="isAdministrative()"
                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>
            <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')"
                :value="entity.supplier?.nickname"
            />
        </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
                        />
                        <VnSelectFilter
                            :label="`${useCapitalize(t('globals.class'))}*`"
                            v-model="correctionFormData.invoiceClass"
                            :options="siiTypeInvoiceOuts"
                            option-value="id"
                            option-label="code"
                            :rules="[requiredFieldRule]"
                        />
                    </QItemSection>
                    <QItemSection>
                        <VnSelectFilter
                            :label="`${useCapitalize(t('globals.type'))}*`"
                            v-model="correctionFormData.invoiceType"
                            :options="cplusRectificationTypes"
                            option-value="id"
                            option-label="description"
                            :rules="[requiredFieldRule]"
                        />
                        <VnSelectFilter
                            :label="`${useCapitalize(t('globals.reason'))}*`"
                            v-model="correctionFormData.invoiceReason"
                            :options="invoiceCorrectionTypes"
                            option-value="id"
                            option-label="description"
                            :rules="[requiredFieldRule]"
                        />
                    </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-item__section > .q-input {
            padding-bottom: 1.4em;
        }
    }
}

@media (max-width: $breakpoint-xs) {
    .q-dialog {
        .q-card__section:nth-child(2) {
            .q-item,
            .q-item__section {
                flex-direction: column;
            }
        }
    }
}
</style>
<i18n>
es:
    To book: Contabilizar
    Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
    Delete invoice: Eliminar factura
    Are you sure you want to delete this invoice?:  Estas seguro de querer eliminar esta 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
</i18n>
