'use client'


import { useTranslation } from '../../../../i18n/useTranslation';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { MagnifyingGlassIcon, XMarkIcon, BuildingOffice2Icon, UserIcon } from '@heroicons/react/24/outline'
import { getUserCandidates } from '../hooks/search-candidate'
import { addUserToMatrix } from '../hooks/addUsertoMatrix'
import type { MatrixUser, UserType } from '../hooks/getStats'

type Props = {
  open: boolean
  onClose: () => void
  matrixName: string
  rootUserId?: number
  matrixId?: string | number
  topNodeEmail?: string
  existingUsers: MatrixUser[]
  onAdd: (u: { id: number; name: string; email: string; type: UserType }) => void
  policyMaxDepth?: number | null // NEW
}

export default function SearchModal({
  open,
  onClose,
  matrixName,
  rootUserId,
  matrixId,
  topNodeEmail,
  existingUsers,
  onAdd,
  policyMaxDepth // NEW
}: Props) {
  const { t } = useTranslation();
  const [query, setQuery] = useState('')
  const [typeFilter, setTypeFilter] = useState<'all' | UserType>('all')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string>('')
  const [items, setItems] = useState<Array<{ userId: number; name: string; email: string; userType: UserType }>>([])
  const [total, setTotal] = useState(0)
  const [limit] = useState(20)

  const [selected, setSelected] = useState<{ userId: number; name: string; email: string; userType: UserType } | null>(null) // NEW
  const [advanced, setAdvanced] = useState(false) // NEW
  const [parentId, setParentId] = useState<number | undefined>(undefined) // NEW
  const [forceFallback, setForceFallback] = useState<boolean>(true) // NEW
  const [adding, setAdding] = useState(false) // NEW
  const [addError, setAddError] = useState<string>('') // NEW
  const [addSuccess, setAddSuccess] = useState<string>('') // NEW
  const [hasSearched, setHasSearched] = useState(false) // NEW
  const [closing, setClosing] = useState(false) // NEW: animated closing state

  const formRef = useRef<HTMLFormElement | null>(null)
  const reqIdRef = useRef(0) // request guard to avoid applying stale results

  const doSearch = useCallback(async () => {
    setError('')
    // Preserve list during refresh to avoid jumpiness
    const shouldPreserve = hasSearched && items.length > 0
    if (!shouldPreserve) {
      setItems([])
      setTotal(0)
    }
    const qTrim = query.trim()
    if (qTrim.length < 3) {
      console.warn('[SearchModal] Skip search: need >=3 chars')
      setHasSearched(false)
      return
    }
    setHasSearched(true)

    const myReqId = ++reqIdRef.current
    try {
      setLoading(true)
      const data = await getUserCandidates({
        q: qTrim,
        type: typeFilter === 'all' ? undefined : typeFilter,
        rootUserId,
        matrixId,
        topNodeEmail,
        limit,
        offset: 0
      })
      // Ignore stale responses
      if (myReqId !== reqIdRef.current) return

      const existingIds = new Set(existingUsers.map(u => String(u.id)))
      const filtered = (data.items || []).filter(i => !existingIds.has(String(i.userId)))
      setItems(filtered)
      setTotal(data.total || 0)
      console.info('[SearchModal] Search success', {
        q: data.q,
        returned: filtered.length,
        original: data.items.length,
        total: data.total,
        combo: (data as any)?._debug?.combo
      })
      if (filtered.length === 0 && data.total > 0) {
        console.warn('[SearchModal] All backend results filtered out as duplicates')
      }
    } catch (e: any) {
      if (myReqId !== reqIdRef.current) return
      console.error('[SearchModal] Search error', e)
      setError(e?.message || 'Search failed')
    } finally {
      if (myReqId === reqIdRef.current) setLoading(false)
    }
  }, [query, typeFilter, rootUserId, matrixId, topNodeEmail, limit, existingUsers, hasSearched, items])

  useEffect(() => {
    if (!open) {
      setQuery('')
      setTypeFilter('all')
      setItems([])
      setTotal(0)
      setError('')
      setLoading(false)
      setHasSearched(false)
      reqIdRef.current = 0 // reset guard
    }
  }, [open])

  useEffect(() => {
    if (!open) return
    const prev = document.body.style.overflow
    document.body.style.overflow = 'hidden'
    return () => { document.body.style.overflow = prev }
  }, [open])

  // Auto-prune current results when parent existingUsers changes (keeps modal open)
  useEffect(() => {
    if (!open || items.length === 0) return
    const existingIds = new Set(existingUsers.map(u => String(u.id)))
    const cleaned = items.filter(i => !existingIds.has(String(i.userId)))
    if (cleaned.length !== items.length) {
      console.info('[SearchModal] Pruned results after parent update', { before: items.length, after: cleaned.length })
      setItems(cleaned)
    }
  }, [existingUsers, items, open])

  // Track a revision to force remount of parent dropdown when existingUsers changes
  const [parentsRevision, setParentsRevision] = useState(0) // NEW

  // Compute children counts per parent (uses parentUserId on existingUsers)
  const parentUsage = useMemo(() => {
    const map = new Map<number, number>()
    existingUsers.forEach(u => {
      if (u.parentUserId != null) {
        map.set(u.parentUserId, (map.get(u.parentUserId) || 0) + 1)
      }
    })
    return map
  }, [existingUsers])

  const potentialParents = useMemo(() => {
    // All users up to depth 5 can be parents (capacity 5)
    return existingUsers
      .filter(u => u.level < 6)
      .sort((a, b) => a.level - b.level || a.id - b.id)
  }, [existingUsers])

  const selectedParent = useMemo(() => {
    if (!parentId) return null
    return existingUsers.find(u => u.id === parentId) || null
  }, [parentId, existingUsers])

  // NEW: when existingUsers changes, refresh dropdown and clear invalid/now-full parent selection
  useEffect(() => {
    setParentsRevision(r => r + 1)
    if (!selectedParent) return
    const used = parentUsage.get(selectedParent.id) || 0
    const isRoot = (selectedParent.level ?? 0) === 0
    const isFull = !isRoot && used >= 5
    const stillExists = !!existingUsers.find(u => u.id === selectedParent.id)
    if (!stillExists || isFull) {
      setParentId(undefined)
    }
  }, [existingUsers, parentUsage, selectedParent])

  const remainingLevels = useMemo(() => {
    if (!selectedParent) return null
    if (!policyMaxDepth || policyMaxDepth <= 0) return Infinity
    return Math.max(0, policyMaxDepth - Number(selectedParent.level ?? 0))
  }, [selectedParent, policyMaxDepth])

  const addDisabledReason = useMemo(() => {
    if (!selectedParent) return ''
    if (!policyMaxDepth || policyMaxDepth <= 0) return ''
    if (Number(selectedParent.level ?? 0) >= policyMaxDepth) {
      return `Parent at max depth (${policyMaxDepth}).`
    }
    return ''
  }, [selectedParent, policyMaxDepth])

  // Helper: is root selected
  const isRootSelected = useMemo(() => {
    if (!selectedParent) return false
    return (selectedParent.level ?? 0) === 0
  }, [selectedParent])

  const closeWithAnimation = useCallback(() => {
    // guard: if already closing, ignore
    if (closing) return
    setClosing(true)
    // allow CSS transitions to play
    setTimeout(() => {
      setClosing(false)
      onClose()
    }, 200) // keep brief for responsiveness
  }, [closing, onClose])

  useEffect(() => {
    // reset closing flag when reopened
    if (open) setClosing(false)
  }, [open])

  const handleAdd = async () => {
    if (!selected) return
    setAddError('')
    setAddSuccess('')
    setAdding(true)
    try {
      // If advanced is not checked, or if advanced is checked but parentId is not set (root selected), use rootUserId as parentUserId
      const effectiveParentId = (!advanced || !parentId) ? rootUserId : parentId;
      const data = await addUserToMatrix({
        childUserId: selected.userId,
        parentUserId: effectiveParentId,
        forceParentFallback: forceFallback,
        rootUserId,
        matrixId,
        topNodeEmail
      })
      console.info('[SearchModal] addUserToMatrix success', data)
      setAddSuccess(`Added at position ${data.position} under parent ${data.parentUserId}`)
      onAdd({ id: selected.userId, name: selected.name, email: selected.email, type: selected.userType })
      // NEW: animated close instead of abrupt onClose
      closeWithAnimation()
      return
      // setSelected(null)
      // setParentId(undefined)
      // Soft refresh: keep list visible; doSearch won't clear items now
      // setTimeout(() => { void doSearch() }, 200)
    } catch (e: any) {
      console.error('[SearchModal] addUserToMatrix error', e)
      setAddError(e?.message || 'Add failed')
    } finally {
      setAdding(false)
    }
  }

  if (!open) return null

  const modal = (
    <div className="fixed inset-0 z-[10000]">
      {/* Backdrop: animate opacity */}
      <div
        className={`absolute inset-0 backdrop-blur-sm transition-opacity duration-200 ${closing ? 'opacity-0' : 'opacity-100'} bg-black/60`}
        onClick={closeWithAnimation} // CHANGED: use animated close
      />
      <div className="absolute inset-0 flex items-center justify-center p-4 sm:p-6">
        <div
          className={`w-full max-w-full sm:max-w-xl md:max-w-3xl lg:max-w-4xl rounded-2xl overflow-hidden bg-[#0F1F3A] shadow-2xl ring-1 ring-black/40 flex flex-col
            transition-all duration-200 ${closing ? 'opacity-0 scale-95 translate-y-1' : 'opacity-100 scale-100 translate-y-0'}`}
          style={{ maxHeight: '90vh' }}
        >
          {/* Header */}
          <div className="relative px-6 py-5 border-b border-blue-900/40 bg-gradient-to-r from-[#142b52] via-[#13365f] to-[#154270]">
            <div className="flex items-center justify-between">
              <h3 className="text-lg font-semibold text-white">
                Add users to “{matrixName}”
              </h3>
              <button
                onClick={closeWithAnimation} // CHANGED: animated close
                className="p-1.5 rounded-md text-blue-200 transition
                  hover:bg-white/15 hover:text-white
                  focus:outline-none focus:ring-2 focus:ring-white/60 focus:ring-offset-2 focus:ring-offset-[#13365f]
                  active:scale-95"
                aria-label="Close"
              >
                <XMarkIcon className="h-5 w-5" />
              </button>
            </div>
            <p className="mt-1 text-xs text-blue-200">{t('autofix.kd642e230')}</p>
          </div>

          {/* Form */}
          <form
            ref={formRef}
            onSubmit={e => {
              e.preventDefault()
              void doSearch()
            }}
            className="px-6 py-4 grid grid-cols-1 md:grid-cols-5 gap-3 border-b border-blue-900/40 bg-[#112645]"
          >
            {/* Query */}
            <div className="md:col-span-2">
              <div className="relative">
                <MagnifyingGlassIcon className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-blue-300" />
                <input
                  value={query}
                  onChange={e => setQuery(e.target.value)}
                  placeholder={t('autofix.kb35549bb')}
                  className="w-full rounded-md bg-[#173456] border border-blue-800 text-sm text-blue-100 placeholder-blue-300 pl-8 pr-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
                />
              </div>
            </div>
            {/* Type */}
            <div>
              <select
                value={typeFilter}
                onChange={e => setTypeFilter(e.target.value as any)}
                className="w-full rounded-md bg-[#173456] border border-blue-800 text-sm text-blue-100 px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
              >
                <option value="all">{t('autofix.k10e2568f')}</option>
                <option value="personal">Personal</option>
                <option value="company">Company</option>
              </select>
            </div>
            {/* Buttons */}
            <div className="flex gap-2">
              <button
                type="submit"
                disabled={loading || query.trim().length < 3}
                className="flex-1 rounded-md bg-blue-600 hover:bg-blue-500 disabled:opacity-50 text-white px-3 py-2 text-sm font-medium shadow-sm transition"
              >
                {loading ? 'Searching…' : 'Search'}
              </button>
              <button
                type="button"
                onClick={() => { setQuery(''); setItems([]); setTotal(0); setError(''); setHasSearched(false); }}
                className="rounded-md border border-blue-800 bg-[#173456] px-3 py-2 text-sm text-blue-100 hover:bg-blue-800/40 transition"
              >
                Clear
              </button>
            </div>
            {/* Total */}
            <div className="text-sm text-blue-200 self-center">{t('autofix.kc0e3b03d')}<span className="font-semibold text-white">{total}</span>
            </div>
          </form>

          {/* Results + selection area (scrollable) */}
          <div className="flex-1 overflow-y-auto px-6 py-4 space-y-4">
            {/* Results section */}
            <div className="relative">
              {error && (
                <div className="text-sm text-red-400 mb-4">{error}</div>
              )}
              {!error && query.trim().length < 3 && (
                <div className="py-12 text-sm text-blue-300 text-center">{t('autofix.kb87eb38b')}</div>
              )}
              {!error && query.trim().length >= 3 && !hasSearched && !loading && (
                <div className="py-12 text-sm text-blue-300 text-center">{t('autofix.k7c740cd5')}</div>
              )}
              {/* Skeleton only for first-time load (when no items yet) */}
              {!error && query.trim().length >= 3 && loading && items.length === 0 && (
                <ul className="space-y-0 divide-y divide-blue-900/40 border border-blue-900/40 rounded-md bg-[#132c4e]">
                  {Array.from({ length: 5 }).map((_, i) => (
                    <li key={i} className="animate-pulse px-4 py-3">
                      <div className="h-3.5 w-36 bg-blue-800/40 rounded" />
                      <div className="mt-2 h-3 w-56 bg-blue-800/30 rounded" />
                    </li>
                  ))}
                </ul>
              )}
              {!error && hasSearched && !loading && query.trim().length >= 3 && items.length === 0 && (
                <div className="py-12 text-sm text-blue-300 text-center">{t('autofix.k1e5d5139')}</div>
              )}
              {!error && hasSearched && items.length > 0 && (
                <ul className="divide-y divide-blue-900/40 border border-blue-900/40 rounded-lg bg-[#132c4e]">
                  {items.map(u => (
                    <li
                      key={u.userId}
                      className="px-4 py-3 flex items-center justify-between gap-3 hover:bg-blue-800/40 transition"
                    >
                      <div className="min-w-0">
                        <div className="flex items-center gap-2">
                          {u.userType === 'company'
                            ? <BuildingOffice2Icon className="h-4 w-4 text-indigo-400" />
                            : <UserIcon className="h-4 w-4 text-blue-300" />}
                          <span className="text-sm font-medium text-blue-100 truncate max-w-[160px]">{u.name}</span>
                          <span className={`text-[10px] font-semibold px-2 py-0.5 rounded-full ${
                            u.userType === 'company'
                              ? 'bg-indigo-700/40 text-indigo-200'
                              : 'bg-blue-700/40 text-blue-200'
                          }`}>
                            {u.userType === 'company' ? 'Company' : 'Personal'}
                          </span>
                        </div>
                        <div className="mt-0.5 text-[11px] text-blue-300 break-all">{u.email}</div>
                      </div>
                      <button
                        onClick={() => {
                          console.log('[SearchModal] Select candidate', { id: u.userId })
                          setSelected(u)
                          setAddError('')
                          setAddSuccess('')
                        }}
                        className="shrink-0 inline-flex items-center rounded-md bg-blue-600 hover:bg-blue-500 text-white px-3 py-1.5 text-xs font-medium shadow-sm transition"
                      >
                        {selected?.userId === u.userId ? 'Selected' : 'Select'}
                      </button>
                    </li>
                  ))}
                </ul>
              )}
              {/* Soft-loading overlay over existing list to avoid jumpiness */}
              {loading && items.length > 0 && (
                <div className="pointer-events-none absolute inset-0 flex items-center justify-center bg-[#0F1F3A]/30">
                  <span className="h-5 w-5 rounded-full border-2 border-blue-400 border-b-transparent animate-spin" />
                </div>
              )}
            </div>

            {/* Selected candidate details (conditional) */}
            {selected && (
              <div className="border border-blue-900/40 rounded-lg p-4 bg-[#132c4e] space-y-3">
                <div className="flex items-center justify-between">
                  <div className="text-sm text-blue-100 font-medium">
                    Candidate: {selected.name} <span className="text-blue-300">({selected.email})</span>
                  </div>
                  <button
                    onClick={() => { setSelected(null); setParentId(undefined); }}
                    className="text-xs text-blue-300 hover:text-white transition"
                  >{t('autofix.kadd80fbc')}</button>
                </div>

                <label className="flex items-center gap-2 text-xs text-blue-200">
                  <input
                    type="checkbox"
                    checked={advanced}
                    onChange={e => setAdvanced(e.target.checked)}
                    className="h-3 w-3 rounded border-blue-700 bg-blue-900 text-indigo-500 focus:ring-indigo-400"
                  />{t('autofix.k11974e0f')}</label>

                {advanced && (
                  <div className="space-y-2">
                    <select
                      key={parentsRevision}
                      value={parentId ?? ''}
                      onChange={e => setParentId(e.target.value ? Number(e.target.value) : undefined)}
                      className="w-full rounded-md bg-[#173456] border border-blue-800 text-xs text-blue-100 px-2 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                      title={addDisabledReason || undefined}
                    >
                      <option value="">(Auto referral / root)</option>
                      {potentialParents.map(p => {
                        const used = parentUsage.get(p.id) || 0
                        const isRoot = (p.level ?? 0) === 0
                        const full = (!isRoot && used >= 5) || (!!policyMaxDepth && policyMaxDepth > 0 && p.level >= policyMaxDepth) // CHANGED
                        const rem = !policyMaxDepth || policyMaxDepth <= 0 ? '∞' : Math.max(0, policyMaxDepth - p.level)
                        return (
                          <option key={p.id} value={p.id} disabled={full} title={full ? 'Parent full or at policy depth' : undefined}>
                            {p.name} • L{p.level} • Slots {isRoot ? `${used} (root ∞)` : `${used}/5`} • Rem levels: {rem}
                          </option>
                        )
                      })}
                    </select>
                    {/* CHANGED: clarify root unlimited and rogue behavior */}
                    <p className="text-[11px] text-blue-300">
                      {isRootSelected
                        ? 'Root has unlimited capacity; placing under root does not mark the user as rogue.'
                        : (!policyMaxDepth || policyMaxDepth <= 0)
                          ? 'Unlimited policy: no remaining-level cap for subtree.'
                          : `Remaining levels under chosen parent = Max(${policyMaxDepth}) - parent level.`}
                    </p>
                  </div>
                )}

                <label className="flex items-center gap-2 text-xs text-blue-200">
                  <input
                    type="checkbox"
                    checked={forceFallback}
                    onChange={e => setForceFallback(e.target.checked)}
                    className="h-3 w-3 rounded border-blue-700 bg-blue-900 text-indigo-500 focus:ring-indigo-400"
                  />{t('autofix.kf823daf7')}</label>
                <p className="text-[11px] text-blue-300">
                  If the referrer is outside the matrix, the user is placed under root; enabling fallback may mark the user as rogue.
                </p>

                {addError && <div className="text-xs text-red-400">{addError}</div>}
                {addSuccess && <div className="text-xs text-green-400">{addSuccess}</div>}

                <div className="flex justify-end">
                  <button
                    onClick={handleAdd}
                    disabled={adding || (!!addDisabledReason && !!advanced)} // NEW
                    title={addDisabledReason || undefined} // NEW
                    className="inline-flex items-center rounded-md bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white px-4 py-2 text-xs font-medium shadow-sm transition"
                  >
                    {adding ? 'Adding…' : 'Add to Matrix'}
                  </button>
                </div>
              </div>
            )}
          </div>

          {/* Footer (hidden when a candidate is selected) */}
          {!selected && (
            <div className="px-6 py-3 border-t border-blue-900/40 flex items-center justify-end bg-[#112645]">
              <button
                onClick={closeWithAnimation} // CHANGED: animated close
                className="text-sm rounded-md px-4 py-2 font-medium
                  bg-white/10 text-blue-200 backdrop-blur
                  hover:bg-indigo-500/20 hover:text-white hover:shadow-sm
                  focus:outline-none focus:ring-2 focus:ring-indigo-300 focus:ring-offset-2 focus:ring-offset-[#112645]
                  active:scale-95 transition"
              >
                Done
              </button>
            </div>
          )}
        </div>
      </div>
    </div>
  )

  return createPortal(modal, document.body)
}
