<template>
    <div class="row">
        <div class="col">
            <div class="row">
                <div class="col-12 col-md">
                    <choose-currency-component v-model:currency_id="filters.currency_id"></choose-currency-component>
                </div>
                <div class="col-12 col-md">
                    <choose-service-component v-model:service_id="filters.service_id" @loaded="isLoading = !isLoading"></choose-service-component>
                </div>
                <div class="col-12 col-md">
                    <validation-wrapper-component :validator="v$.date_from">
                        <label class="all-caps">Date From</label>
                        <date-picker-component v-model.lazy="filters.date_from"></date-picker-component>
                    </validation-wrapper-component>
                </div>
                <div class="col-12  col-md">
                    <validation-wrapper-component :validator="v$.date_to">
                        <label class="all-caps">Date To</label>
                        <date-picker-component v-model.lazy="filters.date_to"></date-picker-component>
                    </validation-wrapper-component>
                </div>
            </div>
            <div class="row m-t-15">
                <div class="col">
                    <button type="button" class="btn btn-lg btn-primary fs-11 " @click="fetchRateLogs" :class="[{'disabled': isLoading}]" :disabled="isLoading">Search</button>
                    <!-- <button type="button" class="btn btn-lg btn-secondary fs-11" @click="resetSearch">Reset</button> -->
                </div>
            </div>
            <loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
            <div class="row" v-if="!isLoading && !hasError">
                <div class="col-12 mx-auto p-0 ">
                    <canvas style="width: 800px; height:350px" id="currency-history-chart"></canvas>
                </div>
            </div>
            <div class="row" v-if="hasError">
                <div class="col">
                    <div class="row align-items-center justify-content-center  hint-text">
                        <div class="col-4 hint-text"><img :src="asset('images/not-found-illustration.png')" class="w-100 hint-text"/></div>
                    </div>
                    <div class="row text-center">
                        <div class="col">
                            <div class="row m-t-20">
                                <div class="col">
                                    <p class="all-caps no-margin fs-11" style="letter-spacing: 2px;">Nothing To Show Here</p>
                                </div>
                            </div>
                            <div class="row m-t-5 align-items-center justify-content-center">
                                <div class="col">
                                    <small class="fs-9 muted all-caps font-lato" style="letter-spacing: 2px">There is no results found, Try adjusting your filters to find what you are looking for.</small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import Chart from 'chart.js';
import { useRequest } from '@/composables/useRequest';
import { useQueueStore } from '@/stores/queue';
import route from '@/general/functions/router';
import useVuelidate from '@vuelidate/core';

const asset = (path: string) => (window as any).Vapor.asset(path);

interface Filters {
    currency_id: number | null;
    service_id: number | null;
    date_to: string | null;
    date_from: string | null;
}

const props = defineProps<{
    paymentMethods: Record<string, any>;
}>();

const { submit } = useRequest();
const queueStore = useQueueStore();

const rateHistory = ref<any[] | null>(null);
const isLoading = ref(true);
const hasError = ref(false);
const section = 'rateHistorySection';

const filters = ref<Filters>({
    currency_id: null,
    service_id: null,
    date_to: null,
    date_from: null,
});

const chartLebels = ref<string[]>([]);
const chartData = ref<any[]>([]);
const paymentMethodsConst = ref<Record<string, string>>({});
const colors = ref([
    'red',
    'pink',
    'blue',
    'purple',
    'black',
    'yellow'
]);

const pendingQueue = computed(() => queueStore.isInCompleteQueue(section));

const v$ = useVuelidate({}, filters);

onMounted(() => {
    paymentMethodsConst.value = Object.entries(props.paymentMethods).reduce((acc, [key, value]) => {
        acc[value as string] = key;
        return acc;
    }, {} as Record<string, string>);
});

const formatDate = (date: Date) => {
    let d = new Date(date);
    let ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(d);
    let mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(d);
    let da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(d);
    return (`${da}-${mo}-${ye}`);
};

const resetSearch = () => {
    var currentDate = new Date();
    filters.value.date_to = formatDate(new Date(currentDate.setDate(currentDate.getDate() + 3)));
    filters.value.date_from = formatDate(new Date(currentDate.setDate(currentDate.getDate() - 6)));
};

const fetchRateLogs = () => {
    isLoading.value = true;
    submit(route('api.currency.history.list') + '?filters=' + JSON.stringify(filters.value), 'get', section, false, false, undefined, {
        successHandler: (response: any) => {
            isLoading.value = false;
            rateHistory.value = response.payload.data;
        },
        errorHandler: (error: any) => {
            isLoading.value = false;
            hasError.value = true;
        }
    });
};

let chartInstance: any = null;

watch(rateHistory, (newVal) => {
    if (!newVal) return;

    const date_from_parts = filters.value.date_from!.split("-");
    const date_from_year = parseInt(date_from_parts[2]);
    const date_from_month = parseInt(date_from_parts[1]) - 1;
    const date_from_day = parseInt(date_from_parts[0]);
    const start = new Date(date_from_year, date_from_month, date_from_day);

    const date_to_parts = filters.value.date_to!.split("-");
    const date_to_year = parseInt(date_to_parts[2]);
    const date_to_month = parseInt(date_to_parts[1]) - 1;
    const date_to_day = parseInt(date_to_parts[0]);
    const end = new Date(date_to_year, date_to_month, date_to_day);

    const ratesByType: Record<string, any[]> = {};
    newVal.forEach(rate => {
        if (!ratesByType[rate.payment_method_type]) {
            ratesByType[rate.payment_method_type] = [];
        }
        ratesByType[rate.payment_method_type].push(rate);
    });

    const startYear = start.getFullYear();
    const startMonth = start.getMonth() + 1;
    const endYear = end.getFullYear();
    const endMonth = end.getMonth() + 1;

    const ratesForRange: Record<string, any[]> = {};
    Object.keys(ratesByType).forEach(type => {
        ratesForRange[type] = [];
        for (let i = start.getDate(); i <= end.getDate(); i++) {
            const dateStr = `${i.toString().padStart(2, '0')}-${startMonth.toString().padStart(2, '0')}-${startYear}`;
            if (i === end.getDate() && startMonth !== endMonth) {
                const endMonthDays = new Date(endYear, endMonth, 0).getDate();
                for (let j = 1; j <= end.getDate(); j++) {
                    const dateStrEnd = `${j.toString().padStart(2, '0')}-${endMonth.toString().padStart(2, '0')}-${endYear}`;
                    const rate = ratesByType[type].find(r => r.created_at === dateStrEnd);
                    ratesForRange[type].push(rate ? rate.rate : '');
                }
            } else {
                const rate = ratesByType[type].find(r => r.created_at === dateStr);
                ratesForRange[type].push(rate ? rate.rate : '');
            }
        }
    });

    const labels: string[] = [];
    for (let i = start.getDate(); i <= end.getDate(); i++) {
        if (i === end.getDate() && startMonth !== endMonth) {
            const endMonthDays = new Date(endYear, endMonth, 0).getDate();
            for (let j = 1; j <= end.getDate(); j++) {
                labels.push(`${j.toString().padStart(2, '0')}-${endMonth.toString().padStart(2, '0')}-${endYear}`);
            }
        } else {
            labels.push(`${i.toString().padStart(2, '0')}-${startMonth.toString().padStart(2, '0')}-${startYear}`);
        }
    }

    const datasets: any[] = [];
    Object.keys(ratesForRange).forEach(type => {
        datasets.push({
            label: `${paymentMethodsConst.value[type]}`,
            data: ratesForRange[type],
            borderColor: colors.value[parseInt(type)],
            fill: false
        });
    });

    setTimeout(() => {
        const ctx = document.getElementById("currency-history-chart") as HTMLCanvasElement;
        if (ctx) {
            if (chartInstance) chartInstance.destroy();
            chartInstance = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: datasets
                },
            });
        }
    }, 300);
});

watch(pendingQueue, (inComplete) => {
    if (inComplete) {
        resetSearch();
    }
});

// Initial logic
queueStore.updateListQueue({ 'name': section });
</script>
