'use client'



import { useTranslation } from '../../../i18n/useTranslation';
import React, { useEffect, useMemo, useState, Suspense } from 'react' // CHANGED: add Suspense
import { useSearchParams, useRouter } from 'next/navigation'
import PageLayout from '../../../components/PageLayout'
import { ArrowLeftIcon, MagnifyingGlassIcon, PlusIcon, UserIcon, BuildingOffice2Icon } from '@heroicons/react/24/outline'
import { useMatrixUsers, MatrixUser } from './hooks/getStats'
import useAuthStore from '../../../store/authStore'
import { getMatrixStats } from '../hooks/getMatrixStats'
import SearchModal from './components/searchModal'

const DEFAULT_FETCH_DEPTH = 50 // provisional large depth to approximate unlimited
const LEVEL_CAP = (level: number) => Math.pow(5, level) // L1=5, L2=25, ...

function MatrixDetailPageInner() {
  const { t } = useTranslation()
  const sp = useSearchParams()
  const router = useRouter()

  const matrixId = sp.get('id') || 'm-1'
  const matrixName = sp.get('name') || 'Unnamed Matrix'
  const topNodeEmail = sp.get('top') || 'top@example.com'
  const rootUserIdParam = sp.get('rootUserId')
  const rootUserId = rootUserIdParam ? Number(rootUserIdParam) : undefined
  console.info('[MatrixDetailPage] Params', { matrixId, matrixName, topNodeEmail, rootUserId })

  // Resolve rootUserId when missing by looking it up via stats
  const accessToken = useAuthStore(s => s.accessToken)
  const [resolvedRootUserId, setResolvedRootUserId] = useState<number | undefined>(rootUserId)
  // NEW: track policy (DB) max depth (null => unlimited)
  const [policyMaxDepth, setPolicyMaxDepth] = useState<number | null>(null)

  useEffect(() => {
    let cancelled = false
    async function resolveRoot() {
      if (rootUserId && rootUserId > 0) {
        console.info('[MatrixDetailPage] Using rootUserId from URL', { rootUserId })
        setResolvedRootUserId(rootUserId)
        return
      }
      if (!accessToken) {
        console.warn('[MatrixDetailPage] No accessToken; cannot resolve rootUserId from stats')
        setResolvedRootUserId(undefined)
        return
      }
      if (!matrixId) {
        console.warn('[MatrixDetailPage] No matrixId; cannot resolve rootUserId from stats')
        setResolvedRootUserId(undefined)
        return
      }
      console.info('[MatrixDetailPage] Resolving rootUserId via stats for matrixId', { matrixId })
      const res = await getMatrixStats({ token: accessToken, baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL })
      console.debug('[MatrixDetailPage] getMatrixStats result', res)
      if (!res.ok) {
        console.error('[MatrixDetailPage] getMatrixStats failed', { status: res.status, message: res.message })
        setResolvedRootUserId(undefined)
        return
      }
      const body = res.body || {}
      const matrices = (body?.data?.matrices ?? body?.matrices ?? []) as any[]
      console.debug('[MatrixDetailPage] Stats matrices overview', {
        count: matrices.length,
        ids: matrices.map((m: any) => m?.id ?? m?.matrixId),
        matrixIds: matrices.map((m: any) => m?.matrixId ?? m?.id),
        rootUserIds: matrices.map((m: any) => m?.rootUserId ?? m?.root_user_id),
        emails: matrices.map((m: any) => m?.topNodeEmail ?? m?.email)
      })
      const found = matrices.find((m: any) =>
        String(m?.id) === String(matrixId) || String(m?.matrixId) === String(matrixId)
      )
      // NEW: extract policy maxDepth (may be null)
      const pmRaw = found?.maxDepth ?? found?.max_depth ?? null
      if (!cancelled) {
        setPolicyMaxDepth(pmRaw == null ? null : Number(pmRaw))
      }
      const ru = Number(found?.rootUserId ?? found?.root_user_id)
      if (ru > 0 && !cancelled) {
        console.info('[MatrixDetailPage] Resolved rootUserId from stats', { matrixId, rootUserId: ru })
        setResolvedRootUserId(ru)
      } else {
        console.warn('[MatrixDetailPage] Could not resolve rootUserId from stats', { matrixId, found })
        setResolvedRootUserId(undefined)
      }
    }
    resolveRoot()
    return () => { cancelled = true }
  }, [matrixId, rootUserId, accessToken])

  // Backend users (changed depth from 5 to DEFAULT_FETCH_DEPTH)
  const { users: fetchedUsers, loading: usersLoading, error: usersError, meta, refetch, serverMaxDepth } = useMatrixUsers(resolvedRootUserId, {
    depth: DEFAULT_FETCH_DEPTH,
    includeRoot: true,
    limit: 2000,
    offset: 0,
    matrixId,
    topNodeEmail
  })

  // Prepare for backend fetches
  const [users, setUsers] = useState<MatrixUser[]>([])

  useEffect(() => {
    console.info('[MatrixDetailPage] useMatrixUsers state', {
      loading: usersLoading,
      error: !!usersError,
      fetchedCount: fetchedUsers.length,
      meta
    })
    setUsers(fetchedUsers)
  }, [fetchedUsers, usersLoading, usersError, meta])

  // Modal state
  const [open, setOpen] = useState(false)
  // ADD: global search state (was removed)
  const [globalSearch, setGlobalSearch] = useState('')

  // Refresh overlay state
  const [refreshing, setRefreshing] = useState(false)

  // Collapsed state for each level
  const [collapsedLevels, setCollapsedLevels] = useState<{ [level: number]: boolean }>({
    0: true, 1: true, 2: true, 3: true, 4: true, 5: true
  })

  // Per-level search
  const [levelSearch, setLevelSearch] = useState<{ [level: number]: string }>({
    0: '', 1: '', 2: '', 3: '', 4: '', 5: ''
  })

  // Counts per level and next available level logic
  const byLevel = useMemo(() => {
    const map = new Map<number, MatrixUser[]>()
    users.forEach(u => {
      if (!u.name) {
        console.warn('[MatrixDetailPage] User missing name, fallback email used', { id: u.id, email: u.email })
      }
      const lvl = (typeof u.level === 'number' && u.level >= 0) ? u.level : 0
      const arr = map.get(lvl) || []
      arr.push({ ...u, level: lvl })
      map.set(lvl, arr)
    })
    console.debug('[MatrixDetailPage] byLevel computed', { levels: Array.from(map.keys()), total: users.length })
    return map
  }, [users])

  const nextAvailableLevel = () => {
    let lvl = 1
    while (true) {
      const current = byLevel.get(lvl)?.length || 0
      if (current < LEVEL_CAP(lvl)) return lvl
      lvl += 1
      if (lvl > 8) return lvl // safety ceiling in demo
    }
  }

  const addToMatrix = (u: Omit<MatrixUser, 'level'>) => {
    const level = nextAvailableLevel()
    console.info('[MatrixDetailPage] addToMatrix', { userId: u.id, nextLevel: level })
    setUsers(prev => [...prev, { ...u, level }])
  }

  // Simple chip for user
  const UserChip = ({ u }: { u: MatrixUser }) => (
    <div className="inline-flex items-center gap-2 rounded-full bg-gray-50 border border-gray-200 px-3 py-1 text-xs text-gray-800">
      {u.type === 'company' ? <BuildingOffice2Icon className="h-4 w-4 text-indigo-600" /> : <UserIcon className="h-4 w-4 text-blue-600" />}
      <span className="font-medium truncate max-w-[140px]">{u.name}</span>
    </div>
  )

  // Global search (already present) + node collapse state
  const [collapsedNodes, setCollapsedNodes] = useState<Record<number, boolean>>({})
  const toggleNode = (id: number) => setCollapsedNodes(p => ({ ...p, [id]: !p[id] }))

  // Build children adjacency map
  const childrenMap = useMemo(() => {
    const m = new Map<number, MatrixUser[]>()
    users.forEach(u => {
      if (u.parentUserId != null) {
        const arr = m.get(u.parentUserId) || []
        arr.push(u)
        m.set(u.parentUserId, arr)
      }
    })
    // sort children by optional position then id
    m.forEach(arr => arr.sort((a,b) => {
      const pa = (a as any).position ?? 0
      const pb = (b as any).position ?? 0
      return pa - pb || a.id - b.id
    }))
    return m
  }, [users])

  // Root node
  const rootNode = useMemo(
    () => users.find(u => u.level === 0 || u.id === resolvedRootUserId),
    [users, resolvedRootUserId]
  )

  const rootChildren = useMemo(() => rootNode ? (childrenMap.get(rootNode.id) || []) : [], [rootNode, childrenMap])
  const rootChildrenCount = useMemo(() => rootChildren.length, [rootChildren])
  const displayedRootSlots = useMemo(() =>
    rootChildren.filter(c => {
      const pos = Number((c as any).position ?? -1)
      return pos >= 1 && pos <= 5
    }).length
  , [rootChildren])

  // Rogue count if flags exist
  const rogueCount = useMemo(
    () => users.filter(u => (u as any).rogueUser || (u as any).rogue_user || (u as any).rogue).length,
    [users]
  )

  // Filter match helper
  const searchLower = globalSearch.trim().toLowerCase()
  const matchesSearch = (u: MatrixUser) =>
    !searchLower ||
    u.name.toLowerCase().includes(searchLower) ||
    u.email.toLowerCase().includes(searchLower)

  // Determine which nodes should be visible when searching:
  // Show all ancestors of matching nodes so the path is visible.
  const visibleIds = useMemo(() => {
    if (!searchLower) return new Set(users.map(u => u.id))
    const matchIds = new Set<number>()
    const parentMap = new Map<number, number | undefined>()
    users.forEach(u => parentMap.set(u.id, u.parentUserId == null ? undefined : u.parentUserId))
    users.forEach(u => {
      if (matchesSearch(u)) {
        let cur: number | undefined = u.id
        while (cur != null) {
          if (!matchIds.has(cur)) matchIds.add(cur)
          cur = parentMap.get(cur)
        }
      }
    })
    return matchIds
  }, [users, searchLower])

  // Auto-expand ancestors for search results
  useEffect(() => {
    if (!searchLower) return
    // Expand all visible nodes containing matches
    setCollapsedNodes(prev => {
      const next = { ...prev }
      visibleIds.forEach(id => { next[id] = false })
      return next
    })
  }, [searchLower, visibleIds])

  // Tree renderer (inside component to access scope)
  const renderNode = (node: MatrixUser, depth: number) => {
    const children = childrenMap.get(node.id) || []
    const hasChildren = children.length > 0
    const collapsed = collapsedNodes[node.id]
    const highlight = matchesSearch(node) && searchLower.length > 0
    if (!visibleIds.has(node.id)) return null
    const isRoot = node.level === 0
    const pos = node.position ?? null
    return (
      <li key={node.id} className="relative">
        <div
          className={`flex items-center gap-2 rounded-md border px-2 py-1 text-xs ${
            highlight ? 'border-blue-500 bg-blue-50' : 'border-gray-200 bg-white'
          }`}
        >
          {hasChildren && (
            <button
              onClick={() => toggleNode(node.id)}
              className="h-4 w-4 rounded border border-gray-300 text-[10px] flex items-center justify-center bg-gray-50 hover:bg-gray-100"
              aria-label={collapsed ? 'Expand' : 'Collapse'}
            >
              {collapsed ? '+' : '–'}
            </button>
          )}
          {!hasChildren && <span className="h-4 w-4" />}
          {node.type === 'company'
            ? <BuildingOffice2Icon className="h-4 w-4 text-indigo-600" />
            : <UserIcon className="h-4 w-4 text-blue-600" />}
          <span className="font-medium truncate max-w-[160px]">{node.name}</span>
          <span className="text-[10px] px-1 rounded bg-gray-100 text-gray-600">L{node.level}</span>
          {(node as any).rogueUser || (node as any).rogue_user || (node as any).rogue ? (
            <span className="text-[10px] px-2 py-0.5 rounded-full bg-yellow-100 text-yellow-800">Rogue</span>
          ) : null}
          {pos != null && (
            <span className="text-[10px] px-1 rounded bg-gray-100 text-gray-600">
              pos {pos}
            </span>
          )}
          {isRoot && (
            <span className="ml-auto text-[10px] text-gray-500">
              Unlimited; positions numbered sequentially
            </span>
          )}
          {!isRoot && hasChildren && (
            <span className="ml-auto text-[10px] text-gray-500">
              {children.length}/5 (slots 1–5)
            </span>
          )}
        </div>
        {hasChildren && !collapsed && (
          <ul className="ml-6 mt-1 flex flex-col gap-1">
            {children.map(c => renderNode(c, depth + 1))}
          </ul>
        )}
      </li>
    )
  }

  // CSV export (now all users fetched)
  const exportCsv = () => {
    const rows = [['id','name','email','type','level','parentUserId','rogue']]
    users.forEach(u => rows.push([
      u.id,
      u.name,
      u.email,
      u.type,
      u.level,
      u.parentUserId ?? '',
      ((u as any).rogueUser || (u as any).rogue_user || (u as any).rogue) ? 'true' : 'false'
    ] as any))
    const csv = rows.map(r => r.map(v => `"${String(v).replace(/"/g,'""')}"`).join(',')).join('\n')
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' })
    const a = document.createElement('a')
    a.href = URL.createObjectURL(blob)
    a.download = `matrix-${matrixId}-unlimited.csv`
    a.click()
    URL.revokeObjectURL(a.href)
  }

  // When modal closes, refetch backend to sync page data
  const handleModalClose = () => {
    setOpen(false)
    setRefreshing(true)
    refetch() // triggers hook reload
  }

  // Stop spinner when hook finishes loading
  useEffect(() => {
    if (!usersLoading && refreshing) {
      setRefreshing(false)
    }
  }, [usersLoading, refreshing])

  // REMOVE old isUnlimited derivation using serverMaxDepth; REPLACE with policy-based
  // const isUnlimited = !serverMaxDepth || serverMaxDepth <= 0;
  const isUnlimited = policyMaxDepth == null || policyMaxDepth <= 0 // NEW

  const policyDepth = (policyMaxDepth && policyMaxDepth > 0) ? policyMaxDepth : null
  const perLevelCounts = useMemo(() => {
    const m = new Map<number, number>()
    users.forEach(u => {
      if (u.level != null && u.level >= 0) {
        m.set(u.level, (m.get(u.level) || 0) + 1)
      }
    })
    return m
  }, [users])
  const totalNonRoot = useMemo(() => users.filter(u => (u.level ?? 0) > 0).length, [users])
  const fillMetrics = useMemo(() => {
    if (!policyDepth) return { label: 'N/A (unlimited policy)', highestFull: 'N/A' }
    let capacitySum = 0
    let highestFullLevel: number | null = null
    for (let k = 1; k <= policyDepth; k++) {
      const cap = Math.pow(5, k)
      capacitySum += cap
      const lvlCount = perLevelCounts.get(k) || 0
      if (lvlCount >= cap) highestFullLevel = k
    }
    if (capacitySum === 0) return { label: 'N/A', highestFull: 'N/A' }
    const pct = Math.round((totalNonRoot / capacitySum) * 100 * 100) / 100
    return { label: `${pct}%`, highestFull: highestFullLevel == null ? 'None' : `L${highestFullLevel}` }
  }, [policyDepth, perLevelCounts, totalNonRoot])

  return (
    <PageLayout>
      {/* Smooth refresh overlay */}
      {refreshing && (
        <div className="fixed inset-0 z-[9999] flex items-center justify-center bg-white/50 backdrop-blur-sm transition-opacity">
          <div className="flex items-center gap-3 rounded-lg bg-white shadow-md border border-gray-200 px-4 py-3">
            <span className="h-5 w-5 rounded-full border-2 border-blue-900 border-b-transparent animate-spin" />
            <span className="text-sm text-gray-700">{t('autofix.k14a4b43e')}</span>
          </div>
        </div>
      )}

      <div className="bg-gradient-to-tr from-blue-50 via-white to-blue-100 min-h-screen w-full">
        <div className="mx-auto max-w-6xl px-2 sm:px-6 py-8">
          {/* Header card */}
          <header className="mb-8 rounded-2xl border border-gray-100 bg-white shadow-lg px-8 py-8 flex flex-col gap-4">
            <div className="flex items-center justify-between">
              <div className="space-y-2">
                <button
                  onClick={() => router.push('/admin/matrix-management')}
                  className="inline-flex items-center gap-2 text-sm text-blue-900 hover:text-blue-700"
                >
                  <ArrowLeftIcon className="h-4 w-4" />{t('autofix.k65b67dc3')}</button>
                <h1 className="text-3xl font-extrabold text-blue-900">{matrixName}</h1>
                <p className="text-base text-blue-700">{t('autofix.k31d46514')}<span className="font-semibold text-blue-900">{topNodeEmail}</span>
                </p>
                <div className="mt-2 flex flex-wrap items-center gap-2">
                  <span className="inline-flex items-center rounded-full bg-gray-100 border border-gray-200 px-3 py-1 text-xs text-gray-800">
                    Root: unlimited immediate children (sequential positions)
                  </span>
                  <span className="inline-flex items-center rounded-full bg-gray-100 border border-gray-200 px-3 py-1 text-xs text-gray-800">
                    Non-root: 5 children (positions 1–5)
                  </span>
                  <span className="inline-flex items-center rounded-full bg-blue-50 border border-blue-200 px-3 py-1 text-xs text-blue-900">
                    Policy depth (DB): {isUnlimited ? 'Unlimited' : policyMaxDepth}
                  </span>
                  <span className="inline-flex items-center rounded-full bg-purple-50 border border-purple-200 px-3 py-1 text-xs text-purple-900">
                    Fetch depth (client slice): {DEFAULT_FETCH_DEPTH}
                  </span>
                  {serverMaxDepth != null && (
                    <span className="inline-flex items-center rounded-full bg-amber-50 border border-amber-200 px-3 py-1 text-xs text-amber-800">
                      Server-reported max depth: {serverMaxDepth}
                    </span>
                  )}
                  <span className="inline-flex items-center rounded-full bg-gray-100 border border-gray-200 px-3 py-1 text-xs text-gray-800">
                    Root children: {rootChildrenCount} (unlimited)
                  </span>
                  <span className="inline-flex items-center rounded-full bg-gray-100 border border-gray-200 px-3 py-1 text-xs text-gray-800">
                    Displayed slots under root (positions 1–5): {displayedRootSlots}/5
                  </span>
                </div>
              </div>
              <div className="flex items-center gap-2">
                <button
                  onClick={() => { setOpen(true) }}
                  className="inline-flex items-center gap-2 rounded-lg bg-blue-900 hover:bg-blue-800 text-blue-50 px-5 py-3 text-base font-semibold shadow transition"
                >
                  <PlusIcon className="h-5 w-5" />{t('autofix.kc7c429a6')}</button>
              </div>
            </div>
          </header>

          {/* Banner for unlimited */}
          {isUnlimited && (
            <div className="mb-4 rounded-md px-4 py-2 text-xs text-blue-900 bg-blue-50 border border-blue-200">
              Unlimited matrix: depth grows without a configured cap. Display limited by fetch slice ({DEFAULT_FETCH_DEPTH} levels requested).
            </div>
          )}

          {/* Sticky controls (CHANGED depth display) */}
          <div className="sticky top-0 z-10 bg-white/90 backdrop-blur px-6 py-4 border-b border-blue-100 flex flex-wrap items-center gap-4 rounded-xl mb-6 shadow">
            <div className="relative w-64">
              <MagnifyingGlassIcon className="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-blue-300" />
              <input
                value={globalSearch}
                onChange={e => setGlobalSearch(e.target.value)}
                placeholder={t('autofix.kd304af2e')}
                className="pl-8 pr-2 py-2 rounded-lg border border-gray-200 text-xs focus:ring-1 focus:ring-blue-900 focus:border-transparent w-full"
              />
            </div>
            <button
              onClick={() => exportCsv()}
              className="text-xs text-blue-900 hover:text-blue-700 underline"
            >
              Export CSV (all fetched)
            </button>
            <div className="ml-auto text-[11px] text-gray-600">
              Policy depth: {isUnlimited ? 'Unlimited' : policyMaxDepth}
            </div>
          </div>

          {/* Small stats (CHANGED wording) */}
          <div className="mb-8 grid grid-cols-1 sm:grid-cols-4 gap-6">
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">{t('autofix.k65e33378')}</div>
              <div className="text-xl font-semibold text-blue-900">{users.length}</div>
            </div>
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">{t('autofix.kb343460d')}</div>
              <div className="text-xl font-semibold text-blue-900">{rogueCount}</div>
            </div>
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">Structure</div>
              <div className="text-xl font-semibold text-blue-900">{t('autofix.kf3557acd')}</div>
            </div>
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">{t('autofix.k776b751c')}</div>
              <div className="text-xl font-semibold text-blue-900">{isUnlimited ? 'Unlimited' : policyMaxDepth}</div>
            </div>
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">{t('autofix.k9683262f')}</div>
              <div className="text-xl font-semibold text-blue-900">{fillMetrics.label}</div>
            </div>
            <div className="rounded-xl border border-gray-100 bg-white p-5 shadow">
              <div className="text-xs text-gray-500 mb-1">{t('autofix.k7f9568ec')}</div>
              <div className="text-xl font-semibold text-blue-900">{fillMetrics.highestFull}</div>
            </div>
          </div>

          {/* Unlimited hierarchical tree (replaces dynamic levels + grouped level list) */}
          <div className="rounded-2xl bg-white border border-gray-100 shadow-lg overflow-hidden mb-8">
            <div className="px-8 py-6 border-b border-gray-100">
              <h2 className="text-xl font-semibold text-blue-900">Matrix Tree (Unlimited Depth)</h2>
              <p className="text-xs text-blue-700">{t('autofix.kab4f5159')}</p>
            </div>
            <div className="px-8 py-6">
              {!rootNode && (
                <div className="text-xs text-gray-500 italic">{t('autofix.k4e61bc77')}</div>
              )}
              {rootNode && (
                <ul className="flex flex-col gap-1">
                  {renderNode(rootNode, 0)}
                </ul>
              )}
            </div>
          </div>

          {/* Vacancies placeholder */}
          <div className="rounded-2xl bg-white border border-dashed border-blue-200 shadow-sm p-6 mb-8">
            <h3 className="text-lg font-semibold text-blue-900 mb-2">Vacancies</h3>
            <p className="text-sm text-blue-700">{t('autofix.k9b3266b5')}</p>
          </div>

          {/* Add Users Modal */}
          <SearchModal
            open={open}
            onClose={handleModalClose}
            matrixName={matrixName}
            rootUserId={resolvedRootUserId}
            matrixId={matrixId}
            topNodeEmail={topNodeEmail}
            existingUsers={users}
            policyMaxDepth={policyMaxDepth}
            onAdd={(u) => { addToMatrix(u) }}
          />
        </div>
      </div>
    </PageLayout>
  )
}

// CHANGED: default export wraps inner component in Suspense
export default function MatrixDetailPage() {
  return (
    <Suspense
      fallback={
        <PageLayout>
          <div className="min-h-screen flex items-center justify-center">
            <div className="text-center">
              <div className="animate-spin rounded-full h-10 w-10 border-b-2 border-[#8D6B1D] mx-auto mb-3" />
              <p className="text-[#4A4A4A]">Loading...</p>
            </div>
          </div>
        </PageLayout>
      }
    >
      <MatrixDetailPageInner />
    </Suspense>
  )
}