// Danh bạ nội bộ (Internal Directory) — Phase 10.2 G-O1 (S34 2026-05-27).
// Card grid responsive, filter search + department, avatar fallback gradient theo
// userId hash stable. File này MIRROR SHA256 identical với fe-admin counterpart.
// Reuse BE GET /api/directory readonly (DirectoryFeatures.cs).
import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useSearchParams } from 'react-router-dom'
import { Mail, Phone, Search, UserCircle2, Users } from 'lucide-react'
import { PageHeader } from '@/components/PageHeader'
import { EmptyState } from '@/components/EmptyState'
import { Input } from '@/components/ui/Input'
import { Select } from '@/components/ui/Select'
import { api } from '@/lib/api'
import { cn } from '@/lib/cn'
import type { Paged, Department } from '@/types/master'
import type { DirectoryItem } from '@/types/directory'

// Pattern 14 Tailwind JIT palette 6 màu gradient cho initials avatar.
const AVATAR_PALETTE = [
  'bg-gradient-to-br from-blue-400 to-blue-600',
  'bg-gradient-to-br from-emerald-400 to-emerald-600',
  'bg-gradient-to-br from-amber-400 to-amber-600',
  'bg-gradient-to-br from-violet-400 to-violet-600',
  'bg-gradient-to-br from-rose-400 to-rose-600',
  'bg-gradient-to-br from-cyan-400 to-cyan-600',
] as const

// Format SĐT Vietnam 10 chữ số: 0XXX XXX XXX
function formatPhone(p: string | null): string {
  if (!p) return ''
  const digits = p.replace(/\D/g, '')
  if (digits.length === 10) return digits.replace(/(\d{4})(\d{3})(\d{3})/, '$1 $2 $3')
  if (digits.length === 11) return digits.replace(/(\d{4})(\d{3})(\d{4})/, '$1 $2 $3')
  return p
}

// Hash stable userId → palette index (charCodeAt sum mod 6).
function avatarColor(userId: string): string {
  let sum = 0
  for (let i = 0; i < userId.length; i++) sum += userId.charCodeAt(i)
  return AVATAR_PALETTE[sum % AVATAR_PALETTE.length]
}

// First letter của FullName (uppercase, fallback "?").
function initials(fullName: string): string {
  const trimmed = fullName.trim()
  if (!trimmed) return '?'
  return trimmed.charAt(0).toUpperCase()
}

export function InternalDirectoryPage() {
  const [sp, setSp] = useSearchParams()
  const search = sp.get('q') ?? ''
  const departmentId = sp.get('deptId') ?? ''

  const [localSearch, setLocalSearch] = useState(search)

  const departments = useQuery({
    queryKey: ['departments-all-directory'],
    queryFn: async () =>
      (await api.get<Paged<Department>>('/departments', { params: { page: 1, pageSize: 200 } })).data.items,
  })

  const list = useQuery({
    queryKey: ['directory', { search, departmentId }],
    queryFn: async () => {
      const res = await api.get<DirectoryItem[]>('/directory', {
        params: {
          search: search || undefined,
          departmentId: departmentId || undefined,
        },
      })
      return res.data
    },
  })

  function setParam(key: string, value: string | null) {
    const next = new URLSearchParams(sp)
    if (value == null || value === '') next.delete(key)
    else next.set(key, value)
    setSp(next, { replace: true })
  }

  function applySearch(e: React.FormEvent) {
    e.preventDefault()
    setParam('q', localSearch.trim() || null)
  }

  const total = list.data?.length ?? 0

  return (
    <div className="p-6">
      <PageHeader
        title="Danh bạ nội bộ"
        description={list.isLoading ? 'Đang tải...' : `${total} nhân viên`}
      />

      {/* Filter bar sticky top */}
      <div className="sticky top-0 z-10 mb-4 flex flex-col gap-2 rounded-lg border border-slate-200 bg-white/95 p-3 shadow-sm backdrop-blur sm:flex-row sm:items-center">
        <form onSubmit={applySearch} className="relative flex-1">
          <Search className="pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-slate-400" />
          <Input
            value={localSearch}
            onChange={e => setLocalSearch(e.target.value)}
            onBlur={() => setParam('q', localSearch.trim() || null)}
            placeholder="Tìm tên / email / SĐT / mã NV..."
            className="pl-8"
          />
        </form>
        <Select
          value={departmentId}
          onChange={e => setParam('deptId', e.target.value || null)}
          className="sm:w-64"
        >
          <option value="">Tất cả phòng ban</option>
          {(departments.data ?? []).map(d => (
            <option key={d.id} value={d.id}>{d.name}</option>
          ))}
        </Select>
      </div>

      {/* Card grid */}
      {list.isLoading ? (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {Array.from({ length: 8 }).map((_, i) => (
            <div key={i} className="h-44 animate-pulse rounded-lg border border-slate-200 bg-slate-100" />
          ))}
        </div>
      ) : total === 0 ? (
        <EmptyState
          icon={Users}
          title="Không tìm thấy nhân viên nào"
          description="Thử đổi từ khoá tìm hoặc chọn phòng ban khác."
        />
      ) : (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {list.data!.map(item => (
            <DirectoryCard key={item.userId} item={item} />
          ))}
        </div>
      )}
    </div>
  )
}

function DirectoryCard({ item }: { item: DirectoryItem }) {
  return (
    <div className="rounded-lg border border-slate-200 bg-white p-4 shadow-sm transition hover:shadow-md">
      {/* Top row: avatar + name + code */}
      <div className="flex items-start gap-3">
        {item.photoUrl ? (
          <img
            src={item.photoUrl}
            alt={item.fullName}
            className="h-14 w-14 shrink-0 rounded-full object-cover ring-2 ring-white shadow"
          />
        ) : (
          <div
            className={cn(
              'flex h-14 w-14 shrink-0 items-center justify-center rounded-full text-xl font-bold text-white shadow ring-2 ring-white',
              avatarColor(item.userId),
            )}
          >
            {initials(item.fullName)}
          </div>
        )}
        <div className="min-w-0 flex-1">
          <div className="flex items-baseline gap-1.5">
            <h3 className="truncate text-sm font-semibold text-slate-900" title={item.fullName}>
              {item.fullName}
            </h3>
            {item.employeeCode && (
              <span className="shrink-0 rounded bg-slate-100 px-1.5 py-0.5 font-mono text-[10px] text-slate-600">
                {item.employeeCode}
              </span>
            )}
          </div>
          {item.position && (
            <p className="mt-0.5 truncate text-xs text-slate-600" title={item.position}>
              {item.position}
            </p>
          )}
          {item.departmentName && (
            <span className="mt-1 inline-flex rounded bg-emerald-100 px-2 py-0.5 text-[11px] font-medium text-emerald-900">
              {item.departmentName}
            </span>
          )}
        </div>
      </div>

      {/* Contact rows */}
      <div className="mt-3 space-y-1.5 border-t border-slate-100 pt-3 text-xs">
        {item.email ? (
          <a
            href={`mailto:${item.email}`}
            className="flex items-center gap-1.5 text-slate-700 hover:text-brand-700 hover:underline"
            title={item.email}
          >
            <Mail className="h-3.5 w-3.5 shrink-0 text-slate-400" />
            <span className="truncate">{item.email}</span>
          </a>
        ) : (
          <div className="flex items-center gap-1.5 text-slate-400">
            <Mail className="h-3.5 w-3.5 shrink-0" />
            <span>—</span>
          </div>
        )}

        {item.phone ? (
          <a
            href={`tel:${item.phone}`}
            className="flex items-center gap-1.5 text-slate-700 hover:text-brand-700 hover:underline"
            title={item.phone}
          >
            <Phone className="h-3.5 w-3.5 shrink-0 text-slate-400" />
            <span className="truncate">{formatPhone(item.phone)}</span>
          </a>
        ) : (
          <div className="flex items-center gap-1.5 text-slate-400">
            <Phone className="h-3.5 w-3.5 shrink-0" />
            <span>—</span>
          </div>
        )}

        {item.internalPhone && (
          <div className="flex items-center gap-1.5">
            <UserCircle2 className="h-3.5 w-3.5 shrink-0 text-slate-400" />
            <span className="inline-flex rounded bg-amber-100 px-1.5 py-0.5 font-mono text-[10px] font-medium text-amber-900">
              Ext: {item.internalPhone}
            </span>
          </div>
        )}
      </div>
    </div>
  )
}
