'use client'

import { useEffect, useMemo, useState } from 'react'
import type { ReactNode } from 'react'
import { Building2, RefreshCw, Save, ShieldCheck, UserCog } from 'lucide-react'
import { AdminShell } from '@/components/admin/AdminShell'
import { backend, type BackendOrgTree, type BackendPermissionItem, type BackendStaffAccount } from '@/lib/backend'

function blankTree(): BackendOrgTree {
  return { units: [], positions: [], assignments: [] }
}

function groupedPermissions(items: BackendPermissionItem[]) {
  return items.reduce<Record<string, BackendPermissionItem[]>>((groups, item) => {
    if (item.code === '*') return groups
    const key = item.group || '其他'
    groups[key] = [...(groups[key] || []), item]
    return groups
  }, {})
}

export default function AdminOrgPage() {
  const [tree, setTree] = useState<BackendOrgTree>(blankTree)
  const [catalog, setCatalog] = useState<BackendPermissionItem[]>([])
  const [accounts, setAccounts] = useState<BackendStaffAccount[]>([])
  const [selectedUnitId, setSelectedUnitId] = useState('')
  const [selectedPositionId, setSelectedPositionId] = useState('')
  const [unitForm, setUnitForm] = useState({ code: '', name: '', parentId: '', description: '' })
  const [positionForm, setPositionForm] = useState({ code: '', name: '', orgUnitId: '', roleCode: '', description: '' })
  const [assignmentForm, setAssignmentForm] = useState({ accountId: '', orgUnitId: '', positionId: '', roleCode: '' })
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [showAdvancedPermissions, setShowAdvancedPermissions] = useState(false)
  const [error, setError] = useState('')
  const [saved, setSaved] = useState('')

  const selectedUnit = useMemo(() => tree.units.find((unit) => unit.id === selectedUnitId) || tree.units[0] || null, [tree.units, selectedUnitId])
  const selectedPosition = useMemo(() => tree.positions.find((position) => position.id === selectedPositionId) || tree.positions.find((position) => position.orgUnitId === selectedUnit?.id) || tree.positions[0] || null, [tree.positions, selectedPositionId, selectedUnit?.id])
  const roles = useMemo(() => Array.from(new Map(tree.positions.map((position) => [position.roleCode, position.roleName || position.roleCode])).entries()), [tree.positions])
  const permissionGroups = useMemo(() => groupedPermissions(catalog), [catalog])
  const unitPositions = selectedUnit ? tree.positions.filter((position) => position.orgUnitId === selectedUnit.id) : []
  const unitAssignments = selectedUnit ? tree.assignments.filter((assignment) => assignment.orgUnitId === selectedUnit.id) : []

  async function reload() {
    setLoading(true)
    try {
      const [orgTree, permissionResult, accountResult] = await Promise.all([
        backend.adminOrgTree(),
        backend.adminPermissionCatalog(),
        backend.adminStaffAccounts(),
      ])
      setTree(orgTree)
      setCatalog(permissionResult.items)
      setAccounts(accountResult.items)
      setSelectedUnitId((current) => current || orgTree.units[0]?.id || '')
      setSelectedPositionId((current) => current || orgTree.positions[0]?.id || '')
      setError('')
    } catch (err) {
      setError(err instanceof Error ? err.message : '组织架构加载失败')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void reload()
  }, [])

  async function saveUnit() {
    setSaving(true)
    setSaved('')
    setError('')
    try {
      const next = await backend.createAdminOrgUnit(unitForm)
      setTree(next)
      setUnitForm({ code: '', name: '', parentId: '', description: '' })
      setSaved('组织已保存')
    } catch (err) {
      setError(err instanceof Error ? err.message : '组织保存失败')
    } finally {
      setSaving(false)
    }
  }

  async function savePosition() {
    setSaving(true)
    setSaved('')
    setError('')
    try {
      const next = await backend.createAdminPosition({ ...positionForm, orgUnitId: positionForm.orgUnitId || selectedUnit?.id || '' })
      setTree(next)
      setPositionForm({ code: '', name: '', orgUnitId: '', roleCode: '', description: '' })
      setSaved('岗位已保存')
    } catch (err) {
      setError(err instanceof Error ? err.message : '岗位保存失败')
    } finally {
      setSaving(false)
    }
  }

  async function saveAssignment() {
    setSaving(true)
    setSaved('')
    setError('')
    try {
      await backend.createAdminStaffAssignment({ ...assignmentForm, orgUnitId: assignmentForm.orgUnitId || selectedUnit?.id || '' })
      await reload()
      setAssignmentForm({ accountId: '', orgUnitId: '', positionId: '', roleCode: '' })
      setSaved('员工归属已保存')
    } catch (err) {
      setError(err instanceof Error ? err.message : '员工归属保存失败')
    } finally {
      setSaving(false)
    }
  }

  async function togglePermission(target: 'unit' | 'position', code: string) {
    const current = target === 'unit' ? selectedUnit : selectedPosition
    if (!current) return
    const nextPermissions = current.permissions.includes(code)
      ? current.permissions.filter((item) => item !== code)
      : [...current.permissions, code]
    setSaving(true)
    setSaved('')
    setError('')
    try {
      const next = target === 'unit'
        ? await backend.updateAdminOrgUnitPermissions(current.id, nextPermissions)
        : await backend.updateAdminPositionPermissions(current.id, nextPermissions)
      setTree(next)
      setSaved('继承权限已更新')
    } catch (err) {
      setError(err instanceof Error ? err.message : '权限保存失败')
    } finally {
      setSaving(false)
    }
  }

  return (
    <AdminShell title="组织架构" description="维护内部部门、岗位和人员归属；权限矩阵收在高级授权里，角色模板请到“角色与权限”。">
      {(error || saved) && (
        <div className={`mb-3 rounded-[4px] px-4 py-3 text-sm font-bold ${error ? 'bg-red-50 text-red-700' : 'bg-emerald-50 text-emerald-700'}`}>
          {error || saved}
        </div>
      )}

      <div className="mb-2 flex justify-end">
        <button type="button" onClick={() => void reload()} disabled={loading} className="inline-flex h-9 items-center gap-2 rounded-[4px] border border-line bg-white px-3 text-xs font-extrabold text-muted hover:border-brand hover:text-brand">
          <RefreshCw className="h-4 w-4" />
          {loading ? '刷新中' : '刷新'}
        </button>
      </div>

      <div className="grid h-[calc(100vh-128px)] min-h-[620px] gap-3 overflow-hidden xl:grid-cols-[280px_minmax(0,1fr)_320px]">
        <aside className="min-h-0 overflow-hidden border border-line bg-white">
          <SectionHeader icon={Building2} title="部门" />
          <div className="h-[calc(100%-45px)] overflow-y-auto">
            {tree.units.map((unit) => (
              <button key={unit.id} type="button" onClick={() => { setSelectedUnitId(unit.id); setSelectedPositionId('') }} className={`block w-full border-b border-line px-3 py-2.5 text-left hover:bg-bg ${selectedUnit?.id === unit.id ? 'bg-bg' : ''}`}>
                <div className="flex items-center justify-between gap-3">
                  <div className="text-sm font-extrabold text-ink" style={{ paddingLeft: `${Math.min(unit.depth, 4) * 12}px` }}>{unit.name}</div>
                  <span className="text-[11px] font-bold text-soft">{unit.staffCount}人</span>
                </div>
                <div className="mt-1 text-xs font-bold text-muted">{unit.code}</div>
              </button>
            ))}
          </div>
        </aside>

        <section className="min-h-0 overflow-y-auto border border-line bg-white">
          <SectionHeader icon={ShieldCheck} title={selectedUnit?.name || '组织详情'} />
          <div className="grid gap-3 p-4">
            <div className="grid gap-3 md:grid-cols-4">
              <Info label="组织编码" value={selectedUnit?.code} />
              <Info label="组织类型" value={selectedUnit?.unitType} />
              <Info label="层级" value={selectedUnit?.depth} />
              <Info label="成员数" value={selectedUnit?.staffCount} />
            </div>

            <div className="grid gap-3 lg:grid-cols-2">
              <div className="border border-line">
                <div className="border-b border-line bg-bg px-3 py-2 text-sm font-extrabold text-ink">岗位</div>
                {unitPositions.map((position) => (
                  <button key={position.id} type="button" onClick={() => setSelectedPositionId(position.id)} className={`block w-full border-b border-line px-3 py-2.5 text-left hover:bg-bg ${selectedPosition?.id === position.id ? 'bg-bg' : ''}`}>
                    <div className="font-extrabold text-ink">{position.name}</div>
                    <div className="mt-1 text-xs font-bold text-muted">{position.roleName} · {position.staffCount}人</div>
                  </button>
                ))}
                {!unitPositions.length && <div className="px-3 py-6 text-sm font-bold text-muted">这个部门暂未配置岗位</div>}
              </div>

              <div className="border border-line">
                <div className="border-b border-line bg-bg px-3 py-2 text-sm font-extrabold text-ink">成员</div>
                {unitAssignments.map((assignment) => (
                  <div key={assignment.id} className="border-b border-line px-3 py-2.5">
                    <div className="font-extrabold text-ink">{assignment.accountName}</div>
                    <div className="mt-1 text-xs font-bold text-muted">{assignment.positionName || assignment.roleName} · {assignment.accountPhone || '-'}</div>
                  </div>
                ))}
                {!unitAssignments.length && <div className="px-3 py-6 text-sm font-bold text-muted">这个部门暂未分配成员</div>}
              </div>
            </div>

            <div className="border border-line bg-bg px-3 py-2.5">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <div className="text-sm font-extrabold text-ink">权限摘要</div>
                  <div className="mt-1 text-xs font-bold text-muted">
                    部门额外权限 {selectedUnit?.permissions.length || 0} 个
                    {selectedPosition ? ` · 岗位额外权限 ${selectedPosition.permissions.length || 0} 个` : ''}
                  </div>
                </div>
                <button type="button" onClick={() => setShowAdvancedPermissions((value) => !value)} className="h-8 rounded-[4px] border border-line bg-white px-3 text-xs font-extrabold text-muted hover:border-brand hover:text-brand">
                  {showAdvancedPermissions ? '收起高级授权' : '高级授权'}
                </button>
              </div>
            </div>

            {showAdvancedPermissions && (
              <>
                <PermissionMatrix
                  title={`${selectedUnit?.name || '组织'}继承权限`}
                  permissions={selectedUnit?.permissions || []}
                  groups={permissionGroups}
                  disabled={saving || !selectedUnit}
                  onToggle={(code) => void togglePermission('unit', code)}
                />

                {selectedPosition && (
                  <PermissionMatrix
                    title={`${selectedPosition.name}岗位权限`}
                    permissions={selectedPosition.permissions || []}
                    groups={permissionGroups}
                    disabled={saving}
                    onToggle={(code) => void togglePermission('position', code)}
                  />
                )}
              </>
            )}
          </div>
        </section>

        <aside className="min-h-0 space-y-3 overflow-y-auto pr-1">
          <Panel title="新增部门">
            <input value={unitForm.code} onChange={(event) => setUnitForm((current) => ({ ...current, code: event.target.value }))} placeholder="编码，如 data_ops" className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
            <input value={unitForm.name} onChange={(event) => setUnitForm((current) => ({ ...current, name: event.target.value }))} placeholder="部门名称" className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
            <select value={unitForm.parentId} onChange={(event) => setUnitForm((current) => ({ ...current, parentId: event.target.value }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">无上级</option>
              {tree.units.map((unit) => <option key={unit.id} value={unit.id}>{unit.name}</option>)}
            </select>
            <textarea value={unitForm.description} onChange={(event) => setUnitForm((current) => ({ ...current, description: event.target.value }))} placeholder="说明" rows={3} className="w-full border border-line p-3 text-sm font-bold outline-none focus:border-brand" />
            <button type="button" onClick={() => void saveUnit()} disabled={saving} className="inline-flex h-10 items-center justify-center gap-2 rounded-[4px] bg-ink px-4 text-sm font-extrabold text-white hover:bg-brand disabled:bg-line-dark">
              <Save className="h-4 w-4" />
              保存部门
            </button>
          </Panel>

          <Panel title="新增岗位">
            <input value={positionForm.code} onChange={(event) => setPositionForm((current) => ({ ...current, code: event.target.value }))} placeholder="编码，如 data_service_staff" className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
            <input value={positionForm.name} onChange={(event) => setPositionForm((current) => ({ ...current, name: event.target.value }))} placeholder="岗位名称" className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
            <select value={positionForm.orgUnitId || selectedUnit?.id || ''} onChange={(event) => setPositionForm((current) => ({ ...current, orgUnitId: event.target.value }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择部门</option>
              {tree.units.map((unit) => <option key={unit.id} value={unit.id}>{unit.name}</option>)}
            </select>
            <select value={positionForm.roleCode} onChange={(event) => setPositionForm((current) => ({ ...current, roleCode: event.target.value }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择角色模板</option>
              {roles.map(([code, name]) => <option key={code} value={code}>{name}</option>)}
            </select>
            <textarea value={positionForm.description} onChange={(event) => setPositionForm((current) => ({ ...current, description: event.target.value }))} placeholder="说明" rows={3} className="w-full border border-line p-3 text-sm font-bold outline-none focus:border-brand" />
            <button type="button" onClick={() => void savePosition()} disabled={saving} className="inline-flex h-10 items-center justify-center gap-2 rounded-[4px] bg-ink px-4 text-sm font-extrabold text-white hover:bg-brand disabled:bg-line-dark">
              <Save className="h-4 w-4" />
              保存岗位
            </button>
          </Panel>

          <Panel title="员工归属">
            <select value={assignmentForm.accountId} onChange={(event) => setAssignmentForm((current) => ({ ...current, accountId: event.target.value }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择员工</option>
              {accounts.map((account) => <option key={account.id} value={account.id}>{account.displayName} · {account.phone}</option>)}
            </select>
            <select value={assignmentForm.orgUnitId || selectedUnit?.id || ''} onChange={(event) => setAssignmentForm((current) => ({ ...current, orgUnitId: event.target.value, positionId: '' }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择部门</option>
              {tree.units.map((unit) => <option key={unit.id} value={unit.id}>{unit.name}</option>)}
            </select>
            <select value={assignmentForm.positionId} onChange={(event) => {
              const position = tree.positions.find((item) => item.id === event.target.value)
              setAssignmentForm((current) => ({ ...current, positionId: event.target.value, roleCode: position?.roleCode || current.roleCode }))
            }} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择岗位</option>
              {tree.positions.filter((position) => !assignmentForm.orgUnitId || position.orgUnitId === assignmentForm.orgUnitId).map((position) => <option key={position.id} value={position.id}>{position.name}</option>)}
            </select>
            <select value={assignmentForm.roleCode} onChange={(event) => setAssignmentForm((current) => ({ ...current, roleCode: event.target.value }))} className="h-10 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand">
              <option value="">选择角色</option>
              {roles.map(([code, name]) => <option key={code} value={code}>{name}</option>)}
            </select>
            <button type="button" onClick={() => void saveAssignment()} disabled={saving} className="inline-flex h-10 items-center justify-center gap-2 rounded-[4px] bg-ink px-4 text-sm font-extrabold text-white hover:bg-brand disabled:bg-line-dark">
              <UserCog className="h-4 w-4" />
              保存归属
            </button>
          </Panel>
        </aside>
      </div>
    </AdminShell>
  )
}

function SectionHeader({ icon: Icon, title }: { icon: typeof Building2; title: string }) {
  return (
    <div className="flex items-center gap-2 border-b border-line px-3 py-2.5">
      <Icon className="h-4 w-4 text-brand" />
      <h2 className="text-sm font-extrabold text-ink">{title}</h2>
    </div>
  )
}

function Info({ label, value }: { label: string; value?: string | number | null }) {
  return (
    <div className="border border-line bg-bg px-3 py-2">
      <div className="text-[11px] font-bold text-soft">{label}</div>
      <div className="mt-1 break-words text-sm font-extrabold text-ink">{value || '-'}</div>
    </div>
  )
}

function Panel({ title, children }: { title: string; children: ReactNode }) {
  return (
    <section className="border border-line bg-white p-3">
      <div className="mb-3 text-sm font-extrabold text-ink">{title}</div>
      <div className="grid gap-2.5">{children}</div>
    </section>
  )
}

function PermissionMatrix({
  title,
  permissions,
  groups,
  disabled,
  onToggle,
}: {
  title: string
  permissions: string[]
  groups: Record<string, BackendPermissionItem[]>
  disabled?: boolean
  onToggle: (code: string) => void
}) {
  return (
    <div className="border border-line">
      <div className="border-b border-line bg-bg px-3 py-2 text-sm font-extrabold text-ink">{title}</div>
      <div className="grid gap-0 md:grid-cols-2">
        {Object.entries(groups).map(([group, items]) => (
          <section key={group} className="border-b border-line p-2.5 md:border-r">
            <div className="mb-2 text-xs font-extrabold text-muted">{group}</div>
            <div className="grid gap-1.5">
              {items.map((permission) => (
                <label key={permission.code} className="grid cursor-pointer grid-cols-[18px_1fr] gap-2 text-xs font-bold text-muted">
                  <input type="checkbox" disabled={disabled} checked={permissions.includes(permission.code)} onChange={() => onToggle(permission.code)} className="mt-0.5 h-4 w-4 accent-brand" />
                  <span>
                    <span className="block text-xs font-extrabold text-ink">{permission.label}</span>
                    <span className="block text-[11px] text-soft">{permission.code}</span>
                  </span>
                </label>
              ))}
            </div>
          </section>
        ))}
      </div>
    </div>
  )
}
