import type { ColumnDef } from '@tanstack/vue-table'
import type { Composer } from 'vue-i18n'

import { Ban, Monitor, MoreHorizontal, Pencil, Trash2 } from 'lucide-vue-next'
import { h } from 'vue'

import type { User } from '@/pages/admin/users/data/schema'

import Badge from '@/components/ui/badge/Badge.vue'
import Button from '@/components/ui/button/Button.vue'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { getOnlineStatusLabel, getOnlineStatusVariant } from '@/pages/admin/users/data/data'

export function getColumns(actions: {
  onEdit: (row: User) => void
  onToggleStatus: (row: User) => void
  onDelete: (row: User) => void
  onManageDevices: (row: User) => void
}, t: Composer['t']): ColumnDef<User>[] {
  return [
    {
      accessorKey: 'username',
      header: () => t('admin.users.columns.username'),
      cell: ({ row }) => {
        const username = row.getValue('username') as string
        return h('div', { class: 'flex items-center space-x-3' }, [
          h('div', { class: 'h-8 w-8 rounded bg-primary/10 flex items-center justify-center flex-shrink-0' }, [
            h('span', { class: 'text-primary font-bold text-sm' }, username.charAt(0).toUpperCase()),
          ]),
          h('div', {}, [
            h('p', { class: 'font-medium' }, username),
          ]),
        ])
      },
    },
    {
      accessorKey: 'email',
      header: () => t('admin.users.columns.email'),
      cell: ({ row }) => {
        const email = row.getValue('email') as string
        return email || '-'
      },
    },
    {
      accessorKey: 'application.name',
      header: () => t('admin.users.columns.application'),
      cell: ({ row }) => {
        const appName = row.original.application?.name
        return appName ? h(Badge, { variant: 'secondary' }, () => appName) : '-'
      },
    },
    {
      accessorKey: 'online_status',
      header: () => t('admin.users.columns.status'),
      cell: ({ row }) => {
        const status = (row.getValue('online_status') as string) || 'offline'
        return h(Badge, { variant: getOnlineStatusVariant(status as any) }, () => getOnlineStatusLabel(status as any))
      },
    },
    {
      accessorKey: 'device_count',
      header: () => t('admin.users.columns.deviceCount'),
      cell: ({ row }) => {
        const count = row.getValue('device_count') as number
        return h('span', { class: 'font-medium' }, count ?? 0)
      },
    },
    {
      accessorKey: 'balance',
      header: () => t('admin.users.columns.balance'),
      cell: ({ row }) => {
        const balance = row.getValue('balance') as number
        const billingType = row.original.application?.billing_type

        if (balance === -1) {
          return h(Badge, { variant: 'default', class: 'bg-green-500 hover:bg-green-600' }, () => t('admin.users.expiry.permanent'))
        }

        if (billingType === 'subscription') {
          if (balance === null || balance === undefined)
            return '-'
          return h('span', { class: balance > 0 ? 'text-green-600 font-medium' : 'text-muted-foreground' }, balance.toFixed(2))
        }

        if (balance === null || balance === undefined)
          return '-'

        return h('span', { class: balance > 0 ? 'text-green-600 font-medium' : 'text-muted-foreground' }, balance.toFixed(2))
      },
    },
    {
      accessorKey: 'expiry_at',
      header: () => t('admin.users.columns.expiryAt'),
      cell: ({ row }) => {
        const expiryAt = row.getValue('expiry_at') as string
        const billingType = row.original.application?.billing_type

        if (billingType !== 'subscription') {
          return h('span', { class: 'text-muted-foreground' }, '-')
        }

        if (!expiryAt) {
          return h('span', { class: 'text-muted-foreground' }, '-')
        }

        try {
          const date = new Date(expiryAt)
          if (Number.isNaN(date.getTime()))
            return '-'

          const now = new Date()
          if (date < now) {
            return h(Badge, { variant: 'destructive' }, () => t('admin.users.expiry.expired'))
          }

          const daysLeft = Math.ceil((date.getTime() - now.getTime()) / (1000 * 60 * 60 * 24))
          return h('div', { class: 'flex flex-col' }, [
            h('span', { class: 'text-green-600 font-medium' }, `${daysLeft} ${t('admin.users.expiry.daysLeft')}`),
            h('span', { class: 'text-xs text-muted-foreground' }, date.toLocaleDateString('zh-CN')),
          ])
        }
        catch {
          return '-'
        }
      },
    },
    {
      accessorKey: 'last_login_at',
      header: () => t('admin.users.columns.lastLoginAt'),
      cell: ({ row }) => {
        const lastLoginAt = row.getValue('last_login_at')
        if (!lastLoginAt)
          return '-'
        try {
          const date = new Date(lastLoginAt as string)
          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 '-'
        }
      },
    },
    {
      accessorKey: 'created_at',
      header: () => t('admin.users.columns.createdAt'),
      cell: ({ row }) => {
        const createdAt = row.getValue('created_at')
        if (!createdAt)
          return '-'
        try {
          const date = new Date(createdAt as string)
          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 '-'
        }
      },
    },
    {
      id: 'actions',
      header: () => h('span', { class: 'sr-only' }, t('common.actions')),
      cell: ({ row }) => {
        const user = row.original
        const isBanned = user.status === 'banned'

        return h(
          DropdownMenu,
          {},
          {
            default: () => [
              h(DropdownMenuTrigger, { asChild: true }, () =>
                h(Button, { variant: 'ghost', class: 'h-8 w-8 p-0' }, () => [
                  h(MoreHorizontal, { class: 'h-4 w-4' }),
                  h('span', { class: 'sr-only' }, t('common.openMenu')),
                ])),
              h(
                DropdownMenuContent,
                { align: 'end' },
                () => [
                  h(DropdownMenuItem, { onClick: () => actions.onEdit(user) }, () => [
                    h(Pencil, { class: 'mr-2 h-4 w-4' }),
                    t('common.edit'),
                  ]),
                  h(DropdownMenuItem, { onClick: () => actions.onManageDevices(user) }, () => [
                    h(Monitor, { class: 'mr-2 h-4 w-4' }),
                    t('admin.users.devices'),
                  ]),
                  h(DropdownMenuItem, { onClick: () => actions.onToggleStatus(user) }, () => [
                    h(Ban, { class: 'mr-2 h-4 w-4' }),
                    isBanned ? t('common.unban') : t('common.ban'),
                  ]),
                  h(DropdownMenuSeparator),
                  h(DropdownMenuItem, { class: 'text-destructive', onClick: () => actions.onDelete(user) }, () => [
                    h(Trash2, { class: 'mr-2 h-4 w-4' }),
                    t('common.delete'),
                  ]),
                ],
              ),
            ],
          },
        )
      },
      enableSorting: false,
      enableHiding: false,
    },
  ]
}
