'use client'

import { useState } from 'react'
import { FieldLabel, FormTooltip, PrimaryButton, SelectField, TextField } from '@/app/FormFields'
import { normalizeSupportedLanguage, USER_LANGUAGE_OPTIONS, type SupportedLanguage } from '@/lib/user-language'

type User = {
  id: string
  email: string
  displayName: string | null
  role: 'line_manager' | 'expert' | 'admin'
  isActive: boolean
  authProvider: string
  preferredLanguage: SupportedLanguage
  lastLoginAt: string | null
  createdAt: string
}

type UsersLabels = {
  inviteTitle: string
  email: string
  role: string
  language: string
  addUser: string
  adding: string
  failedInvite: string
  inviteSuccess: string
  activeMembers: string
  countFiltered: string
  filterPlaceholder: string
  disabled: string
  none: string
  member: string
  lastLogin: string
  actions: string
  you: string
  never: string
  disable: string
  reEnable: string
  actionFailed: string
  roleHelp: string
  activeHelp: string
  roles: Record<User['role'], string>
}

const DEFAULT_LABELS: UsersLabels = {
  inviteTitle: 'Invite a new member',
  email: 'Email',
  role: 'Role',
  language: 'Language',
  addUser: 'Add user',
  adding: 'Adding...',
  failedInvite: 'Failed to invite user',
  inviteSuccess: '{email} can now sign in. They have been sent an invite to their email.',
  activeMembers: 'Active members',
  countFiltered: '{filtered} of {total}',
  filterPlaceholder: 'Filter by name or email',
  disabled: 'Disabled',
  none: 'None',
  member: 'Member',
  lastLogin: 'Last login',
  actions: 'Actions',
  you: 'you',
  never: 'Never',
  disable: 'Disable',
  reEnable: 'Re-enable',
  actionFailed: 'Action failed',
  roleHelp: 'Line managers can submit and track their own tickets. Experts can review tickets and manage knowledge/projects. Admins can also manage users and tenant configuration.',
  activeHelp: 'Disabling a member blocks access for this tenant without deleting their user record or historical ticket activity.',
  roles: {
    line_manager: 'Line manager',
    expert: 'Expert',
    admin: 'Admin',
  },
}

function formatLabel(template: string, replacements: Record<string, string | number>) {
  return Object.entries(replacements).reduce(
    (text, [key, value]) => text.replaceAll(`{${key}}`, String(value)),
    template,
  )
}

function formatDate(iso: string | null) {
  if (!iso) return 'Never'
  return new Intl.DateTimeFormat('en', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  }).format(new Date(iso))
}

function splitDisplayName(displayName: string | null) {
  const parts = displayName?.trim().split(/\s+/).filter(Boolean) ?? []
  return {
    firstName: parts[0] ?? '',
    lastName: parts.slice(1).join(' '),
  }
}

function activeMemberMatchesSearch(user: User, search: string) {
  const query = search.trim().toLowerCase()
  if (!query) return true

  const { firstName, lastName } = splitDisplayName(user.displayName)
  return [user.email, firstName, lastName].some((value) =>
    value.toLowerCase().startsWith(query),
  )
}

export default function UsersClient({
  initialUsers,
  currentUserId,
  labels = DEFAULT_LABELS,
}: {
  initialUsers: User[]
  currentUserId: string
  labels?: UsersLabels
}) {
  const [userList, setUserList] = useState<User[]>(initialUsers)
  const [inviteEmail, setInviteEmail] = useState('')
  const [inviteRole, setInviteRole] = useState<User['role']>('line_manager')
  const [inviteLanguage, setInviteLanguage] = useState<SupportedLanguage>('en')
  const [inviting, setInviting] = useState(false)
  const [inviteError, setInviteError] = useState<string | null>(null)
  const [inviteSuccess, setInviteSuccess] = useState<string | null>(null)
  const [actionError, setActionError] = useState<string | null>(null)
  const [activeSearch, setActiveSearch] = useState('')

  async function handleInvite(e: React.FormEvent) {
    e.preventDefault()
    if (!inviteEmail.trim()) return
    setInviting(true)
    setInviteError(null)
    setInviteSuccess(null)

    const res = await fetch('/api/admin/users', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email: inviteEmail.trim(), role: inviteRole, preferredLanguage: inviteLanguage }),
    })

    const data = await res.json().catch(() => ({}))

    if (!res.ok) {
      setInviteError(data.error ?? labels.failedInvite)
      setInviting(false)
      return
    }

    setInviteSuccess(formatLabel(labels.inviteSuccess, { email: inviteEmail.trim() }))
    setInviteEmail('')
    setInviteLanguage('en')
    // Refresh the list
    const listRes = await fetch('/api/admin/users')
    if (listRes.ok) {
      const updated = await listRes.json()
      setUserList(updated)
    }
    setInviting(false)
  }

  async function handlePatch(userId: string, patch: { role?: User['role']; isActive?: boolean }) {
    setActionError(null)
    const res = await fetch(`/api/admin/users/${userId}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(patch),
    })
    const data = await res.json().catch(() => ({}))
    if (!res.ok) {
      setActionError(data.error ?? labels.actionFailed)
      return
    }
    setUserList((prev) =>
      prev.map((u) => (u.id === userId ? { ...u, ...patch } : u)),
    )
  }

  const active = userList.filter((u) => u.isActive)
  const filteredActive = active.filter((u) => activeMemberMatchesSearch(u, activeSearch))
  const disabled = userList.filter((u) => !u.isActive)
  const activeCountLabel = activeSearch.trim()
    ? `${filteredActive.length} of ${active.length}`
    : active.length.toString()

  return (
    <div className="space-y-8">
      {/* Invite form */}
      <section className="rounded-lg border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-900">
        <h2 className="mb-4 text-sm font-semibold text-zinc-950 dark:text-white">{labels.inviteTitle}</h2>
        <form onSubmit={handleInvite} className="flex flex-wrap items-end gap-2">
          <div className="min-w-0 flex-1">
            <FieldLabel htmlFor="inviteEmail" className="sr-only">{labels.email}</FieldLabel>
            <TextField
              id="inviteEmail"
              type="email"
              value={inviteEmail}
              onChange={(e) => setInviteEmail(e.target.value)}
              placeholder="name@example.com"
              required
            />
          </div>
          <div>
            <FieldLabel htmlFor="inviteRole" className="sr-only">{labels.role}</FieldLabel>
            <SelectField
              id="inviteRole"
              value={inviteRole}
              onChange={(e) => setInviteRole(e.target.value as User['role'])}
              className="w-auto min-w-40"
              aria-describedby="invite-role-help"
            >
              <option value="line_manager">{labels.roles.line_manager}</option>
              <option value="expert">{labels.roles.expert}</option>
              <option value="admin">{labels.roles.admin}</option>
            </SelectField>
          </div>
          <FormTooltip id="invite-role-help" text={labels.roleHelp} className="self-center" />
          <div>
            <FieldLabel htmlFor="inviteLanguage" className="sr-only">{labels.language}</FieldLabel>
            <SelectField
              id="inviteLanguage"
              value={inviteLanguage}
              onChange={(e) => setInviteLanguage(normalizeSupportedLanguage(e.target.value))}
              className="w-auto min-w-32"
            >
              {USER_LANGUAGE_OPTIONS.map((option) => (
                <option key={option.value} value={option.value}>{option.label}</option>
              ))}
            </SelectField>
          </div>
          <PrimaryButton
            type="submit"
            disabled={inviting || !inviteEmail.trim()}
          >
            {inviting ? labels.adding : labels.addUser}
          </PrimaryButton>
        </form>
        {inviteError && <p className="mt-2 text-sm text-red-700 dark:text-red-300">{inviteError}</p>}
        {inviteSuccess && <p className="mt-2 text-sm text-emerald-700 dark:text-emerald-300">{inviteSuccess}</p>}
      </section>

      {actionError && (
        <p className="text-sm text-red-700 dark:text-red-300">{actionError}</p>
      )}

      {/* Active users table */}
      <section>
        <div className="mb-3 flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
          <h2 className="text-sm font-semibold text-zinc-950 dark:text-white">
            Active members <span className="font-normal text-zinc-500">({activeCountLabel})</span>
          </h2>
          <div className="w-full sm:w-80">
            <label htmlFor="active-member-search" className="sr-only">
              Search active members
            </label>
            <TextField
              id="active-member-search"
              type="search"
              value={activeSearch}
              onChange={(e) => setActiveSearch(e.target.value)}
              placeholder="Search active members"
              className="h-10"
            />
          </div>
        </div>
        <UserTable
          rows={filteredActive}
          currentUserId={currentUserId}
          onPatch={handlePatch}
          showDisable
          labels={labels}
        />
      </section>

      {/* Disabled users */}
      {disabled.length > 0 && (
        <section>
          <h2 className="mb-3 text-sm font-semibold text-zinc-500 dark:text-zinc-400">
            {labels.disabled} <span className="font-normal">({disabled.length})</span>
          </h2>
          <UserTable
            rows={disabled}
            currentUserId={currentUserId}
            onPatch={handlePatch}
            showDisable={false}
            labels={labels}
          />
        </section>
      )}
    </div>
  )
}

function UserTable({
  rows,
  currentUserId,
  onPatch,
  showDisable,
  labels,
}: {
  rows: User[]
  currentUserId: string
  onPatch: (userId: string, patch: { role?: User['role']; isActive?: boolean }) => void
  showDisable: boolean
  labels: UsersLabels
}) {
  if (rows.length === 0) {
    return (
      <div className="rounded-lg border border-zinc-200 bg-white px-6 py-10 text-center text-sm text-zinc-500 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-400">
        {labels.none}
      </div>
    )
  }

  return (
    <div className="overflow-hidden rounded-lg border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-zinc-200 bg-zinc-50 text-left dark:border-zinc-800 dark:bg-zinc-800/50">
            <th className="px-4 py-3 font-medium text-zinc-700 dark:text-zinc-300">{labels.member}</th>
            <th className="px-4 py-3 font-medium text-zinc-700 dark:text-zinc-300">
              <span className="inline-flex items-center gap-2">
                {labels.role}
                <FormTooltip id={`role-help-${showDisable ? 'active' : 'disabled'}`} text={labels.roleHelp} />
              </span>
            </th>
            <th className="hidden px-4 py-3 font-medium text-zinc-700 sm:table-cell dark:text-zinc-300">{labels.lastLogin}</th>
            <th className="px-4 py-3">
              <span className="sr-only">{labels.actions}</span>
              <FormTooltip id={`member-actions-help-${showDisable ? 'active' : 'disabled'}`} text={labels.activeHelp} />
            </th>
          </tr>
        </thead>
        <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
          {rows.map((user) => {
            const isSelf = user.id === currentUserId
            return (
              <tr key={user.id} className="hover:bg-zinc-50 dark:hover:bg-zinc-800/50">
                <td className="px-4 py-3">
                  <p className="font-medium text-zinc-950 dark:text-zinc-50">
                    {user.displayName ?? user.email}
                    {isSelf && (
                      <span className="ml-2 rounded-full bg-zinc-100 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
                        {labels.you}
                      </span>
                    )}
                  </p>
                  {user.displayName && (
                    <p className="text-xs text-zinc-500 dark:text-zinc-400">{user.email}</p>
                  )}
                </td>
                <td className="px-4 py-3">
                  {isSelf ? (
                    <span className="text-zinc-700 dark:text-zinc-300">{labels.roles[user.role]}</span>
                  ) : (
                    <SelectField
                      value={user.role}
                      onChange={(e) => onPatch(user.id, { role: e.target.value as User['role'] })}
                      className="h-9 w-auto px-3 text-sm"
                      aria-describedby={`role-help-${showDisable ? 'active' : 'disabled'}`}
                    >
                      <option value="line_manager">{labels.roles.line_manager}</option>
                      <option value="expert">{labels.roles.expert}</option>
                      <option value="admin">{labels.roles.admin}</option>
                    </SelectField>
                  )}
                </td>
                <td className="hidden px-4 py-3 text-zinc-500 sm:table-cell dark:text-zinc-400">
                  {user.lastLoginAt ? formatDate(user.lastLoginAt) : labels.never}
                </td>
                <td className="px-4 py-3 text-right">
                  {!isSelf && showDisable && (
                    <button
                      onClick={() => onPatch(user.id, { isActive: false })}
                      className="text-xs text-red-600 hover:underline dark:text-red-400"
                    >
                      {labels.disable}
                    </button>
                  )}
                  {!isSelf && !showDisable && (
                    <button
                      onClick={() => onPatch(user.id, { isActive: true })}
                      className="text-xs text-sky-700 hover:underline dark:text-sky-400"
                    >
                      {labels.reEnable}
                    </button>
                  )}
                </td>
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}
