<script setup lang="ts">
import { Head } from '@inertiajs/vue3';
import {
    Clock,
    Moon,
    Sun,
    Sunrise,
    TrendingDown,
    TrendingUp,
    UserCheck,
} from '@lucide/vue';
import { Donut } from '@unovis/ts';
import { VisDonut, VisSingleContainer, VisTooltip } from '@unovis/vue';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import AttendanceCard from '@/components/card/AttendanceCard.vue';
import StatCard from '@/components/card/StatCard.vue';
import {
    Card,
    CardContent,
    CardDescription, CardHeader,
    CardTitle
} from '@/components/ui/card';
import type { ChartConfig } from '@/components/ui/chart';
import { ChartContainer } from '@/components/ui/chart';
import { useCan } from '@/composables/useCan';
import AdminLayout from '@/layouts/AdminLayout.vue';
import { formatRupiah } from '@/lib/rupiah';
import AttendanceWebcamModal from '@/pages/admin/hr/attendances/form/AttendanceWebcamModal.vue';
import type { TodayAttendance } from '@/types/attendance';

interface DashboardProps {
    attendance: {
        total_employees: number;
        percentage: number;
        present: number;
        absent: number;
        on_leave: number;
    };
    revenueSummary: {
        total_revenue: number;
        total_discount: number;
        total_marketplace_fees: number;
        total_deduction: number;
        total_orders: number;
        avg_order: number;
    };
    expenseSummary: {
        total: number;
        purchase_total: number;
        expense_total: number;
        advance_total: number;
    };

    orderStats: {
        by_channel: Array<{
            channel: string;
            label: string;
            count: number;
            total: number;
        }>;
        by_payment_type: Array<{
            payment_type: string;
            label: string;
            count: number;
            total: number;
        }>;
        by_marketing: Array<{
            name: string;
            count: number;
            total: number;
        }>;
        by_status: Array<{
            status: string;
            label: string;
            count: number;
        }>;
    };
    todayAttendance: TodayAttendance;
    isOnLeave: boolean;
    canCheckIn: boolean;
}

const props = defineProps<DashboardProps>();

const { can, hasRole } = useCan();

const webcamModalOpen = ref(false);
const webcamMode = ref<'check-in' | 'check-out'>('check-in');

function openCheckInModal() {
    webcamMode.value = 'check-in';
    webcamModalOpen.value = true;
}

function openCheckOutModal() {
    webcamMode.value = 'check-out';
    webcamModalOpen.value = true;
}

const currentTime = ref(new Date());
let timer: ReturnType<typeof setInterval>;

onMounted(() => {
    timer = setInterval(() => {
        currentTime.value = new Date();
    }, 1000);
});

onUnmounted(() => {
    clearInterval(timer);
});

const timeStr = computed(() => {
    return currentTime.value.toLocaleTimeString('id-ID', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false,
    });
});

const dateStr = computed(() => {
    return currentTime.value.toLocaleDateString('id-ID', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
    });
});

const greeting = computed(() => {
    const hour = currentTime.value.getHours();

    if (hour >= 4 && hour < 11) {
        return { text: 'Selamat Pagi', icon: Sunrise };
    }

    if (hour >= 11 && hour < 15) {
        return { text: 'Selamat Siang', icon: Sun };
    }

    if (hour >= 15 && hour < 18) {
        return { text: 'Selamat Sore', icon: Sun };
    }

    return { text: 'Selamat Malam', icon: Moon };
});

// Chart configs - each segment uses a different color family for clarity
const allChartColors = [
    '#60a5fa', // biru
    '#f97316', // oranye
    '#22c55e', // hijau
    '#a855f7', // ungu
    '#ef4444', // merah
];

const channelColors = allChartColors;
const channelChartConfig = computed(() => {
    const config: ChartConfig = {};
    props.orderStats.by_channel.forEach((item, index) => {
        config[item.channel] = {
            label: item.label,
            color: channelColors[index % channelColors.length],
        };
    });

    return config;
});

const paymentColors = allChartColors;
const paymentChartConfig = computed(() => {
    const config: ChartConfig = {};
    props.orderStats.by_payment_type.forEach((item, index) => {
        config[item.payment_type] = {
            label: item.label,
            color: paymentColors[index % paymentColors.length],
        };
    });

    return config;
});

const statusColors = allChartColors;
const statusChartConfig = computed(() => {
    const config: ChartConfig = {};
    props.orderStats.by_status.forEach((item, index) => {
        config[item.status] = {
            label: item.label,
            color: statusColors[index % statusColors.length],
        };
    });

    return config;
});

const marketingColors = allChartColors;
const marketingChartConfig = computed(() => {
    const config: ChartConfig = {};
    props.orderStats.by_marketing.forEach((item, index) => {
        config[`mkt_${index}`] = {
            label: item.name,
            color: marketingColors[index % marketingColors.length],
        };
    });

    return config;
});

// Tooltip triggers for donut charts
const donutSegmentSelector = Donut.selectors.segment;

function channelTooltip(arc: any) {
    const d = arc.data as typeof props.orderStats.by_channel[number];
    return `<div class="rounded-lg border bg-background px-3 py-1.5 shadow-xl" style="line-height:1.2">
        <p style="margin:0;display:flex;align-items:center;gap:0.5rem">
            <span class="size-2.5 rounded-full" style="background-color: ${channelChartConfig.value[d.channel]?.color ?? channelColors[0]}"></span>
            <span class="text-muted-foreground">${d.label}</span>
            <span class="ml-auto font-medium tabular-nums text-foreground">${d.count.toLocaleString('id-ID')}</span>
        </p>
    </div>`;
}

function paymentTooltip(arc: any) {
    const d = arc.data as typeof props.orderStats.by_payment_type[number];
    return `<div class="rounded-lg border bg-background px-3 py-1.5 shadow-xl" style="line-height:1.2">
        <p style="margin:0;display:flex;align-items:center;gap:0.5rem">
            <span class="size-2.5 rounded-full" style="background-color: ${paymentChartConfig.value[d.payment_type]?.color ?? paymentColors[0]}"></span>
            <span class="text-muted-foreground">${d.label}</span>
            <span class="ml-auto font-medium tabular-nums text-foreground">${d.count.toLocaleString('id-ID')}</span>
        </p>
    </div>`;
}

function marketingTooltip(arc: any) {
    const d = arc.data as typeof props.orderStats.by_marketing[number];
    const idx = props.orderStats.by_marketing.indexOf(d);
    return `<div class="rounded-lg border bg-background px-3 py-1.5 shadow-xl" style="line-height:1.2">
        <p style="margin:0;display:flex;align-items:center;gap:0.5rem">
            <span class="size-2.5 rounded-full" style="background-color: ${marketingColors[idx % marketingColors.length]}"></span>
            <span class="text-muted-foreground">${d.name}</span>
            <span class="ml-auto font-medium tabular-nums text-foreground">${d.count.toLocaleString('id-ID')}</span>
        </p>
    </div>`;
}

function statusTooltip(arc: any) {
    const d = arc.data as typeof props.orderStats.by_status[number];
    return `<div class="rounded-lg border bg-background px-3 py-1.5 shadow-xl" style="line-height:1.2">
        <p style="margin:0;display:flex;align-items:center;gap:0.5rem">
            <span class="size-2.5 rounded-full" style="background-color: ${statusChartConfig.value[d.status]?.color ?? statusColors[0]}"></span>
            <span class="text-muted-foreground">${d.label}</span>
            <span class="ml-auto font-medium tabular-nums text-foreground">${d.count.toLocaleString('id-ID')}</span>
        </p>
    </div>`;
}

const visibleStatsCount = computed(() => {
    let count = 0;

    if (can('dashboard.attendance')) {
        count++;
    }

    if (can('dashboard.revenue')) {
        count++;
    }

    if (can('dashboard.expense')) {
        count++;
    }

    return count;
});

const statsGridClass = computed(() => {
    const count = visibleStatsCount.value;

    if (count === 1) {
        return 'grid gap-4 grid-cols-1 md:max-w-md';
    }

    if (count === 2) {
        return 'grid gap-4 grid-cols-1 md:grid-cols-2';
    }

    if (count === 3) {
        return 'grid gap-4 grid-cols-1 md:grid-cols-3';
    }

    return 'grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-4';
});

const visibleChartsCount = computed(() => {
    let count = 0;

    if (can('dashboard.orders_channel')) {
        count++;
    }

    if (can('dashboard.orders_payment')) {
        count++;
    }

    if (can('dashboard.orders_marketing')) {
        count++;
    }

    if (can('dashboard.orders_status')) {
        count++;
    }

    return count;
});

const chartsGridClass = computed(() => {
    const count = visibleChartsCount.value;

    if (count === 1) {
        return 'grid gap-4 grid-cols-1 md:max-w-xl';
    }

    if (count === 2) {
        return 'grid gap-4 grid-cols-1 md:grid-cols-2';
    }

    if (count === 3) {
        return 'grid gap-4 grid-cols-1 md:grid-cols-3';
    }

    return 'grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-4';
});
</script>

<template>

    <Head title="Dasbor" />

    <AdminLayout>
        <div class="flex flex-1 flex-col gap-6">
            <!-- Welcome Card -->
            <Card class="relative overflow-hidden">
                <div class="absolute inset-0 bg-linear-to-br from-primary/5 to-background" />
                <CardHeader class="relative">
                    <div class="flex items-center gap-3">
                        <div class="flex size-12 items-center justify-center rounded-full bg-primary/10">
                            <component :is="greeting.icon" class="size-6 text-primary" />
                        </div>
                        <div>
                            <CardTitle class="text-2xl font-bold">
                                {{ greeting.text }},
                                {{ $page.props.auth.user?.username }}!
                            </CardTitle>
                            <CardDescription class="mt-1">
                                Selamat datang di dasbor aplikasi.
                            </CardDescription>
                        </div>
                    </div>
                </CardHeader>
                <CardContent class="relative">
                    <div class="flex items-center gap-2 text-sm text-muted-foreground">
                        <span>{{ dateStr }}</span>
                        <span>-</span>
                        <span class="flex items-center gap-1">
                            <Clock class="size-3.5" />
                            {{ timeStr }}
                        </span>
                    </div>
                </CardContent>
            </Card>

            <AttendanceCard :today-attendance="todayAttendance" :is-on-leave="isOnLeave" :can-check-in="canCheckIn"
                @check-in="openCheckInModal" @check-out="openCheckOutModal" />

            <div v-if="visibleStatsCount > 0" :class="statsGridClass">
                <StatCard v-if="can('dashboard.attendance')" title="Kehadiran" :icon="UserCheck"
                    main-label="Total Karyawan" :main-value="attendance.total_employees"
                    :sub-label="attendance.percentage + '% hadir'" :items="[
                        {
                            label: 'Hadir',
                            value: attendance.present,
                        },
                        {
                            label: 'Tidak Hadir',
                            value: attendance.absent,
                        },
                        {
                            label: 'Cuti',
                            value: attendance.on_leave,
                        },
                    ]" />

                <StatCard v-if="can('dashboard.revenue')" title="Pendapatan" :icon="TrendingUp" main-label="Total"
                    :main-value="'Rp' + formatRupiah(revenueSummary.total_revenue)" :sub-label="revenueSummary.total_orders + ' transaksi selesai'
                        " :items="[
                            {
                                label: 'Bersih',
                                value: 'Rp' + formatRupiah(
                                    revenueSummary.total_revenue -
                                    revenueSummary.total_deduction,
                                ),
                            },
                            {
                                label: 'Potongan',
                                value: 'Rp' + formatRupiah(revenueSummary.total_marketplace_fees ?? 0),
                            },
                            {
                                label: 'Diskon',
                                value: 'Rp' + formatRupiah(revenueSummary.total_discount),
                            },
                        ]" />

                <StatCard v-if="can('dashboard.expense')" title="Pengeluaran" :icon="TrendingDown" main-label="Total"
                    :main-value="'Rp' + formatRupiah(expenseSummary.total)" :items="[
                        ...(!hasRole('admin-toko') ? [{
                            label: 'Belanja',
                            value: 'Rp' + formatRupiah(expenseSummary.purchase_total),
                        }] : []),
                        {
                            label: 'Pengeluaran',
                            value: 'Rp' + formatRupiah(expenseSummary.expense_total),
                        },
                        {
                            label: 'Kasbon',
                            value: 'Rp' + formatRupiah(expenseSummary.advance_total),
                        },
                    ]" />
            </div>

            <div v-if="visibleChartsCount > 0" :class="chartsGridClass">
                <Card v-if="can('dashboard.orders_channel')">
                    <CardHeader>
                        <CardTitle class="text-base">Pesanan per Channel</CardTitle>
                    </CardHeader>
                    <CardContent>
                        <div v-if="orderStats.by_channel.length > 0">
                            <ChartContainer :config="channelChartConfig"
                                class="mx-auto aspect-square max-h-[200px] chart-channel">
                                <VisSingleContainer :data="orderStats.by_channel" :margin="{ top: 10, bottom: 10 }">
                                    <VisDonut :value="(d: (typeof orderStats.by_channel)[number]) => d.count"
                                        :color="(d: (typeof orderStats.by_channel)[number]) => channelChartConfig[d.channel]?.color ?? channelColors[0]"
                                        :arc-width="30" />
                                    <VisTooltip :triggers="{ [donutSegmentSelector]: channelTooltip }"
                                        class-name="custom-tooltip" />
                                </VisSingleContainer>
                            </ChartContainer>
                            <div class="mt-3 flex flex-wrap justify-center gap-3">
                                <div v-for="(item, index) in orderStats.by_channel" :key="item.channel"
                                    class="flex items-center gap-1.5">
                                    <span class="size-2.5 rounded-full"
                                        :style="{ backgroundColor: channelColors[index % channelColors.length] }" />
                                    <span class="text-xs text-muted-foreground">{{ item.label }}</span>
                                    <span class="text-xs font-medium">{{ item.count }}</span>
                                </div>
                            </div>
                        </div>
                        <div v-else class="flex h-[200px] items-center justify-center text-muted-foreground">
                            Belum ada data
                        </div>
                    </CardContent>
                </Card>

                <Card v-if="can('dashboard.orders_payment')">
                    <CardHeader>
                        <CardTitle class="text-base">Pesanan per Pembayaran</CardTitle>
                    </CardHeader>
                    <CardContent>
                        <div v-if="orderStats.by_payment_type.length > 0">
                            <ChartContainer :config="paymentChartConfig"
                                class="mx-auto aspect-square max-h-[200px] chart-payment">
                                <VisSingleContainer :data="orderStats.by_payment_type"
                                    :margin="{ top: 10, bottom: 10 }">
                                    <VisDonut :value="(d: (typeof orderStats.by_payment_type)[number]) => d.count"
                                        :color="(d: (typeof orderStats.by_payment_type)[number]) => paymentChartConfig[d.payment_type]?.color ?? paymentColors[0]"
                                        :arc-width="30" />
                                    <VisTooltip :triggers="{ [donutSegmentSelector]: paymentTooltip }"
                                        class-name="custom-tooltip" />
                                </VisSingleContainer>
                            </ChartContainer>
                            <div class="mt-3 flex flex-wrap justify-center gap-3">
                                <div v-for="(item, index) in orderStats.by_payment_type" :key="item.payment_type"
                                    class="flex items-center gap-1.5">
                                    <span class="size-2.5 rounded-full"
                                        :style="{ backgroundColor: paymentColors[index % paymentColors.length] }" />
                                    <span class="text-xs text-muted-foreground">{{ item.label }}</span>
                                    <span class="text-xs font-medium">{{ item.count }}</span>
                                </div>
                            </div>
                        </div>
                        <div v-else class="flex h-[200px] items-center justify-center text-muted-foreground">
                            Belum ada data
                        </div>
                    </CardContent>
                </Card>

                <Card v-if="can('dashboard.orders_marketing')">
                    <CardHeader>
                        <CardTitle class="text-base">Pesanan per Marketing</CardTitle>
                    </CardHeader>
                    <CardContent>
                        <div v-if="orderStats.by_marketing.length > 0">
                            <ChartContainer :config="marketingChartConfig"
                                class="mx-auto aspect-square max-h-[200px] chart-marketing">
                                <VisSingleContainer :data="orderStats.by_marketing" :margin="{ top: 10, bottom: 10 }">
                                    <VisDonut :value="(d: (typeof orderStats.by_marketing)[number]) => d.count"
                                        :color="(_d: (typeof orderStats.by_marketing)[number], i: number) => marketingColors[i % marketingColors.length]"
                                        :arc-width="30" />
                                    <VisTooltip :triggers="{ [donutSegmentSelector]: marketingTooltip }"
                                        class-name="custom-tooltip" />
                                </VisSingleContainer>
                            </ChartContainer>
                            <div class="mt-3 flex flex-wrap justify-center gap-3">
                                <div v-for="(item, index) in orderStats.by_marketing" :key="item.name"
                                    class="flex items-center gap-1.5">
                                    <span class="size-2.5 rounded-full"
                                        :style="{ backgroundColor: marketingColors[index % marketingColors.length] }" />
                                    <span class="text-xs text-muted-foreground">{{ item.name }}</span>
                                    <span class="text-xs font-medium">{{ item.count }}</span>
                                </div>
                            </div>
                        </div>
                        <div v-else class="flex h-[200px] items-center justify-center text-muted-foreground">
                            Belum ada data
                        </div>
                    </CardContent>
                </Card>

                <Card v-if="can('dashboard.orders_status')">
                    <CardHeader>
                        <CardTitle class="text-base">Pesanan per Status</CardTitle>
                    </CardHeader>
                    <CardContent>
                        <div v-if="orderStats.by_status.length > 0">
                            <ChartContainer :config="statusChartConfig"
                                class="mx-auto aspect-square max-h-[200px] chart-status">
                                <VisSingleContainer :data="orderStats.by_status" :margin="{ top: 10, bottom: 10 }">
                                    <VisDonut :value="(d: (typeof orderStats.by_status)[number]) => d.count"
                                        :color="(d: (typeof orderStats.by_status)[number]) => statusChartConfig[d.status]?.color ?? statusColors[0]"
                                        :arc-width="30" />
                                    <VisTooltip :triggers="{ [donutSegmentSelector]: statusTooltip }"
                                        class-name="custom-tooltip" />
                                </VisSingleContainer>
                            </ChartContainer>
                            <div class="mt-3 flex flex-wrap justify-center gap-3">
                                <div v-for="(item, index) in orderStats.by_status" :key="item.status"
                                    class="flex items-center gap-1.5">
                                    <span class="size-2.5 rounded-full"
                                        :style="{ backgroundColor: statusColors[index % statusColors.length] }" />
                                    <span class="text-xs text-muted-foreground">{{ item.label }}</span>
                                    <span class="text-xs font-medium">{{ item.count }}</span>
                                </div>
                            </div>
                        </div>
                        <div v-else class="flex h-[200px] items-center justify-center text-muted-foreground">
                            Belum ada data
                        </div>
                    </CardContent>
                </Card>
            </div>
        </div>

        <AttendanceWebcamModal v-if="canCheckIn" v-model:open="webcamModalOpen" :mode="webcamMode" />
    </AdminLayout>
</template>

<style>
:root {
    --vis-tooltip-background-color: transparent !important;
    --vis-tooltip-border-color: transparent !important;
    --vis-tooltip-padding: 0 !important;
    --vis-tooltip-box-shadow: none !important;
    --vis-tooltip-border-radius: 0 !important;
}

.custom-tooltip {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
}

.chart-channel,
.chart-payment,
.chart-marketing,
.chart-status {
    --vis-donut-segment-stroke-width: 2;
    --vis-donut-segment-stroke-color: #374151;
}
</style>
