'use client'

import Link from 'next/link'
import { useParams } from 'next/navigation'
import { useEffect, useMemo, useState } from 'react'
import { ArrowLeft, BadgeCheck, Ban, RefreshCw, Save } from 'lucide-react'
import { AdminShell } from '@/components/admin/AdminShell'
import { backend, type BackendOrgTree, type BackendPermissionItem, type BackendStaffAccount, type BackendStaffAssignment, type BackendStaffAuditLog, type BackendStaffEffectivePermissions, type BackendStaffRole } from '@/lib/backend'

type StaffDraft = {
  displayName: string
  phone: string
  role: string
  positionTitle: string
  remark: string
  status: 'active' | 'disabled'
}

type AssignmentDraft = {
  orgUnitId: string
  positionId: string
  roleCode: string
}

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

function formatDate(value?: string | null) {
  if (!value) return '-'
  return new Date(value).toLocaleString('zh-CN')
}

function draftFromAccount(account: BackendStaffAccount): StaffDraft {
  return {
    displayName: account.displayName || '',
    phone: account.phone || '',
    role: account.role || '',
    positionTitle: account.positionTitle || '',
    remark: account.remark || '',
    status: account.status === 'disabled' ? 'disabled' : 'active',
  }
}

function assignmentDraftFrom(account: BackendStaffAccount, assignments: BackendStaffAssignment[]): AssignmentDraft {
  const primary = assignments.find((item) => item.accountId === account.id && item.isPrimary)
    || assignments.find((item) => item.accountId === account.id)
  return {
    orgUnitId: primary?.orgUnitId || account.orgUnitId || '',
    positionId: primary?.positionId || account.positionId || '',
    roleCode: primary?.roleCode || account.role || '',
  }
}

export default function AdminStaffAccountDetailPage() {
  const params = useParams<{ id: string }>()
  const accountId = decodeURIComponent(params.id)
  const [account, setAccount] = useState<BackendStaffAccount | null>(null)
  const [roles, setRoles] = useState<BackendStaffRole[]>([])
  const [orgTree, setOrgTree] = useState<BackendOrgTree>(blankTree)
  const [permissionCatalog, setPermissionCatalog] = useState<BackendPermissionItem[]>([])
  const [effectivePermissions, setEffectivePermissions] = useState<BackendStaffEffectivePermissions | null>(null)
  const [logs, setLogs] = useState<BackendStaffAuditLog[]>([])
  const [draft, setDraft] = useState<StaffDraft | null>(null)
  const [assignmentDraft, setAssignmentDraft] = useState<AssignmentDraft>({ orgUnitId: '', positionId: '', roleCode: '' })
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [savingAssignment, setSavingAssignment] = useState(false)
  const [savingDirectPermissions, setSavingDirectPermissions] = useState(false)
  const [directPermissionText, setDirectPermissionText] = useState('')
  const [saved, setSaved] = useState('')
  const [error, setError] = useState('')

  const responsibilityItems = useMemo(() => [
    { label: '交付任务', value: account?.taskCount || 0 },
    { label: '咨询需求', value: account?.consultingCount || 0 },
    { label: '数据服务', value: account?.dataServiceCount || 0 },
    { label: '报名核销', value: account?.checkinCount || 0 },
  ], [account])
  const roleOptions = useMemo(
    () => roles.filter((role) => role.code !== 'super_admin' || account?.role === 'super_admin'),
    [account?.role, roles],
  )
  const accountAssignments = useMemo(
    () => orgTree.assignments.filter((item) => item.accountId === accountId),
    [accountId, orgTree.assignments],
  )
  const primaryAssignment = useMemo(
    () => accountAssignments.find((item) => item.isPrimary) || accountAssignments[0] || null,
    [accountAssignments],
  )
  const assignmentUnitId = assignmentDraft.orgUnitId || primaryAssignment?.orgUnitId || account?.orgUnitId || orgTree.units[0]?.id || ''
  const assignmentPositions = useMemo(
    () => orgTree.positions.filter((position) => position.orgUnitId === assignmentUnitId),
    [assignmentUnitId, orgTree.positions],
  )
  const primaryUnit = useMemo(
    () => orgTree.units.find((unit) => unit.id === (primaryAssignment?.orgUnitId || account?.orgUnitId || '')) || null,
    [account?.orgUnitId, orgTree.units, primaryAssignment?.orgUnitId],
  )
  const primaryPosition = useMemo(
    () => orgTree.positions.find((position) => position.id === (primaryAssignment?.positionId || account?.positionId || '')) || null,
    [account?.positionId, orgTree.positions, primaryAssignment?.positionId],
  )

  async function reload() {
    setLoading(true)
    try {
      const [accountResult, roleResult, orgResult, logResult, effectiveResult, catalogResult] = await Promise.allSettled([
        backend.adminStaffAccount(accountId),
        backend.adminStaffRoles(),
        backend.adminOrgTree(),
        backend.adminStaffAuditLogs({ search: accountId }),
        backend.adminStaffEffectivePermissions(accountId),
        backend.adminPermissionCatalog(),
      ])
      if (accountResult.status !== 'fulfilled') throw accountResult.reason
      setAccount(accountResult.value)
      setDraft(draftFromAccount(accountResult.value))
      setRoles(roleResult.status === 'fulfilled' ? roleResult.value.items : [])
      setOrgTree(orgResult.status === 'fulfilled' ? orgResult.value : blankTree())
      setAssignmentDraft(assignmentDraftFrom(accountResult.value, orgResult.status === 'fulfilled' ? orgResult.value.assignments : []))
      setLogs(logResult.status === 'fulfilled' ? logResult.value.items : [])
      setEffectivePermissions(effectiveResult.status === 'fulfilled' ? effectiveResult.value : null)
      setDirectPermissionText(effectiveResult.status === 'fulfilled' ? effectiveResult.value.directPermissions.join('\n') : '')
      setPermissionCatalog(catalogResult.status === 'fulfilled' ? catalogResult.value.items.filter((item) => item.code !== '*') : [])
      setError('')
    } catch (err) {
      setError(err instanceof Error ? err.message : '员工详情加载失败')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void reload()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [accountId])

  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    if (!draft) return
    setSaving(true)
    setSaved('')
    setError('')
    try {
      const updated = await backend.updateAdminStaffAccount(accountId, draft)
      setAccount(updated)
      setDraft(draftFromAccount(updated))
      setSaved('员工信息已保存')
    } catch (err) {
      setError(err instanceof Error ? err.message : '员工信息保存失败')
    } finally {
      setSaving(false)
    }
  }

  async function toggleStatus() {
    if (!account) return
    setSaving(true)
    setSaved('')
    setError('')
    try {
      const updated = account.status === 'disabled'
        ? await backend.enableAdminStaffAccount(account.id)
        : await backend.disableAdminStaffAccount(account.id)
      setAccount(updated)
      setDraft(draftFromAccount(updated))
      setSaved(updated.status === 'disabled' ? '员工已禁用' : '员工已恢复')
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : '员工状态更新失败')
    } finally {
      setSaving(false)
    }
  }

  function updateAssignmentUnit(orgUnitId: string) {
    const position = orgTree.positions.find((item) => item.orgUnitId === orgUnitId)
    setAssignmentDraft({
      orgUnitId,
      positionId: position?.id || '',
      roleCode: position?.roleCode || draft?.role || account?.role || '',
    })
  }

  function updateAssignmentPosition(positionId: string) {
    const position = orgTree.positions.find((item) => item.id === positionId)
    setAssignmentDraft((current) => ({
      ...current,
      positionId,
      roleCode: position?.roleCode || current.roleCode,
    }))
  }

  async function savePrimaryAssignment() {
    if (!account) return
    const orgUnitId = assignmentDraft.orgUnitId || primaryAssignment?.orgUnitId || account.orgUnitId || ''
    const roleCode = assignmentDraft.roleCode || primaryAssignment?.roleCode || account.role || ''
    if (!orgUnitId || !roleCode) {
      setError('请选择部门和角色')
      return
    }
    setSavingAssignment(true)
    setSaved('')
    setError('')
    try {
      await backend.createAdminStaffAssignment({
        accountId: account.id,
        orgUnitId,
        positionId: assignmentDraft.positionId || null,
        roleCode,
        isPrimary: true,
      })
      setSaved('主岗位归属已保存')
      await reload()
    } catch (err) {
      setError(err instanceof Error ? err.message : '主岗位归属保存失败')
    } finally {
      setSavingAssignment(false)
    }
  }

  async function saveDirectPermissions() {
    if (!account) return
    const allowed = new Set(permissionCatalog.map((item) => item.code))
    const permissions = directPermissionText
      .split(/[,\n，；; ]+/)
      .map((item) => item.trim())
      .filter((item) => item && allowed.has(item))
    setSavingDirectPermissions(true)
    setSaved('')
    setError('')
    try {
      const next = await backend.saveAdminStaffDirectPermissions(account.id, Array.from(new Set(permissions)))
      setEffectivePermissions(next)
      setDirectPermissionText(next.directPermissions.join('\n'))
      setSaved('员工特殊授权已保存')
    } catch (err) {
      setError(err instanceof Error ? err.message : '特殊授权保存失败')
    } finally {
      setSavingDirectPermissions(false)
    }
  }

  return (
    <AdminShell title="员工账号详情" description="维护后台员工账号、组织岗位归属、特殊授权和负责事项。">
      <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
        <Link href="/admin/staff-accounts" 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">
          <ArrowLeft className="h-4 w-4" />
          返回员工账号
        </Link>
        <button type="button" onClick={() => void reload()} 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" />
          刷新
        </button>
      </div>

      {(saved || error) && (
        <div className={`mb-3 rounded-[4px] px-4 py-3 text-sm font-bold ${error ? 'bg-red-50 text-red-700' : 'bg-green-50 text-green'}`}>
          {error || saved}
        </div>
      )}

      {loading && <div className="border border-line bg-white px-5 py-8 text-sm font-bold text-muted">正在加载员工详情...</div>}
      {!loading && account && draft && (
        <div className="grid h-[calc(100vh-150px)] min-h-[560px] gap-3 overflow-hidden xl:grid-cols-[minmax(0,1fr)_360px]">
          <form onSubmit={submit} className="min-h-0 overflow-y-auto border border-line bg-white">
            <div className="grid gap-3 px-4 py-4 lg:grid-cols-2">
              <label className="block">
                <span className="mb-1.5 block text-xs font-bold text-ink">姓名</span>
                <input value={draft.displayName} onChange={(event) => setDraft({ ...draft, displayName: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
              </label>
              <label className="block">
                <span className="mb-1.5 block text-xs font-bold text-ink">手机号</span>
                <input value={draft.phone} onChange={(event) => setDraft({ ...draft, phone: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
              </label>
              <label className="block">
                <span className="mb-1.5 block text-xs font-bold text-ink">兼容角色缓存</span>
                <select value={draft.role} onChange={(event) => setDraft({ ...draft, role: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-3 text-sm font-bold outline-none focus:border-brand">
                  {roleOptions.map((role) => <option key={role.code} value={role.code}>{role.name}</option>)}
                </select>
              </label>
              <label className="block">
                <span className="mb-1.5 block text-xs font-bold text-ink">岗位称谓</span>
                <input value={draft.positionTitle} onChange={(event) => setDraft({ ...draft, positionTitle: event.target.value })} className="h-9 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
              </label>
              <label className="block">
                <span className="mb-1.5 block text-xs font-bold text-ink">状态</span>
                <select value={draft.status} onChange={(event) => setDraft({ ...draft, status: event.target.value as StaffDraft['status'] })} className="h-9 w-full rounded-[4px] border border-line px-3 text-sm font-bold outline-none focus:border-brand">
                  <option value="active">启用</option>
                  <option value="disabled">禁用</option>
                </select>
              </label>
              <label className="block lg:col-span-2">
                <span className="mb-1.5 block text-xs font-bold text-ink">备注</span>
                <textarea value={draft.remark} onChange={(event) => setDraft({ ...draft, remark: event.target.value })} className="min-h-[88px] w-full rounded-[4px] border border-line px-3 py-2 text-sm outline-none focus:border-brand" />
              </label>
            </div>
            <div className="flex flex-wrap justify-between gap-3 border-t border-line px-4 py-3">
              <button type="button" onClick={() => void toggleStatus()} disabled={saving} className="inline-flex h-10 items-center gap-2 rounded-[4px] border border-line px-4 text-sm font-extrabold text-muted hover:border-brand hover:text-brand disabled:bg-line-dark">
                {account.status === 'disabled' ? <BadgeCheck className="h-4 w-4" /> : <Ban className="h-4 w-4" />}
                {account.status === 'disabled' ? '恢复员工' : '禁用员工'}
              </button>
              <button disabled={saving} className="inline-flex h-10 items-center gap-2 rounded-[4px] bg-brand px-4 text-sm font-extrabold text-white hover:bg-brand-dark disabled:bg-line-dark">
                <Save className="h-4 w-4" />
                {saving ? '保存中...' : '保存修改'}
              </button>
            </div>
          </form>

          <aside className="min-h-0 space-y-3 overflow-y-auto pr-1">
            <section className="border border-line bg-white p-4">
              <h2 className="mb-3 text-sm font-extrabold text-ink">账号状态</h2>
              <div className="grid gap-1.5 text-xs font-bold text-muted">
                <div>岗位：{account.roleName || account.role}</div>
                <div>入口：{account.defaultEntry || '-'}</div>
                <div>主部门：{primaryUnit?.name || '-'}</div>
                <div>主岗位：{primaryPosition?.name || primaryAssignment?.positionName || '-'}</div>
                <div>最近登录：{formatDate(account.lastLoginAt)}</div>
                <div>创建时间：{formatDate(account.createdAt)}</div>
                <div>更新时间：{formatDate(account.updatedAt)}</div>
              </div>
            </section>

            <section className="border border-line bg-white p-4">
              <h2 className="mb-3 text-sm font-extrabold text-ink">组织归属</h2>
              <div className="grid gap-2">
                <select value={assignmentDraft.orgUnitId || assignmentUnitId} onChange={(event) => updateAssignmentUnit(event.target.value)} className="h-9 w-full border border-line px-2.5 text-xs font-bold outline-none focus:border-brand">
                  <option value="">选择部门</option>
                  {orgTree.units.map((unit) => <option key={unit.id} value={unit.id}>{'　'.repeat(Math.min(unit.depth, 4))}{unit.name}</option>)}
                </select>
                <select value={assignmentDraft.positionId || ''} onChange={(event) => updateAssignmentPosition(event.target.value)} className="h-9 w-full border border-line px-2.5 text-xs font-bold outline-none focus:border-brand">
                  <option value="">不指定岗位</option>
                  {assignmentPositions.map((position) => <option key={position.id} value={position.id}>{position.name}</option>)}
                </select>
                <select value={assignmentDraft.roleCode || draft.role} onChange={(event) => setAssignmentDraft((current) => ({ ...current, roleCode: event.target.value }))} className="h-9 w-full border border-line px-2.5 text-xs font-bold outline-none focus:border-brand">
                  <option value="">选择角色</option>
                  {roleOptions.map((role) => <option key={role.code} value={role.code}>{role.name}</option>)}
                </select>
                <button type="button" onClick={() => void savePrimaryAssignment()} disabled={savingAssignment} className="h-9 rounded-[4px] bg-ink px-3 text-xs font-extrabold text-white disabled:bg-line-dark">
                  {savingAssignment ? '保存中...' : '保存为主岗位'}
                </button>
              </div>
              <div className="mt-3 space-y-1.5">
                {accountAssignments.length === 0 ? (
                  <div className="border border-dashed border-line px-3 py-4 text-center text-xs font-bold text-muted">暂无组织归属</div>
                ) : accountAssignments.map((item) => (
                  <div key={item.id} className="border border-line px-3 py-2 text-xs font-bold text-muted">
                    <div className="flex items-center justify-between gap-2">
                      <span className="font-extrabold text-ink">{item.orgUnitName || '-'}</span>
                      {item.isPrimary && <span className="rounded-[4px] bg-brand-light px-2 py-0.5 text-[10px] text-brand">主岗</span>}
                    </div>
                    <div className="mt-1">{item.positionName || item.roleName || item.roleCode}</div>
                  </div>
                ))}
              </div>
            </section>

            <section className="border border-line bg-white p-4">
              <h2 className="mb-3 text-sm font-extrabold text-ink">任务与负责事项</h2>
              <div className="grid grid-cols-2 gap-2">
                {responsibilityItems.map((item) => (
                  <div key={item.label} className="border border-line bg-bg px-3 py-2">
                    <div className="text-[11px] font-bold text-soft">{item.label}</div>
                    <div className="mt-1 text-xl font-extrabold text-ink">{item.value}</div>
                  </div>
                ))}
              </div>
            </section>

            <section className="border border-line bg-white p-4">
              <h2 className="mb-3 text-sm font-extrabold text-ink">有效权限来源</h2>
              {effectivePermissions ? (
                <div className="grid grid-cols-2 gap-2">
                  <PermissionCount label="角色权限" value={effectivePermissions.rolePermissions.length} />
                  <PermissionCount label="部门继承" value={effectivePermissions.orgPermissions.length} />
                  <PermissionCount label="岗位附加" value={effectivePermissions.positionPermissions.length} />
                  <PermissionCount label="特殊授权" value={effectivePermissions.directPermissions.length} />
                  <div className="col-span-2 border border-line bg-bg px-3 py-2">
                    <div className="text-[11px] font-bold text-soft">最终有效权限</div>
                    <div className="mt-1 text-xl font-extrabold text-ink">{effectivePermissions.effectivePermissions.includes('*') ? '全部' : effectivePermissions.effectivePermissions.length}</div>
                  </div>
                </div>
              ) : (
                <div className="border border-dashed border-line px-3 py-6 text-center text-sm font-bold text-muted">权限来源暂不可用</div>
              )}
            </section>

            <section className="border border-line bg-white p-4">
              <h2 className="mb-2 text-sm font-extrabold text-ink">员工特殊授权</h2>
              <p className="mb-3 text-xs font-bold leading-5 text-muted">这里只处理单账号例外。常规权限请在“角色与权限”统一维护。</p>
              <textarea
                value={directPermissionText}
                onChange={(event) => setDirectPermissionText(event.target.value)}
                placeholder="每行一个权限代码，如 data_service:update"
                className="min-h-[96px] w-full border border-line px-3 py-2 text-xs font-bold outline-none focus:border-brand"
              />
              <button type="button" onClick={() => void saveDirectPermissions()} disabled={savingDirectPermissions} className="mt-2 h-9 rounded-[4px] bg-ink px-3 text-xs font-extrabold text-white disabled:bg-line-dark">
                {savingDirectPermissions ? '保存中...' : '保存特殊授权'}
              </button>
            </section>

            <section className="border border-line bg-white p-4">
              <h2 className="mb-3 text-sm font-extrabold text-ink">相关操作记录</h2>
              {logs.length === 0 ? (
                <div className="border border-dashed border-line px-3 py-6 text-center text-sm font-bold text-muted">暂无记录</div>
              ) : (
                <div className="space-y-2">
                  {logs.slice(0, 8).map((log) => (
                    <div key={log.id} className="border border-line px-3 py-2">
                      <div className="text-sm font-bold text-ink">{log.summary || log.action}</div>
                      <div className="mt-1 text-xs font-bold text-muted">{log.actorName || log.actorEmail || '-'} · {formatDate(log.createdAt)}</div>
                    </div>
                  ))}
                </div>
              )}
            </section>
          </aside>
        </div>
      )}
    </AdminShell>
  )
}

function PermissionCount({ label, value }: { label: string; value: number }) {
  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 text-xl font-extrabold text-ink">{value}</div>
    </div>
  )
}
