<script setup lang="ts">
import type { TableColumn } from '@nuxt/ui'
import { h, resolveComponent } from 'vue'

const UBadge = resolveComponent('UBadge')
const UAvatar = resolveComponent('UAvatar')
const UButton = resolveComponent('UButton')
const UDropdownMenu = resolveComponent('UDropdownMenu')
const NuxtTime = resolveComponent('NuxtTime')
const SuperAdminUserBanStatus = resolveComponent('SuperAdminUserBanStatus')
const SuperAdminUserOAuthAccounts = resolveComponent('SuperAdminUserOAuthAccounts')
const { locale, t } = useI18n()
const localePath = useLocalePath()
const { fetchSession } = useAuth()

const loading = ref(true)
const newUserModal = ref(false)
const banUserModal = ref(false)
const loadingUserId = ref<string | null>(null)
const showDeleteUserConfirmation = ref(false)
const selectedUser = ref<AdminUserRow | null>(null)
const toast = useToast()
const isEmailsMasked = ref(true)

definePageMeta({
  middleware: 'super-admin'
})

// Reactive pagination state
const page = ref(1)
const pageSize = ref(20)

// Filter state
const filters = ref({
  role: 'all',
  emailVerified: 'all',
  banned: 'all',
  subscription: 'all',
  provider: 'all'
})

// Reset page when filters change
watch(filters, () => {
  page.value = 1
}, { deep: true })

// Types
type ApiUser = {
  id: string
  name: string
  email: string
  image: string | null
  emailVerified: boolean
  superAdmin: boolean
  createdAt: string
  updatedAt: string
  banned?: boolean
  bannedUntil?: string | null
  providers?: string[]
  subscriptions?: Array<{
    id: string
    status: string
    productName: string | null
    productId: string | null
    interval: string | null
    intervalCount: number | null
  }>
}
type UsersResponse = { users: ApiUser[], total: number, page: number, pageSize: number }

// Fetch on client to avoid SSR cache/stale session issues; react to pagination and filter changes
const { data, refresh, pending } = await useApiFetch<UsersResponse>('/api/super-admin/users', {
  server: false,
  query: computed(() => ({
    page: page.value,
    pageSize: pageSize.value,
    role: filters.value.role,
    emailVerified: filters.value.emailVerified,
    banned: filters.value.banned,
    subscription: filters.value.subscription,
    provider: filters.value.provider
  }))
})

const isLoading = computed(() => {
  const pendingValue = typeof pending === 'object' && 'value' in pending ? pending.value : pending
  return Boolean(pendingValue) || loading.value
})

// Fetch available products for subscription filter
const { data: productsData } = await useApiFetch<Array<{ id: string, name: string }>>(
  '/api/super-admin/products',
  { server: false }
)

// Extract products list from ApiResponse
const products = computed<Array<{ id: string, name: string }>>(() => {
  const productsDataValue = productsData.value
  return Array.isArray(productsDataValue) ? productsDataValue : []
})

type AdminUserRow = ApiUser
const users = computed(() => {
  const response = data.value
  return (response && 'users' in response ? response.users : []) as AdminUserRow[]
})
const totalUsers = computed(() => {
  const response = data.value
  return (response && 'total' in response ? response.total : 0) as number
})

type SortState = false | 'asc' | 'desc'
type SortableColumn = { getIsSorted: () => SortState, toggleSorting: (desc?: boolean) => void }

function getSortedHeader(column: SortableColumn, label: string) {
  const isSorted = column.getIsSorted()

  return h(UButton, {
    color: 'neutral',
    variant: 'ghost',
    label,
    trailingIcon: isSorted
      ? isSorted === 'asc'
        ? 'lucide:chevron-up'
        : 'lucide:chevron-down'
      : 'lucide:chevrons-up-down',
    ui: {
      base: '-mx-2.5 font-semibold',
      trailingIcon: 'size-3'
    },
    onClick: () => column.toggleSorting(column.getIsSorted() === 'asc')
  })
}

const formatInterval = (interval: string | null, intervalCount: number | null) => {
  if (!interval) return ''
  if (intervalCount === 1) return interval
  return `${intervalCount} ${interval}s`
}

const getStatusColor = (status: string): 'success' | 'warning' | 'error' | 'neutral' => {
  switch (status.toLowerCase()) {
    case 'active':
      return 'success'
    case 'trialing':
      return 'warning'
    case 'canceled':
    case 'incomplete':
    case 'incomplete_expired':
    case 'past_due':
    case 'unpaid':
      return 'error'
    default:
      return 'neutral'
  }
}

const columns: TableColumn<AdminUserRow>[] = [
  {
    accessorKey: 'image',
    header: '',
    cell: ({ row }) => {
      return h('div', { class: 'flex items-center' }, [
        h(UAvatar, {
          src: row.original.image,
          size: 'sm'
        })
      ])
    }
  },
  {
    accessorKey: 'name',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.name')),
    cell: ({ row }) => {
      return h('div', { class: 'flex items-center gap-3' }, [
        h('div', undefined, [
          h('p', { class: 'font-medium text-highlighted' }, row.original.name)
        ])
      ])
    }
  },
  {
    id: 'email',
    accessorKey: 'email',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.email')),
    cell: ({ row }) => {
      return h('div', undefined, [
        h('p', { class: '' }, isEmailsMasked.value ? maskEmail(row.original.email) : row.original.email)
      ])
    }
  },
  {
    id: 'superAdmin',
    accessorKey: 'superAdmin',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.role')),
    cell: ({ row }) => {
      const isSuperAdmin = Boolean(row.getValue('superAdmin') as boolean)
      const color = isSuperAdmin ? 'success' : 'neutral'

      return h(UBadge, { class: 'capitalize', variant: 'subtle', color, size: 'sm' }, () =>
        isSuperAdmin ? 'Admin' : 'User'
      )
    }
  },
  {
    id: 'emailVerified',
    accessorKey: 'emailVerified',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.verified')),
    cell: ({ row }) => {
      const verified = Boolean(row.getValue('emailVerified') as boolean)
      const color = verified ? 'success' : 'error'

      return h(UBadge, { class: 'capitalize', variant: 'subtle', color, size: 'sm' }, () =>
        verified ? 'Verified' : 'Unverified'
      )
    }
  },
  {
    id: 'banned',
    accessorKey: 'banned',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.banned')),
    cell: ({ row }) => {
      return h(SuperAdminUserBanStatus, {
        user: row.original,
        loading: loadingUserId.value === row.original.id,
        onLiftBan: () => liftBan(row.original)
      })
    }
  },
  {
    id: 'providers',
    accessorKey: 'providers',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.linkedAccounts')),
    cell: ({ row }) => {
      return h('div', { class: 'text-xs' }, [
        h(SuperAdminUserOAuthAccounts, { oauthAccounts: row.original.providers as string[] })
      ])
    }
  },
  {
    id: 'subscriptions',
    accessorKey: 'subscriptions',
    header: t('admin.usersPage.columns.subscriptions'),
    cell: ({ row }) => {
      const subs = row.original.subscriptions
      if (!subs || subs.length === 0) {
        return h('div', { class: 'text-xs text-muted' }, '-')
      }

      return h('div', { class: 'flex flex-col gap-1' }, subs.map((sub) => {
        return h('div', { class: 'flex items-center gap-1.5 text-xs' }, [
          h(UBadge, {
            variant: 'subtle',
            color: getStatusColor(sub.status),
            size: 'sm'
          }, () => sub.status),
          h('span', { class: 'font-medium' }, sub.productName || 'N/A'),
          sub.interval ? h('span', { class: 'text-muted' }, `(${formatInterval(sub.interval, sub.intervalCount)})`) : null
        ].filter(Boolean))
      }))
    }
  },
  {
    id: 'createdAt',
    accessorKey: 'createdAt',
    header: ({ column }) => getSortedHeader(column, t('admin.usersPage.columns.created')),
    cell: ({ row }) => {
      return h('div', { class: 'text-xs' }, [
        h(NuxtTime, { datetime: row.getValue('createdAt') as string, locale: locale.value, class: 'text-xs' })
      ])
    }
  },
  {
    id: 'actions',
    header: '',
    cell: ({ row }) => {
      return h(UDropdownMenu, {
        items: actions.value,
        content: { align: 'end', side: 'bottom', sideOffset: 0 }
      }, () =>
        h(UButton, {
          icon: 'lucide:ellipsis',
          variant: 'ghost',
          color: 'neutral',
          class: 'text-neutral-500',
          onClick: () => { selectedUser.value = row.original }
        })
      )
    }
  }
]

const actions = computed(() => [
  {
    label: t('admin.usersPage.actions.sendPasswordReset'),
    onSelect: async () => {
      if (selectedUser.value) {
        await sendForgotPasswordEmail(selectedUser.value)
      }
    }
  },
  {
    label: t('admin.usersPage.actions.impersonate'),
    onSelect: async () => {
      if (selectedUser.value) {
        await startImpersonationSession(selectedUser.value)
      }
    }
  },
  {
    label: t('admin.usersPage.actions.ban'),
    onSelect: () => {
      if (selectedUser.value) {
        banUserModal.value = true
      }
    }
  },
  {
    label: t('admin.usersPage.actions.delete'),
    color: 'error' as const,
    onSelect: () => {
      if (selectedUser.value) {
        showDeleteUserConfirmation.value = true
      }
    }
  }
])
async function handleUserCreated() {
  await refresh()
  newUserModal.value = false
}

async function handleUserBanned() {
  await refresh()
  banUserModal.value = false
}

const liftBan = async (user: AdminUserRow) => {
  const { liftBanUser } = useAuth()
  await liftBanUser({ userId: user.id })
  toast.add({
    title: t('admin.usersPage.messages.unbanSuccess'),
    description: t('admin.usersPage.messages.unbanSuccessDescription'),
    color: 'success'
  })
  await refresh()
}

async function handleUserDeleted() {
  showDeleteUserConfirmation.value = false
  await refresh()
}

const sendForgotPasswordEmail = async (user: AdminUserRow) => {
  try {
    loadingUserId.value = user.id
    const { requestPasswordReset } = useAuth()
    const { error } = await requestPasswordReset({ email: user.email })

    if (error) {
      toast.add({
        title: t('admin.usersPage.messages.error'),
        description: error.message || t('admin.usersPage.messages.passwordResetError'),
        color: 'error'
      })
    } else {
      toast.add({
        title: t('admin.usersPage.messages.passwordResetSent'),
        description: t('admin.usersPage.messages.passwordResetSentDescription'),
        color: 'success'
      })
    }
  } catch {
    toast.add({
      title: t('admin.usersPage.messages.error'),
      description: t('admin.usersPage.messages.passwordResetError'),
      color: 'error'
    })
  } finally {
    loadingUserId.value = null
  }
}

const startImpersonationSession = async (user: AdminUserRow) => {
  const { impersonateUser } = useAuth()
  await impersonateUser({ userId: user.id })
  await fetchSession()
  window.location.href = '/dashboard'
}
const maskEmail = (email: string) => {
  const [localPart, domain] = email?.split('@') ?? []
  return `${localPart?.split('')
    .map(() => '•')
    .join('')}@${domain}`
}

const maskEmails = () => {
  isEmailsMasked.value = !isEmailsMasked.value
}

// Filter options
const roleOptions = computed(() => [
  { label: t('admin.usersPage.filters.role.all'), value: 'all' },
  { label: t('admin.usersPage.filters.role.admin'), value: 'admin' },
  { label: t('admin.usersPage.filters.role.user'), value: 'user' }
])

const verifiedOptions = computed(() => [
  { label: t('admin.usersPage.filters.verified.all'), value: 'all' },
  { label: t('admin.usersPage.filters.verified.verified'), value: 'verified' },
  { label: t('admin.usersPage.filters.verified.unverified'), value: 'unverified' }
])

const bannedOptions = computed(() => [
  { label: t('admin.usersPage.filters.banned.all'), value: 'all' },
  { label: t('admin.usersPage.filters.banned.banned'), value: 'banned' },
  { label: t('admin.usersPage.filters.banned.active'), value: 'active' }
])

const subscriptionOptions = computed(() => {
  const baseOptions = [
    { label: t('admin.usersPage.filters.subscription.all'), value: 'all' },
    { label: t('admin.usersPage.filters.subscription.active'), value: 'active' },
    { label: t('admin.usersPage.filters.subscription.none'), value: 'none' }
  ]

  // Group products by name and collect all IDs for each name
  const productsByName = new Map<string, string[]>()
  for (const product of products.value) {
    if (!productsByName.has(product.name)) {
      productsByName.set(product.name, [])
    }
    productsByName.get(product.name)!.push(product.id)
  }

  // Create options with comma-separated IDs for products with same name
  const productOptions = Array.from(productsByName.entries()).map(([name, ids]) => ({
    label: name,
    value: ids.join(',') // Multiple IDs separated by comma
  }))

  return [...baseOptions, ...productOptions]
})

const providerOptions = computed(() => [
  { label: t('admin.usersPage.filters.provider.all'), value: 'all' },
  { label: t('admin.usersPage.filters.provider.credential'), value: 'credential' },
  { label: t('admin.usersPage.filters.provider.github'), value: 'github' },
  { label: t('admin.usersPage.filters.provider.google'), value: 'google' }
])

const hasActiveFilters = computed(() =>
  filters.value.role !== 'all'
  || filters.value.emailVerified !== 'all'
  || filters.value.banned !== 'all'
  || filters.value.subscription !== 'all'
  || filters.value.provider !== 'all'
)

const clearFilters = () => {
  filters.value = {
    role: 'all',
    emailVerified: 'all',
    banned: 'all',
    subscription: 'all',
    provider: 'all'
  }
}

onMounted(() => {
  loading.value = false
})
</script>

<template>
  <NuxtLayout
    :page-title="t('admin.users')"
    :parent="{
      label: t('admin.title'),
      to: localePath('/dashboard/admin')
    }"
    name="dashboard"
    type="admin"
  >
    <template #actions>
      <UButton
        :title="isEmailsMasked ? t('admin.usersPage.unmaskButton') : t('admin.usersPage.maskButton')"
        :icon="isEmailsMasked ? 'lucide:eye-off' : 'lucide:eye'"
        variant="soft"
        color="neutral"
        @click="maskEmails"
      />
      <UButton
        :title="t('admin.usersPage.createButton')"
        icon="lucide:plus"
        @click="newUserModal = true"
      />
    </template>
    <UPageBody>
      <PageRefresh :on-refresh="refresh" />
      <PageMainCard
        :title="t('admin.users')"
        :description="t('admin.usersDescription')"
        :icon="useSolarIcon('users-group-rounded')"
        :loading="isLoading"
        :on-refresh="refresh"
      >
        <template #header-actions>
          <div class="text-sm text-muted">
            <span v-if="isLoading">Loading...</span>
            <span v-else-if="totalUsers > 0">
              Total: {{ totalUsers }}
            </span>
            <span v-else>No users found</span>
          </div>
        </template>
        <template #header>
          <!-- Filters -->
          <div class="flex items-center gap-2">
            <label class="text-sm font-medium text-muted">{{ t('admin.usersPage.filters.role.label') }}:</label>
            <USelect
              v-model="filters.role"
              :items="roleOptions"
              size="xs"
              class="w-32"
            />
          </div>

          <div class="flex items-center gap-2">
            <label class="text-sm font-medium text-muted">{{ t('admin.usersPage.filters.verified.label') }}:</label>
            <USelect
              v-model="filters.emailVerified"
              :items="verifiedOptions"
              size="xs"
              class="w-32"
            />
          </div>

          <div class="flex items-center gap-2">
            <label class="text-sm font-medium text-muted">{{ t('admin.usersPage.filters.banned.label') }}:</label>
            <USelect
              v-model="filters.banned"
              :items="bannedOptions"
              size="xs"
              class="w-32"
            />
          </div>

          <div class="flex items-center gap-2">
            <label class="text-sm font-medium text-muted">{{ t('admin.usersPage.filters.subscription.label') }}:</label>
            <USelect
              v-model="filters.subscription"
              :items="subscriptionOptions"
              size="xs"
              class="w-32"
            />
          </div>

          <div class="flex items-center gap-2">
            <label class="text-sm font-medium text-muted">{{ t('admin.usersPage.filters.provider.label') }}:</label>
            <USelect
              v-model="filters.provider"
              :items="providerOptions"
              size="xs"
              class="w-32"
            />
          </div>

          <UButton
            v-if="hasActiveFilters"
            :label="t('admin.usersPage.filters.clear')"
            variant="ghost"
            color="neutral"
            size="xs"
            icon="lucide:x"
            @click="clearFilters"
          />
        </template>
        <UTable
          :data="users"
          :columns="columns"
          :loading="isLoading"
          :empty="isLoading ? 'Loading...' : 'No users found'"
          class="mb-4"
          :ui="{
            th: 'px-1 py-1',
            td: 'px-1 py-1 whitespace-nowrap'
          }"
        />
        <template #footer-actions>
          <UPagination
            v-model:page="page"
            :items-per-page="pageSize"
            :total="totalUsers"
            size="xs"
          />
          <USelect
            v-model="pageSize"
            :items="[
              { label: '10', value: 10 },
              { label: '20', value: 20 },
              { label: '50', value: 50 },
              { label: '100', value: 100 }
            ]"
            size="xs"
          />
        </template>
      </PageMainCard>
    </UPageBody>

    <!-- Modals -->
    <UModal
      v-model:open="newUserModal"
      :title="t('admin.usersPage.modals.createUser.title')"
      :description="t('admin.usersPage.modals.createUser.description')"
    >
      <template #body>
        <SuperAdminNewUserForm @user-created="handleUserCreated" />
      </template>
    </UModal>
    <UModal
      v-model:open="banUserModal"
      :title="t('admin.usersPage.modals.banUser.title')"
      :description="t('admin.usersPage.modals.banUser.description')"
    >
      <template #body>
        <SuperAdminBanUserForm
          v-if="selectedUser"
          :user="(selectedUser as any)"
          @user-banned="handleUserBanned"
        />
      </template>
    </UModal>

    <UModal
      v-model:open="showDeleteUserConfirmation"
      :title="t('admin.usersPage.modals.deleteUser.title')"
      :description="t('admin.usersPage.modals.deleteUser.description')"
    >
      <template #body>
        <SuperAdminDeleteUserForm
          v-if="selectedUser"
          :user="(selectedUser as any)"
          :users="(users as any)"
          @user-deleted="handleUserDeleted"
          @cancel="showDeleteUserConfirmation = false"
        />
      </template>
    </UModal>
  </NuxtLayout>
  <PageStatus />
  <NotificationsSlideover />
</template>
