<template>
    <v-card>
        <v-card-title class="d-flex align-center ga-3 flex-wrap">
            <span>Apps</span>
            <v-spacer />

            <v-menu v-model="dateMenu" :close-on-content-click="false" transition="scale-transition" offset-y>
                <template #activator="{ props }">
                    <v-text-field
                        v-bind="props"
                        :model-value="formattedDate"
                        density="compact"
                        variant="outlined"
                        hide-details
                        label="Date"
                        readonly
                        style="max-width: 180px"
                    />
                </template>
                <v-date-picker
                    v-model="selectedDate"
                    first-day-of-week="1"
                    show-adjacent-months
                    @update:modelValue="dateMenu = false"
                />
            </v-menu>

            <v-autocomplete
                v-model="selectedUserId"
                v-model:search="memberSearch"
                :items="userOptions"
                item-title="label"
                item-value="id"
                label="Member"
                density="compact"
                variant="outlined"
                hide-details
                :disabled="!canViewAllTracking"
                :loading="membersLoading"
                no-filter
                clearable
                style="max-width: 280px"
            />
        </v-card-title>

        <v-data-table :headers="headers" :items="items" item-value="application_name">
            <template #item.totalUsageSeconds="{ item }">{{ formatDuration(item.totalUsageSeconds) }}</template>
        </v-data-table>
    </v-card>
</template>

<script setup>
import axios from "axios"
import { computed, onMounted, ref, watch } from "vue"
import { useRoute, useRouter } from "vue-router"
import { currentUser } from "../auth"
import { apiEndpoints } from "../apiEndpoints"

const route = useRoute()
const router = useRouter()

const headers = [
    { title: "App Name", key: "applicationName" },
    { title: "Time Spent", key: "totalUsageSeconds" }
]

const selectedDate = ref(typeof route.query.date === "string" ? route.query.date : formatAsYmd(new Date()))
const selectedUserId = ref(route.query.user ? Number(route.query.user) : null)
const memberSearch = ref("")
const dateMenu = ref(false)
const organization = ref(null)
const userOptions = ref([])
const membersLoading = ref(false)
const items = ref([])

const canViewAllTracking = computed(() =>
    Boolean(organization.value?.isAdmin)
    || Boolean(organization.value?.isManager)
)
const formattedDate = computed(() => {
    const parsed = parseDateInput(selectedDate.value)
    return parsed
        ? parsed.toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" })
        : ""
})

function parseDateInput(date) {
    if (!date) return null

    if (date instanceof Date) {
        return Number.isNaN(date.getTime()) ? null : new Date(date.getFullYear(), date.getMonth(), date.getDate())
    }

    if (typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date)) {
        const [year, month, day] = date.split("-").map(Number)
        const parsed = new Date(year, month - 1, day)
        return Number.isNaN(parsed.getTime()) ? null : parsed
    }

    const parsed = new Date(date)
    return Number.isNaN(parsed.getTime()) ? null : new Date(parsed.getFullYear(), parsed.getMonth(), parsed.getDate())
}

function formatAsYmd(date) {
    const year = date.getFullYear()
    const month = `${date.getMonth() + 1}`.padStart(2, "0")
    const day = `${date.getDate()}`.padStart(2, "0")
    return `${year}-${month}-${day}`
}

function normalizeDateValue(value) {
    const parsed = parseDateInput(value)
    return parsed ? formatAsYmd(parsed) : formatAsYmd(new Date())
}

async function bootstrapScope() {
    const { data } = await axios.get(apiEndpoints.organizations.list, { params: { page: 1, perPage: 1 } })
    organization.value = data?.data?.[0] || null

    await fetchMembers(memberSearch.value)

    if (!selectedUserId.value && userOptions.value.length > 0) {
        selectedUserId.value = userOptions.value[0].id
    }
}

async function fetchMembers(search = "") {
    if (!organization.value?.id) return

    membersLoading.value = true
    try {
        const { data } = await axios.get(apiEndpoints.organizations.members(organization.value.id), {
            params: {
                page: 1,
                perPage: 20,
                search: search || undefined
            }
        })

        userOptions.value = (data?.data || []).map((member) => ({
            id: Number(member.id),
            label: member.displayName || member.email || `User ${member.id}`
        }))
    } finally {
        membersLoading.value = false
    }
}

async function fetchApps() {
    if (!selectedUserId.value) return

    try {
        const { data } = await axios.get(apiEndpoints.users.apps(selectedUserId.value), {
            params: { date: normalizeDateValue(selectedDate.value) }
        })

        items.value = data.data ?? []
    } catch (error) {
        console.error("Failed to fetch apps", error)
        items.value = []
    }
}

function formatDuration(seconds) {
    const value = Math.max(0, Number(seconds) || 0)
    const h = Math.floor(value / 3600)
    const m = Math.floor((value % 3600) / 60)
    return `${h}h ${m}m`
}

watch(memberSearch, async (value) => {
    if (!canViewAllTracking.value) return
    await fetchMembers(typeof value === "string" ? value.trim() : "")
})

watch([selectedDate, selectedUserId], async () => {
    const normalizedDate = normalizeDateValue(selectedDate.value)
    if (selectedDate.value !== normalizedDate) {
        selectedDate.value = normalizedDate
        return
    }

    router.replace({
        query: {
            date: normalizedDate,
            user: selectedUserId.value || undefined
        }
    })

    await fetchApps()
})

onMounted(async () => {
    await bootstrapScope()
    await fetchApps()
})
</script>
