'use client'

import { useState } from 'react'

import { useI18n } from '@/components/providers/i18n-provider'
import { Button, Notice, Select } from '@/components/ui/controls'
import { DataTable, type Column } from '@/components/ui/data-table'
import { Badge } from '@/components/ui/display'
import { ApiClientError, api, failureMessage } from '@/lib/api/client'

export interface UserRow {
  id: string
  email: string
  name: string
  nameAr: string
  employeeId: string
  department: string
  departmentAr: string
  roleKey: string
  isActive: boolean
  lastLoginAt: number | null
}

/**
 * User administration (§33).
 *
 * Role changes go through the API, which revokes the user's live sessions — a demotion
 * that only takes effect at the next sign-in is not a demotion.
 */
export function UsersTable({
  rows,
  roles,
  canManage,
  currentUserId,
}: {
  rows: UserRow[]
  roles: Array<{ key: string; name: string; nameAr: string }>
  canManage: boolean
  currentUserId: string
}) {
  const { t, locale, relative } = useI18n()
  const [users, setUsers] = useState(rows)
  const [busyId, setBusyId] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [message, setMessage] = useState<string | null>(null)

  const update = async (id: string, payload: Record<string, unknown>, successKey: string) => {
    setBusyId(id)
    setError(null)
    setMessage(null)
    try {
      const updated = await api.patch<{ id: string; isActive: boolean; roles: string[] }>(
        `/api/users/${id}`,
        payload,
      )
      setUsers((current) =>
        current.map((user) =>
          user.id === updated.id
            ? { ...user, isActive: updated.isActive, roleKey: updated.roles[0] ?? user.roleKey }
            : user,
        ),
      )
      setMessage(t(successKey))
    } catch (caught) {
      setError(
        caught instanceof ApiClientError
          ? failureMessage(caught.failure, locale)
          : t('common.serverError'),
      )
    } finally {
      setBusyId(null)
    }
  }

  const columns: Array<Column<UserRow>> = [
    {
      key: 'name',
      header: t('users.columns.name'),
      sortValue: (row) => (locale === 'ar' ? row.nameAr : row.name),
      cell: (row) => (
        <div className="min-w-0">
          <p className="truncate text-text">{locale === 'ar' ? row.nameAr : row.name}</p>
          <p className="truncate font-mono text-[11px] text-text-faint">{row.email}</p>
        </div>
      ),
    },
    {
      key: 'employeeId',
      header: t('users.columns.employeeId'),
      secondary: true,
      sortValue: (row) => row.employeeId,
      cell: (row) => <span className="font-mono text-[11px] text-text-muted">{row.employeeId}</span>,
    },
    {
      key: 'department',
      header: t('users.columns.department'),
      secondary: true,
      sortValue: (row) => row.department,
      cell: (row) => (
        <span className="text-text-muted">
          {locale === 'ar' ? row.departmentAr : row.department}
        </span>
      ),
    },
    {
      key: 'role',
      header: t('users.columns.roles'),
      sortValue: (row) => row.roleKey,
      cell: (row) =>
        canManage ? (
          <Select
            aria-label={t('users.changeRole')}
            value={row.roleKey}
            disabled={busyId === row.id}
            onChange={(event) =>
              update(row.id, { roleKey: event.target.value }, 'users.roleChanged')
            }
            className="w-auto min-w-40"
          >
            {roles.map((role) => (
              <option key={role.key} value={role.key}>
                {locale === 'ar' ? role.nameAr : role.name}
              </option>
            ))}
          </Select>
        ) : (
          <Badge tone="muted">{t(`role.${row.roleKey}`)}</Badge>
        ),
    },
    {
      key: 'status',
      header: t('users.columns.status'),
      align: 'end',
      sortValue: (row) => (row.isActive ? 1 : 0),
      cell: (row) => (
        <Badge tone={row.isActive ? 'brand' : 'muted'}>
          {row.isActive ? t('users.active') : t('users.inactive')}
        </Badge>
      ),
    },
    {
      key: 'lastLogin',
      header: t('users.columns.lastLogin'),
      align: 'end',
      secondary: true,
      sortValue: (row) => row.lastLoginAt ?? 0,
      cell: (row) => (
        <span className="text-[11px] text-text-faint">
          {row.lastLoginAt ? relative(row.lastLoginAt) : t('users.never')}
        </span>
      ),
    },
    {
      key: 'actions',
      header: t('common.actions'),
      align: 'end',
      cell: (row) =>
        canManage ? (
          <Button
            size="sm"
            variant={row.isActive ? 'ghost' : 'secondary'}
            loading={busyId === row.id}
            disabled={row.id === currentUserId}
            title={row.id === currentUserId ? t('common.na') : undefined}
            onClick={() => update(row.id, { isActive: !row.isActive }, 'users.statusChanged')}
          >
            {row.isActive ? t('users.deactivate') : t('users.activate')}
          </Button>
        ) : null,
    },
  ]

  return (
    <div className="space-y-3">
      {error ? <Notice tone="danger">{error}</Notice> : null}
      {message ? <Notice tone="success">{message}</Notice> : null}

      <DataTable
        rows={users}
        columns={columns}
        getRowKey={(row) => row.id}
        searchable={(row) => `${row.name} ${row.nameAr} ${row.email} ${row.employeeId}`}
        initialSort={{ key: 'role', direction: 'asc' }}
        caption={t('users.title')}
        emptyTitle={t('users.empty')}
      />
    </div>
  )
}
