<script setup lang="ts">
import type { ColumnDef } from '@tanstack/vue-table'

import { List, Search } from 'lucide-vue-next'
import { computed, h, onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'

import DataTable from '@/components/data-table/data-table.vue'
import { generateVueTable } from '@/components/data-table/use-generate-vue-table'
import DataTableViewOptions from '@/components/data-table/view-options.vue'
import DateTimePicker from '@/components/ui/date-picker/DateTimePicker.vue'
import { BasicPage } from '@/components/global-layout'
import Badge from '@/components/ui/badge/Badge.vue'
import { Input } from '@/components/ui/input'
import api from '@/services/api'

interface Variable {
  id: number
  key: string
  var_type: string
  scope: string
  max_records: number
}

interface VariableRecord {
  id: number
  data: any
  user_id?: number
  user?: {
    id: number
    username: string
  }
  created_at: string
}

function parseRecordData(record: VariableRecord): Record<string, any> {
  const rawData = record.data
  if (rawData == null || rawData === '') return {}
  if (typeof rawData === 'object') {
    if (Array.isArray(rawData)) {
      if (rawData.length > 0 && typeof rawData[0] === 'object' && rawData[0] !== null && !Array.isArray(rawData[0])) {
        return rawData[0] as Record<string, any>
      }
      const obj: Record<string, any> = {}
      rawData.forEach((item, index) => { obj[`item_${index}`] = item })
      return obj
    }
    return rawData as Record<string, any>
  }
  if (typeof rawData === 'string') {
    try {
      const parsed = JSON.parse(rawData)
      if (parsed != null && typeof parsed === 'object') {
        if (Array.isArray(parsed)) {
          if (parsed.length > 0 && typeof parsed[0] === 'object' && parsed[0] !== null && !Array.isArray(parsed[0])) {
            return parsed[0] as Record<string, any>
          }
          const obj: Record<string, any> = {}
          parsed.forEach((item: any, index: number) => { obj[`item_${index}`] = item })
          return obj
        }
        return parsed as Record<string, any>
      }
      return {}
    }
    catch {
      return {}
    }
  }
  return {}
}

const route = useRoute()
const router = useRouter()
const { t } = useI18n()

const loading = ref(true)
const variable = ref<Variable | null>(null)
const records = ref<VariableRecord[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(10)
const dateRange = ref<{ from: string, to: string }>({ from: '', to: '' })
const searchQuery = ref('')

const dynamicKeys = computed(() => {
  const keys = new Set<string>()
  records.value.forEach((record) => {
    const data = parseRecordData(record)
    if (data && typeof data === 'object') {
      Object.keys(data).forEach(key => keys.add(key))
    }
  })
  return Array.from(keys).sort()
})

const columns = computed<ColumnDef<VariableRecord>[]>(() => {
  const cols: ColumnDef<VariableRecord>[] = []

  cols.push({
    accessorKey: 'id',
    header: () => 'ID',
    cell: ({ row }) => h('div', { class: 'max-w-xs truncate' }, String(row.original.id)),
    size: 80,
  })

  if (variable.value?.scope === 'user') {
    cols.push({
      accessorKey: 'user',
      header: () => t('agent.cloudVariables.records.user'),
      cell: ({ row }) => {
        const user = row.original.user
        if (user) {
          return h(Badge, { variant: 'outline' }, () => user.username)
        }
        return h('span', { class: 'text-muted-foreground' }, '-')
      },
      size: 120,
    })
  }

  dynamicKeys.value.forEach((key) => {
    cols.push({
      id: `data_${key}`,
      header: () => key,
      accessorFn: (row) => {
        const data = parseRecordData(row)
        return data?.[key]
      },
      cell: ({ row }) => {
        const data = parseRecordData(row.original)
        const value = data?.[key]
        if (value === null || value === undefined) {
          return h('span', { class: 'text-muted-foreground' }, '-')
        }
        if (typeof value === 'object') {
          return h('div', { class: 'max-w-xs truncate', title: JSON.stringify(value) }, JSON.stringify(value))
        }
        if (typeof value === 'boolean') {
          return h(Badge, { variant: value ? 'default' : 'secondary' }, () => String(value))
        }
        return h('div', { class: 'max-w-xs truncate', title: String(value) }, String(value))
      },
      size: 150,
    })
  })

  if (dynamicKeys.value.length === 0) {
    cols.push({
      id: 'data',
      header: () => t('agent.cloudVariables.records.data'),
      cell: ({ row }) => {
        const data = parseRecordData(row.original)
        if (!data || Object.keys(data).length === 0) {
          return h('span', { class: 'text-muted-foreground' }, '-')
        }
        return h('div', { class: 'max-w-md truncate', title: JSON.stringify(data) }, JSON.stringify(data))
      },
    })
  }

  cols.push({
    accessorKey: 'created_at',
    header: () => t('agent.cloudVariables.records.createdAt'),
    cell: ({ row }) => {
      const createdAt = row.original.created_at
      if (!createdAt) return '-'
      try {
        const date = new Date(createdAt)
        if (Number.isNaN(date.getTime())) return '-'
        return date.toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
        })
      }
      catch {
        return '-'
      }
    },
    size: 160,
  })

  return cols
})

const serverPagination = computed(() => ({
  page: page.value,
  pageSize: pageSize.value,
  total: total.value,
  onPageChange: (newPage: number) => {
    page.value = newPage
  },
  onPageSizeChange: (newPageSize: number) => {
    pageSize.value = newPageSize
    page.value = 1
  },
}))

const table = generateVueTable<VariableRecord>({
  get data() { return records.value },
  get loading() { return loading.value },
  get columns() { return columns.value },
  serverPagination: serverPagination.value,
})

const columnLabels = computed(() => {
  const labels: Record<string, string> = {
    id: 'ID',
    created_at: 'agent.cloudVariables.records.createdAt',
  }
  if (variable.value?.scope === 'user') {
    labels.user = 'agent.cloudVariables.records.user'
  }
  dynamicKeys.value.forEach((key) => {
    labels[`data_${key}`] = key
  })
  return labels
})

watch([page, pageSize], () => {
  fetchRecords()
})

watch(dateRange, (newVal, oldVal) => {
  if (newVal.from !== oldVal.from || newVal.to !== oldVal.to) {
    page.value = 1
    fetchRecords()
  }
}, { deep: true })

async function fetchVariable() {
  try {
    const data = await api.get<{ variables: Variable[] }>(`/agent/cloud-variables`)
    const vars = data?.variables || []
    variable.value = vars.find((v: Variable) => String(v.id) === route.params.id) || null
    if (variable.value && variable.value.var_type !== 'stream') {
      router.back()
    }
  }
  catch {
    // ignore
  }
}

async function fetchRecords() {
  if (!variable.value) return
  loading.value = true
  try {
    const params = new URLSearchParams()
    params.append('page', String(page.value))
    params.append('page_size', String(pageSize.value))
    if (dateRange.value.from) {
      params.append('start_date', dateRange.value.from.split('T')[0])
    }
    if (dateRange.value.to) {
      params.append('end_date', dateRange.value.to.split('T')[0])
    }

    const data = await api.get<{ records: VariableRecord[], total: number }>(`/agent/cloud-variables/${variable.value.id}/records?${params}`)
    records.value = data?.records || []
    total.value = data?.total || 0
  }
  catch {
    records.value = []
    total.value = 0
  }
  finally {
    loading.value = false
  }
}

onMounted(async () => {
  await fetchVariable()
  if (variable.value) {
    fetchRecords()
  }
})
</script>

<template>
  <BasicPage
    :title="t('agent.cloudVariables.records.title')"
    :description="t('agent.cloudVariables.records.description', { key: variable?.key || '' })"
    :breadcrumbs="[
      { title: t('nav.dashboard'), href: '/agent' },
      { title: t('nav.cloudVariables'), href: '/agent/cloud-variables' },
      { title: t('agent.cloudVariables.records.title') },
    ]"
    sticky
  >
    <div class="space-y-6">
      <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('agent.cloudVariables.records.totalRecords') }}
            </UiCardTitle>
            <List class="size-4 text-muted-foreground" />
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ total }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('agent.cloudVariables.types.stream') }}
            </UiCardTitle>
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ variable?.key || '-' }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('agent.cloudVariables.records.maxRecordsLabel') }}
            </UiCardTitle>
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ variable?.max_records || t('agent.cloudVariables.records.unlimited') }}
            </div>
          </UiCardContent>
        </UiCard>

        <UiCard>
          <UiCardHeader class="flex flex-row items-center justify-between pb-2 space-y-0">
            <UiCardTitle class="text-sm font-medium">
              {{ t('agent.cloudVariables.columns.scope') }}
            </UiCardTitle>
          </UiCardHeader>
          <UiCardContent>
            <div class="text-2xl font-bold">
              {{ variable?.scope === 'user' ? t('agent.cloudVariables.userScope') : t('agent.cloudVariables.appScope') }}
            </div>
          </UiCardContent>
        </UiCard>
      </div>

      <UiCard>
        <UiCardContent class="p-6">
          <DataTable :columns="columns" :data="records" :loading="loading" :table="table" :server-pagination="serverPagination" @refresh="fetchRecords">
            <template #toolbar>
              <div class="flex flex-wrap items-center justify-between gap-2">
                <div class="flex flex-wrap items-center gap-2">
                  <div class="relative">
                    <Search class="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
                    <Input
                      v-model="searchQuery"
                      :placeholder="t('agent.cloudVariables.records.searchPlaceholder')"
                      class="pl-8 h-8 w-[150px] lg:w-[250px]"
                      disabled
                    />
                  </div>
                  <DateTimePicker
                    v-model="dateRange.from"
                    :placeholder="t('agent.cloudVariables.records.startDate')"
                    class="w-[180px]"
                  />
                  <span class="text-muted-foreground text-sm">{{ t('agent.cloudVariables.records.to') }}</span>
                  <DateTimePicker
                    v-model="dateRange.to"
                    :placeholder="t('agent.cloudVariables.records.endDate')"
                    class="w-[180px]"
                  />
                </div>
                <DataTableViewOptions :table="table" :column-labels="columnLabels" />
              </div>
            </template>
          </DataTable>
        </UiCardContent>
      </UiCard>
    </div>
  </BasicPage>
</template>
