<script setup>
import axios from 'axios';
import { computed, ref, onBeforeMount } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useStateStore } from 'stores/useStateStore';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
import useNotify from 'src/composables/useNotify';
import TicketSummary from './Card/TicketSummary.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnRow from 'src/components/ui/VnRow.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import TicketFilter from './TicketFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FetchData from 'src/components/FetchData.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import { toTimeFormat } from 'src/filters/date';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
import TicketProblems from 'src/components/TicketProblems.vue';

const route = useRoute();
const router = useRouter();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
const tableRef = ref();
const quasar = useQuasar();
const { notify } = useNotify();
const clientsOptions = ref([]);
const addressesOptions = ref([]);
const agenciesOptions = ref([]);
const selectedClient = ref();
const stateStore = useStateStore();
const from = Date.vnNew();
from.setHours(0, 0, 0, 0);
from.setDate(from.getDate() - 7);
const to = Date.vnNew();
to.setHours(23, 59, 0, 0);
to.setDate(to.getDate() + 1);
const userParams = {
    from: null,
    to: null,
};
onBeforeMount(() => {
    initializeFromQuery();
    stateStore.rightDrawer = true;
    if (!route.query.createForm) return;
    onClientSelected(JSON.parse(route.query.createForm));
});
const initializeFromQuery = () => {
    const query = route.query.table ? JSON.parse(route.query.table) : {};
    from.value = query.from || from.toISOString();
    to.value = query.to || to.toISOString();
    Object.assign(userParams, { from, to });
};

const selectedRows = ref([]);
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
const showForm = ref(false);
const dialogData = ref();
const companiesOptions = ref([]);
const accountingOptions = ref([]);
const amountToReturn = ref();

const columns = computed(() => [
    {
        align: 'left',
        name: 'statusIcons',
        hidden: true,
        format: () => '',
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'id',
        label: t('ticketList.id'),
        chip: {
            condition: () => true,
        },
        isId: true,
    },
    {
        align: 'left',
        label: t('ticketList.salesPerson'),
        name: 'salesPersonFk',
        component: 'select',
        attrs: {
            url: 'Workers/activeWithInheritedRole',
            fields: ['id', 'name'],
            where: { role: 'salesPerson' },
            optionFilter: 'firstName',
            useLike: false,
        },
        columnField: {
            component: null,
        },
        columnClass: 'expand',
        format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
    },
    {
        align: 'left',
        name: 'shippedDate',
        cardVisible: true,
        label: t('ticketList.shipped'),
        columnFilter: {
            component: 'date',
            alias: 't',
            inWhere: true,
        },
        format: ({ shippedDate }) => toDate(shippedDate),
    },
    {
        align: 'left',
        name: 'shipped',
        label: t('ticketList.hour'),
        format: (row) => toTimeFormat(row.shipped),
    },
    {
        align: 'left',
        name: 'zoneLanding',
        label: t('ticketList.closure'),
        format: (row, dashIfEmpty) => dashIfEmpty(toTimeFormat(row.zoneLanding)),
    },
    {
        align: 'left',
        name: 'nickname',
        label: t('ticketList.nickname'),
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'addressNickname',
        label: t('ticketList.addressNickname'),
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'province',
        label: t('ticketList.province'),
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'stateFk',
        label: t('ticketList.state'),
        columnFilter: {
            name: 'stateFk',
            component: 'select',
            attrs: {
                url: 'States',
                fields: ['id', 'name'],
            },
        },
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'zoneFk',
        label: t('ticketList.zone'),
        columnFilter: {
            component: 'select',
            attrs: {
                url: 'Zones',
                fields: ['id', 'name'],
            },
            alias: 't',
            inWhere: true,
        },
        columnClass: 'expand',
        format: (row, dashIfEmpty) => dashIfEmpty(row.zoneName),
    },
    {
        align: 'left',
        name: 'warehouse',
        label: t('ticketList.warehouse'),
        columnClass: 'expand',
    },
    {
        align: 'left',
        name: 'totalWithVat',
        label: t('ticketList.totalWithVat'),
        cardVisible: true,
        columnFilter: {
            component: 'number',
            inWhere: true,
        },
        format: (row) => toCurrency(row.totalWithVat),
    },
    {
        align: 'left',
        name: 'packing',
        label: t('ticketSale.packaging'),
        format: (row, dashIfEmpty) => dashIfEmpty(row.packing),
    },
    {
        align: 'right',
        name: 'tableActions',
        actions: [
            {
                title: t('ticketList.toLines'),
                icon: 'list',
                isPrimary: true,
                action: (row) => redirectToLines(row.id),
            },
            {
                title: t('components.smartCard.viewSummary'),
                icon: 'preview',
                action: (row, evt) => {
                    if (evt && evt.ctrlKey) {
                        const url = router.resolve({
                            params: { id: row.id },
                            name: 'TicketCard',
                        }).href;
                        window.open(url, '_blank');
                    } else viewSummary(row.id, TicketSummary);
                },
            },
        ],
    },
]);
function redirectToLines(id) {
    const url = `#/ticket/${id}/sale`;
    window.open(url, '_blank');
}

const onClientSelected = async (formData) => {
    await fetchClient(formData);
    await fetchAddresses(formData);
};

const fetchAvailableAgencies = async (formData) => {
    if (!formData.warehouseId || !formData.addressId || !formData.landed) return;
    let params = {
        warehouseFk: formData.warehouseId,
        addressFk: formData.addressId,
        landed: formData.landed,
    };

    const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params });

    agenciesOptions.value = data;

    const defaultAgency = agenciesOptions.value.find(
        (agency) =>
            agency.agencyModeFk === selectedClient.value.defaultAddress.agencyModeFk
    );

    if (defaultAgency) formData.agencyModeId = defaultAgency.agencyModeFk;
};

const fetchClient = async (formData) => {
    const filter = {
        include: {
            relation: 'defaultAddress',
            scope: {
                fields: ['id', 'agencyModeFk'],
            },
        },
        where: { id: formData.clientId },
    };
    const params = { filter: JSON.stringify(filter) };
    const { data } = await axios.get('Clients', { params });
    const [client] = data;
    selectedClient.value = client;
};

const fetchAddresses = async (formData) => {
    if (!formData.clientId) return;

    const filter = {
        fields: ['nickname', 'street', 'city', 'id', 'isActive'],
        order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'],
    };
    const params = { filter: JSON.stringify(filter) };
    const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, {
        params,
    });
    addressesOptions.value = data;

    addressesOptions.value = data;

    const { defaultAddress } = selectedClient.value;
    formData.addressId = defaultAddress.id;
};

const getColor = (row) => {
    if (row.alertLevelCode === 'OK') return 'bg-success';
    else if (row.alertLevelCode === 'FREE') return 'bg-notice';
    else if (row.alertLevel === 1) return 'bg-warning';
    else if (row.alertLevel === 0) return 'bg-alert';
};

const getDateColor = (date) => {
    const today = Date.vnNew();
    today.setHours(0, 0, 0, 0);
    const timeTicket = new Date(date);
    timeTicket.setHours(0, 0, 0, 0);
    const comparation = today - timeTicket;
    if (comparation == 0) return 'bg-warning';
    if (comparation < 0) return 'bg-success';
};

async function makeInvoice(ticket) {
    const ticketsIds = ticket.map((item) => item.id);
    const { data } = await axios.post(`Tickets/invoiceTicketsAndPdf`, { ticketsIds });
    const response = data;
    if (response)
        quasar.notify({
            message: t('globals.dataSaved'),
            type: 'positive',
        });
}

async function sendDocuware(ticket) {
    try {
        let ticketIds = ticket.map((item) => item.id);

        const { data } = await axios.post(`Docuwares/upload`, {
            fileCabinet: 'deliveryNote',
            ticketIds,
        });

        for (let ticket of ticketIds) {
            ticket.stateFk = data.id;
            ticket.state = data.name;
            ticket.alertLevel = data.alertLevel;
            ticket.alertLevelCode = data.code;
        }
        notify('globals.dataSaved', 'positive');
    } catch (err) {
        console.err('err: ', err);
    }
}

function openBalanceDialog(ticket) {
    const checkedTickets = ticket;
    const amountPaid = ref(0);
    const clientFk = ref(null);
    const description = ref([]);
    const firstTicketClientId = checkedTickets[0].clientFk;
    const isSameClient = checkedTickets.every(
        (ticket) => ticket.clientFk === firstTicketClientId
    );

    if (!isSameClient) {
        throw new Error('You cannot make a payment on account from multiple clients');
    }

    for (let ticketData of checkedTickets) {
        amountPaid.value += ticketData.totalWithVat;
        clientFk.value = ticketData.clientFk;
        description.value.push(ticketData.id);
    }

    const balanceCreateDialog = ref({
        amountPaid: amountPaid.value,
        clientFk: clientFk.value,
        description: `Albaran: ${description.value.join(', ')}`,
    });
    dialogData.value = balanceCreateDialog;
    showForm.value = true;
}

async function onSubmit() {
    const { data: email } = await axios.get('Clients', {
        params: {
            filter: JSON.stringify({ where: { id: dialogData.value.value.clientFk } }),
        },
    });

    const { data } = await axios.post(
        `Clients/${dialogData.value.value.clientFk}/createReceipt`,
        {
            payed: dialogData.value.payed,
            companyFk: dialogData.value.companyFk,
            bankFk: dialogData.value.bankFk,
            amountPaid: dialogData.value.value.amountPaid,
            description: dialogData.value.value.description,
            clientFk: dialogData.value.value.clientFk,
            email: email[0].email,
        }
    );

    if (data) notify('globals.dataSaved', 'positive');
    showForm.value = false;
}

const setAmountToReturn = (newAmountGiven) => {
    const amountPaid = dialogData.value.value.amountPaid;

    amountToReturn.value = newAmountGiven - amountPaid;
};

function setReference(data) {
    let newDescription = '';

    switch (data) {
        case 1:
            newDescription = `${t(
                'ticketList.creditCard'
            )}, ${dialogData.value.value.description.replace(
                /^(Credit Card, |Cash, |Transfers, )/,
                ''
            )}`;
            break;
        case 2:
            newDescription = `${t(
                'ticketList.cash'
            )}, ${dialogData.value.value.description.replace(
                /^(Credit Card, |Cash, |Transfers, )/,
                ''
            )}`;
            break;
        case 3:
            newDescription = `${newDescription.replace(
                /^(Credit Card, |Cash, |Transfers, )/,
                ''
            )}`;
            break;
        case 4:
            newDescription = `${t(
                'ticketList.transfers'
            )}, ${dialogData.value.value.description.replace(
                /^(Credit Card, |Cash, |Transfers, )/,
                ''
            )}`;
            break;
        case 3317:
            newDescription = '';
            break;
        default:
            break;
    }

    dialogData.value.value.description = newDescription;
}
</script>

<template>
    <FetchData
        url="Companies"
        @on-fetch="(data) => (companiesOptions = data)"
        auto-load
    />
    <FetchData
        url="Accountings"
        @on-fetch="(data) => (accountingOptions = data)"
        auto-load
    />
    <VnSearchbar
        data-key="TicketList"
        :label="t('Search ticket')"
        :info="t('You can search by ticket id or alias')"
        data-cy="ticketListSearchBar"
    />
    <RightMenu>
        <template #right-panel>
            <TicketFilter data-key="TicketList" />
        </template>
    </RightMenu>
    <VnTable
        ref="tableRef"
        data-key="TicketList"
        url="Tickets/filter"
        :create="{
            urlCreate: 'Tickets/new',
            title: t('ticketList.createTicket'),
            onDataSaved: ({ id }) => tableRef.redirect(id),
            formInitialData: { clientId: null },
        }"
        default-mode="table"
        :order="['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id']"
        :columns="columns"
        :user-params="userParams"
        :right-search="false"
        redirect="ticket"
        v-model:selected="selectedRows"
        :table="{
            'row-key': 'id',
            selection: 'multiple',
        }"
        data-cy="ticketListTable"
    >
        <template #column-statusIcons="{ row }">
            <TicketProblems :row="row" />
        </template>
        <template #column-salesPersonFk="{ row }">
            <span class="link" @click.stop>
                {{ dashIfEmpty(row.userName) }}
                <CustomerDescriptorProxy :id="row.salesPersonFk" />
            </span>
        </template>
        <template #column-shippedDate="{ row }">
            <span v-if="getDateColor(row.shipped)">
                <QChip :class="getDateColor(row.shipped)" dense square>
                    {{ toDate(row.shippedDate) }}
                </QChip>
            </span>
        </template>
        <template #column-nickname="{ row }">
            <span class="link" @click.stop>
                {{ row.nickname }}
                <CustomerDescriptorProxy :id="row.clientFk" />
            </span>
        </template>
        <template #column-addressNickname="{ row }">
            <span class="link" @click.stop>
                {{ row.addressNickname }}
                <CustomerDescriptorProxy :id="row.clientFk" />
            </span>
        </template>
        <template #column-stateFk="{ row }">
            <span v-if="row.refFk">
                <span class="link" @click.stop>
                    {{ row.refFk }}
                    <InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
                </span>
            </span>
            <span v-else-if="getColor(row)">
                <QChip :class="getColor(row)" dense square>
                    {{ row.state }}
                </QChip>
            </span>
            <span v-else>
                {{ row.state }}
            </span>
        </template>
        <template #column-zoneFk="{ row }">
            <span class="link" @click.stop>
                {{ dashIfEmpty(row.zoneName) }}
                <ZoneDescriptorProxy :id="row.zoneFk" />
            </span>
        </template>
        <template #column-totalWithVat="{ row }">
            <QChip
                v-if="row.totalWithVat > 0 && row.totalWithVat < 50"
                class="bg-warning"
                dense
                square
            >
                {{ row.totalWithVat }}
            </QChip>
        </template>
        <template #more-create-dialog="{ data }">
            <VnRow>
                <VnSelect
                    url="Clients"
                    :fields="['id', 'name']"
                    :label="t('ticketList.client')"
                    v-model="data.clientId"
                    :options="clientsOptions"
                    option-value="id"
                    option-label="name"
                    hide-selected
                    required
                    @update:model-value="(client) => onClientSelected(data)"
                    :sort-by="'id ASC'"
                >
                    <template #option="scope">
                        <QItem v-bind="scope.itemProps">
                            <QItemSection>
                                <QItemLabel>
                                    {{ scope.opt.name }}
                                </QItemLabel>
                                <QItemLabel caption>
                                    {{ `#${scope.opt.id}` }}
                                </QItemLabel>
                            </QItemSection>
                        </QItem>
                    </template>
                </VnSelect>
            </VnRow>
            <VnRow>
                <VnSelect
                    :label="t('basicData.address')"
                    v-model="data.addressId"
                    :options="addressesOptions"
                    option-value="id"
                    option-label="nickname"
                    hide-selected
                    map-options
                    required
                    :disable="!data.clientId"
                    :sort-by="'isActive DESC'"
                    @update:model-value="() => fetchAvailableAgencies(data)"
                >
                    <template #option="scope">
                        <QItem
                            v-bind="scope.itemProps"
                            :class="{ disabled: !scope.opt.isActive }"
                        >
                            <QItemSection style="min-width: min-content" avatar>
                                <QIcon
                                    v-if="
                                        scope.opt.isActive &&
                                        selectedClient?.defaultAddressFk === scope.opt.id
                                    "
                                    size="sm"
                                    color="grey"
                                    name="star"
                                    class="fill-icon"
                                />
                            </QItemSection>
                            <QItemSection>
                                <QItemLabel
                                    :class="{
                                        'color-vn-label': !scope.opt?.isActive,
                                    }"
                                >
                                    {{
                                        `${
                                            !scope.opt?.isActive
                                                ? t('basicData.inactive')
                                                : ''
                                        } `
                                    }}
                                    <span>
                                        {{ scope.opt?.nickname }}:
                                        {{ scope.opt?.street }}, {{ scope.opt?.city }}
                                    </span>
                                </QItemLabel>
                            </QItemSection>
                        </QItem>
                    </template>
                </VnSelect>
            </VnRow>
            <VnRow>
                <div class="col">
                    <VnInputDate
                        placeholder="dd-mm-aaa"
                        :label="t('globals.landed')"
                        v-model="data.landed"
                        @update:model-value="() => fetchAvailableAgencies(data)"
                    />
                </div>
            </VnRow>
            <VnRow>
                <div class="col">
                    <VnSelect
                        url="Warehouses"
                        :sort-by="['name']"
                        :label="t('globals.warehouse')"
                        v-model="data.warehouseId"
                        :options="warehousesOptions"
                        option-value="id"
                        option-label="name"
                        hide-selected
                        required
                        @update:model-value="() => fetchAvailableAgencies(data)"
                    />
                </div>
            </VnRow>
            <VnRow>
                <div class="col">
                    <VnSelect
                        :label="t('globals.agency')"
                        v-model="data.agencyModeId"
                        :options="agenciesOptions"
                        option-value="agencyModeFk"
                        option-label="agencyMode"
                        hide-selected
                    />
                </div>
            </VnRow>
        </template>
    </VnTable>
    <QPageSticky :offset="[20, 80]" style="z-index: 2">
        <QBtn
            v-if="hasSelectedRows"
            @click="makeInvoice(selectedRows)"
            color="primary"
            fab
            icon="vn:invoice-in"
        />
        <QTooltip>
            {{ t('ticketList.createInvoice') }}
        </QTooltip>
    </QPageSticky>
    <QPageSticky v-if="hasSelectedRows" :offset="[20, 140]" style="z-index: 2">
        <QBtn
            @click.stop="openBalanceDialog(selectedRows)"
            color="primary"
            fab
            icon="vn:recovery"
        />
        <QTooltip>
            {{ t('ticketList.accountPayment') }}
        </QTooltip>
    </QPageSticky>
    <QDialog ref="dialogRef" v-model="showForm">
        <QCard class="q-pa-md q-mb-md">
            <QForm @submit="onSubmit()" class="q-pa-sm">
                {{ t('ticketList.addPayment') }}
                <VnRow>
                    <VnInputDate
                        :label="t('ticketList.date')"
                        v-model="dialogData.payed"
                    />
                    <VnSelect
                        :label="t('ticketList.company')"
                        v-model="dialogData.companyFk"
                        :options="companiesOptions"
                        option-value="id"
                        option-label="code"
                        hide-selected
                    >
                    </VnSelect>
                </VnRow>
                <VnRow>
                    <VnSelect
                        :label="t('ticketList.bank')"
                        v-model="dialogData.bankFk"
                        :options="accountingOptions"
                        option-value="id"
                        option-label="bank"
                        hide-selected
                        @update:model-value="setReference"
                    />
                    <VnInput
                        :label="t('ticketList.amount')"
                        v-model="dialogData.value.amountPaid"
                    />
                </VnRow>
                <VnRow v-if="dialogData.bankFk === 2">
                    <span>
                        {{ t('ticketList.cash') }}
                    </span>
                </VnRow>
                <VnRow v-if="dialogData.bankFk === 2">
                    <VnInput
                        :label="t('ticketList.deliveredAmount')"
                        v-model="dialogData.value.amountGiven"
                        @update:model-value="setAmountToReturn"
                        type="number"
                    />
                    <VnInput
                        :label="t('ticketList.amountToReturn')"
                        :model-value="amountToReturn"
                        type="number"
                        readonly
                    />
                </VnRow>
                <VnRow v-if="dialogData.bankFk === 3 || dialogData.bankFk === 3117">
                    <VnInput
                        :label="t('ticketList.compensation')"
                        v-model="dialogData.value.compensation"
                        type="text"
                    />
                </VnRow>
                <VnRow>
                    <VnInput
                        :label="t('ticketList.reference')"
                        v-model="dialogData.value.description"
                        type="text"
                    />
                </VnRow>
                <VnRow v-if="dialogData.bankFk === 2">
                    <QCheckbox
                        :label="t('ticketList.viewReceipt')"
                        v-model="dialogData.value.viewReceipt"
                        :toggle-indeterminate="false"
                    />
                    <QCheckbox
                        :label="t('ticketList.sendEmail')"
                        v-model="dialogData.value.senEmail"
                        :toggle-indeterminate="false"
                    />
                </VnRow>
                <div class="q-mt-lg row justify-end">
                    <QBtn
                        :label="t('globals.save')"
                        color="primary"
                        @click="onSubmit()"
                    />
                    <QBtn
                        flat
                        :label="t('globals.close')"
                        color="primary"
                        v-close-popup
                    />
                </div>
            </QForm>
        </QCard>
    </QDialog>
    <QPageSticky v-if="hasSelectedRows" :offset="[20, 200]" style="z-index: 2">
        <QBtn
            @click="sendDocuware(selectedRows)"
            color="primary"
            fab
            icon="install_mobile"
        />
        <QTooltip>
            {{ t('ticketList.sendDocuware') }}
        </QTooltip>
    </QPageSticky>
</template>
<style scoped>
.disabled,
.disabled *,
[disabled],
[disabled] * {
    cursor: pointer !important;
}
</style>
<i18n>
es:
    Search ticket: Buscar ticket
    You can search by ticket id or alias: Puedes buscar por id o alias del ticket
    Zone: Zona
    New ticket: Nuevo ticket
    Component lack: Faltan componentes
</i18n>