<script setup lang="ts">
import { ref, computed, watch, type Ref } from 'vue'
import { Bar } from 'vue-chartjs'
import {
    Chart as ChartJS,
    Title,
    Tooltip,
    Legend,
    BarElement,
    CategoryScale,
    LinearScale,
} from 'chart.js'
import { getYears, getQuarters, getIssues, type QuarterData, type IssueTimeSummary } from '@/composable/useRepoApi'
import { useAuthStore } from '@/stores/auth'
import { i18n } from '@/plugins/02_i18n'
import type { TableColumn } from '@nuxt/ui'
import { useI18n } from 'vue-i18n'
import Default from '@/layouts/default.vue'

ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

const authStore = useAuthStore()

const { t } = useI18n()
const repos = ref<number[]>([])
const years = ref<number[]>([])
const quarters = ref<QuarterData[]>([])
const issues = ref<IssueTimeSummary[]>([])

const selectedRepo = ref<number | null>(null)
const selectedYear = ref<number | null>(null)
const selectedQuarter = ref<string | null>(null)

const page = ref(1)
const totalItems = ref(0)

const loading = ref(false)
const error = ref<string | null>(null)

async function loadData<T>(fetchFn: () => Promise<any>, target: Ref<T[]>, errorMsg: string) {
    loading.value = true
    error.value = null
    try {
        const response = await fetchFn()
        target.value = response.items || response || []
    } catch (e: any) {
        error.value = e?.message || errorMsg
    } finally {
        loading.value = false
    }
}

// onMounted(() => loadData(() => getRepos(), repos, t('repo_chart.failed_to_load_repositories')))

watch(selectedRepo, async (newRepo) => {
    selectedYear.value = null
    selectedQuarter.value = null
    quarters.value = []
    issues.value = []
    if (newRepo) {
        await loadData(() => getYears(newRepo), years, t('repo_chart.failed_to_load_years'))
    }
})

watch(selectedYear, async (newYear) => {
    selectedQuarter.value = null
    issues.value = []
    if (newYear && selectedRepo.value) {
        await loadData(() => getQuarters(selectedRepo.value!, newYear), quarters, t('repo_chart.failed_to_load_quarters'))
    }
})

watch(selectedQuarter, async (newQuarter) => {
    if (newQuarter && selectedRepo.value && selectedYear.value) {
        await loadIssues(selectedRepo.value, selectedYear.value, newQuarter)
    } else {
        issues.value = []
    }
})

watch(page, () => {
    if (selectedRepo.value && selectedYear.value && selectedQuarter.value) {
        loadIssues(selectedRepo.value, selectedYear.value, selectedQuarter.value)
    }
})

async function loadIssues(repoID: number, year: number, quarterStr: string) {
    const quarterPart = quarterStr.split('_Q')[1]
    if (!quarterPart) return
    loading.value = true
    error.value = null
    try {
        const response = await getIssues(repoID, year, parseInt(quarterPart), page.value, 10)
        issues.value = response.items || []
        totalItems.value = response.items_count || 0
    } catch (e: any) {
        error.value = e?.message || t('repo_chart.failed_to_load_issues')
    } finally {
        loading.value = false
    }
}

const chartData = computed(() => ({
    labels: quarters.value.map((q) => q.quarter),
    datasets: [
        {
            label: t('repo_chart.hours_worked'),
            backgroundColor: '#3b82f6',
            data: quarters.value.map((q) => q.time),
        },
    ],
}))

const chartOptions = computed(() => ({
    responsive: true,
    maintainAspectRatio: false,
    onClick: (_event: any, elements: any[]) => {
        if (elements.length > 0) {
            const index = elements[0].index
            const quarter = quarters.value[index]
            if (quarter) {
                selectedQuarter.value = quarter.quarter
            }
        }
    },
    plugins: {
        legend: { position: 'top' as const },
        title: { display: true, text: t('repo_chart.work_by_quarter') },
    },
    scales: {
        y: {
            beginAtZero: true,
            title: { display: true, text: t('repo_chart.hours') },
        },
    },
}))

const hasData = computed(() => quarters.value.length > 0)
const hasIssues = computed(() => issues.value.length > 0)

const items = computed(() => repos.value.map(r => ({ value: r, label: `Repo ${r}` })))

const yearItems = computed(() => [
    { value: null, label: t('repo_chart.select_a_year') },
    ...years.value.map(y => ({ value: y, label: String(y) }))
])

const quarterItems = computed(() => [
    { value: null, label: t('repo_chart.all_quarters') },
    ...quarters.value.map(q => ({
        value: q.quarter,
        label: `${q.quarter} (${q.time.toFixed(1)}h)`
    }))
])

const columns = computed<TableColumn<IssueTimeSummary>[]>(() => [
    {
        accessorKey: 'IssueID',
        header: 'ID'
    },
    {
        accessorKey: 'IssueName',
        header: i18n.t('repo_chart.issue_name'),
    },
    {
        accessorKey: 'CreatedDate',
        header: i18n.t('repo_chart.created_on'),
        cell: ({ row }) => {
            const date = new Date(row.getValue('CreatedDate'))
            return date.toLocaleDateString(i18n.locale.value)
        }
    },
    {
        accessorKey: 'TotalHoursSpent',
        header: i18n.t('repo_chart.hours_spent'),
        meta: {
            class: { th: 'text-right', td: 'text-right font-medium' }
        },
        cell: ({ row }) => `${row.getValue('TotalHoursSpent')}h`
    },
])
</script>

<template>
      <component :is="Default || 'div'">
    <div class="container mx-auto">
        <div class="p-6 bg-(--main-light) dark:bg-(--black) font-sans">
            <h1 class="text-2xl font-bold mb-6 text-black dark:text-white">{{ $t('repo_chart.repository_work_chart') }}
            </h1>
            <div v-if="error" class="mb-4 p-3 bg-red-100 text-red-700 rounded">{{ error }}</div>

            <div v-if="loading" class="mb-4 p-3 bg-blue-100 text-blue-700 rounded">{{ $t('repo_chart.loading') }}...
            </div>

            <div v-if="!authStore.isAuthenticated" class="mb-4 p-3 bg-yellow-100 text-yellow-700 rounded">
                {{ $t('repo_chart.login_to_view_charts') }}
            </div>

            <div v-if="authStore.isAuthenticated" class="flex flex-wrap gap-4 mb-6">
                <div class="flex flex-col">
                    <label class="mb-1 text-sm font-medium text-black dark:text-white">{{ $t('repo_chart.repository')
                        }}</label>
                    <USelect v-model="selectedRepo" :items="items" :disabled="loading"
                        :placeholder="$t('repo_chart.select_a_repository')" class="dark:text-white text-black " />
                    <!-- Select a repository -->
                </div>
                <div class="flex flex-col">
                    <label class="mb-1 text-sm font-medium text-black dark:text-white">{{ $t('repo_chart.year')
                        }}</label>
                    <USelect v-model="selectedYear" :items="yearItems"
                        :disabled="loading || !selectedRepo || years.length === 0"
                        :placeholder="$t('repo_chart.select_a_year')"
                        class="dark:text-white text-black placeholder:text-(--placeholder)" />
                </div>
                <div class="flex flex-col">
                    <label class="mb-1 text-sm font-medium text-black dark:text-white">{{ $t('repo_chart.quarter')
                        }}</label>
                    <USelect v-model="selectedQuarter" :items="quarterItems"
                        :disabled="loading || !selectedYear || quarters.length === 0"
                        :placeholder="$t('repo_chart.all_quarters')"
                        class="dark:text-white text-black placeholder:text-(--placeholder)" />
                </div>
            </div>

            <div v-if="hasData && authStore.isAuthenticated"
                class="mb-6 p-4  border border-(--border-light) dark:border-(--border-dark) rounded">
                <h2 class="text-xl font-medium mb-4 text-black dark:text-white">{{
                    $t('repo_chart.work_done_by_quarter') }}</h2>
                <div class="h-80">
                    <Bar :data="chartData" :options="chartOptions" />
                </div>
            </div>

            <div v-if="hasIssues && authStore.isAuthenticated"
                class="p-4  border border-(--border-light) dark:border-(--border-dark) rounded">
                <h2 class="text-xl font-medium mb-4 text-black dark:text-white">{{ $t('repo_chart.issues_for') }} {{
                    selectedQuarter }}
                </h2>
                <UTable :data="issues" :columns="columns" class="flex-1 dark:text-white! text-dark" />
                <div class="pt-4 flex justify-center items-center dark:text-white! text-dark">
                    <UPagination v-model:page="page" :total="totalItems" :page-size="10" />
                </div>
            </div>

            <div v-else-if="selectedQuarter && !loading && authStore.isAuthenticated && !hasIssues"
                class="mt-4 p-3 dark:bg-(--black) bg-(--main-light) border border-(--border-light) dark:border-(--border-dark) dark:text-white! text-black rounded">
                {{ $t('validate_error.no_issues_for_quarter') }}.
            </div>

            <div v-else-if="!loading && authStore.isAuthenticated"
                class="p-3 dark:bg-(--black) bg-(--main-light)  border border-(--border-light) dark:border-(--border-dark) rounded dark:text-white! text-black">
                <span v-if="!selectedRepo">{{ $t('repo_chart.select_repo_to_view_data') }}</span>
                <span v-else-if="!selectedYear">{{ $t('repo_chart.select_year_to_view_data') }}</span>
                <span v-else-if="!selectedQuarter">{{ $t('repo_chart.select_quarter_to_view_issues') }}</span>
                <span v-else-if="quarters.length === 0">{{ $t('repo_chart.no_work_data_available') }}</span>
            </div>
        </div>
    </div>
    </component>
</template>