import { useState, useEffect, useCallback, useRef } from 'react'
import { useSubMenu } from '../../hooks/useSubMenu'
import data from '@emoji-mart/data'
import EmojiPicker from '@emoji-mart/react'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragOverlay,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import {
  fetchUsers,
  fetchRoles,
  updatePermissionsApi,
  updateUserApi,
  updateRoleDefaultApi,
  approveUserApi,
  rejectUserApi,
  assignRolesApi,
  createRoleApi,
  updateRoleApi,
  deleteRoleApi,
  fetchRegistrationSettings,
  updateRegistrationSettingsApi,
  fetchOAuthSettings,
  updateOAuthSettingsApi,
  fetchMenuConfig,
  updateMenuConfigApi,
  type UserListItem,
  type RoleWithPermissions,
  type RegistrationSettings,
  type OAuthSettings,
  type MenuConfigItem,
} from '../../services/authApi'
import { useMenuStore } from '../../store/menuStore'

const DEFAULT_ROLE_COLORS: Record<string, string> = {
  ADMIN: 'var(--red)',
  MANAGER: 'var(--orange)',
  USER: 'var(--cyan)',
  VIEWER: 'var(--t3)',
}

const CUSTOM_ROLE_COLORS = [
  '#a78bfa', '#34d399', '#f472b6', '#fbbf24', '#60a5fa', '#2dd4bf',
]

function getRoleColor(code: string, index: number): string {
  return DEFAULT_ROLE_COLORS[code] || CUSTOM_ROLE_COLORS[index % CUSTOM_ROLE_COLORS.length]
}

const statusLabels: Record<string, { label: string; color: string; dot: string }> = {
  PENDING: { label: '승인대기', color: 'text-yellow-400', dot: 'bg-yellow-400' },
  ACTIVE: { label: '활성', color: 'text-green-400', dot: 'bg-green-400' },
  LOCKED: { label: '잠김', color: 'text-red-400', dot: 'bg-red-400' },
  INACTIVE: { label: '비활성', color: 'text-text-3', dot: 'bg-text-3' },
  REJECTED: { label: '거절됨', color: 'text-red-300', dot: 'bg-red-300' },
}


// ─── 사용자 관리 패널 ─────────────────────────────────────────
function UsersPanel() {
  const [searchTerm, setSearchTerm] = useState('')
  const [statusFilter, setStatusFilter] = useState<string>('')
  const [users, setUsers] = useState<UserListItem[]>([])
  const [loading, setLoading] = useState(true)
  const [allRoles, setAllRoles] = useState<RoleWithPermissions[]>([])
  const [roleEditUserId, setRoleEditUserId] = useState<string | null>(null)
  const [selectedRoleSns, setSelectedRoleSns] = useState<number[]>([])
  const roleDropdownRef = useRef<HTMLDivElement>(null)

  const loadUsers = useCallback(async () => {
    setLoading(true)
    try {
      const data = await fetchUsers(searchTerm || undefined, statusFilter || undefined)
      setUsers(data)
    } catch (err) {
      console.error('사용자 목록 조회 실패:', err)
    } finally {
      setLoading(false)
    }
  }, [searchTerm, statusFilter])

  useEffect(() => {
    loadUsers()
  }, [loadUsers])

  useEffect(() => {
    fetchRoles().then(setAllRoles).catch(console.error)
  }, [])

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (roleDropdownRef.current && !roleDropdownRef.current.contains(e.target as Node)) {
        setRoleEditUserId(null)
      }
    }
    if (roleEditUserId) {
      document.addEventListener('mousedown', handleClickOutside)
    }
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [roleEditUserId])

  const handleUnlock = async (userId: string) => {
    try {
      await updateUserApi(userId, { status: 'ACTIVE' })
      await loadUsers()
    } catch (err) {
      console.error('계정 잠금 해제 실패:', err)
    }
  }

  const handleApprove = async (userId: string) => {
    try {
      await approveUserApi(userId)
      await loadUsers()
    } catch (err) {
      console.error('사용자 승인 실패:', err)
    }
  }

  const handleReject = async (userId: string) => {
    try {
      await rejectUserApi(userId)
      await loadUsers()
    } catch (err) {
      console.error('사용자 거절 실패:', err)
    }
  }

  const handleDeactivate = async (userId: string) => {
    try {
      await updateUserApi(userId, { status: 'INACTIVE' })
      await loadUsers()
    } catch (err) {
      console.error('사용자 비활성화 실패:', err)
    }
  }

  const handleActivate = async (userId: string) => {
    try {
      await updateUserApi(userId, { status: 'ACTIVE' })
      await loadUsers()
    } catch (err) {
      console.error('사용자 활성화 실패:', err)
    }
  }

  const handleOpenRoleEdit = (user: UserListItem) => {
    setRoleEditUserId(user.id)
    setSelectedRoleSns(user.roleSns || [])
  }

  const toggleRoleSelection = (roleSn: number) => {
    setSelectedRoleSns(prev =>
      prev.includes(roleSn) ? prev.filter(s => s !== roleSn) : [...prev, roleSn]
    )
  }

  const handleSaveRoles = async (userId: string) => {
    try {
      await assignRolesApi(userId, selectedRoleSns)
      await loadUsers()
      setRoleEditUserId(null)
    } catch (err) {
      console.error('역할 할당 실패:', err)
    }
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString('ko-KR', {
      year: 'numeric', month: '2-digit', day: '2-digit',
      hour: '2-digit', minute: '2-digit',
    })
  }

  const pendingCount = users.filter(u => u.status === 'PENDING').length

  return (
    <div className="flex flex-col h-full">
      <div className="flex items-center justify-between px-6 py-4 border-b border-border">
        <div className="flex items-center gap-3">
          <div>
            <h1 className="text-lg font-bold text-text-1 font-korean">사용자 관리</h1>
            <p className="text-xs text-text-3 mt-1 font-korean">총 {users.length}명</p>
          </div>
          {pendingCount > 0 && (
            <span className="px-2.5 py-1 text-[10px] font-bold rounded-full bg-[rgba(250,204,21,0.15)] text-yellow-400 border border-[rgba(250,204,21,0.3)] animate-pulse font-korean">
              승인대기 {pendingCount}명
            </span>
          )}
        </div>
        <div className="flex items-center gap-3">
          <select
            value={statusFilter}
            onChange={(e) => setStatusFilter(e.target.value)}
            className="px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 focus:border-primary-cyan focus:outline-none font-korean"
          >
            <option value="">전체 상태</option>
            <option value="PENDING">승인대기</option>
            <option value="ACTIVE">활성</option>
            <option value="LOCKED">잠김</option>
            <option value="INACTIVE">비활성</option>
            <option value="REJECTED">거절됨</option>
          </select>
          <input
            type="text"
            placeholder="이름, 계정 검색..."
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            className="w-56 px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 placeholder-text-3 focus:border-primary-cyan focus:outline-none font-korean"
          />
          <button className="px-4 py-2 text-xs font-semibold rounded-md bg-primary-cyan text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)] transition-all font-korean">
            + 사용자 추가
          </button>
        </div>
      </div>

      <div className="flex-1 overflow-auto">
        {loading ? (
          <div className="flex items-center justify-center h-32 text-text-3 text-sm font-korean">불러오는 중...</div>
        ) : (
          <table className="w-full">
            <thead>
              <tr className="border-b border-border bg-bg-1">
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">이름</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">계정</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">소속</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">역할</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">인증</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">상태</th>
                <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean">최근 로그인</th>
                <th className="px-6 py-3 text-right text-[11px] font-semibold text-text-3 font-korean">관리</th>
              </tr>
            </thead>
            <tbody>
              {users.map((user) => {
                const statusInfo = statusLabels[user.status] || statusLabels.INACTIVE
                return (
                  <tr key={user.id} className="border-b border-border hover:bg-[rgba(255,255,255,0.02)] transition-colors">
                    <td className="px-6 py-3 text-[12px] text-text-1 font-semibold font-korean">{user.name}</td>
                    <td className="px-6 py-3 text-[12px] text-text-2 font-mono">{user.account}</td>
                    <td className="px-6 py-3 text-[12px] text-text-2 font-korean">{user.orgAbbr || '-'}</td>
                    <td className="px-6 py-3">
                      <div className="relative">
                        <div
                          className="flex flex-wrap gap-1 cursor-pointer"
                          onClick={() => handleOpenRoleEdit(user)}
                          title="클릭하여 역할 변경"
                        >
                          {user.roles.length > 0 ? user.roles.map((roleCode, idx) => {
                            const color = getRoleColor(roleCode, idx)
                            const roleName = allRoles.find(r => r.code === roleCode)?.name || roleCode
                            return (
                              <span
                                key={roleCode}
                                className="px-2 py-0.5 text-[10px] font-semibold rounded-md font-korean"
                                style={{
                                  background: `${color}20`,
                                  color: color,
                                  border: `1px solid ${color}40`
                                }}
                              >
                                {roleName}
                              </span>
                            )
                          }) : (
                            <span className="text-[10px] text-text-3 font-korean">역할 없음</span>
                          )}
                          <span className="text-[10px] text-text-3 ml-0.5">
                            <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
                          </span>
                        </div>
                        {roleEditUserId === user.id && (
                          <div
                            ref={roleDropdownRef}
                            className="absolute z-20 top-full left-0 mt-1 p-2 bg-bg-1 border border-border rounded-lg shadow-lg min-w-[200px]"
                          >
                            <div className="text-[10px] text-text-3 font-korean font-semibold mb-1.5 px-1">역할 선택</div>
                            {allRoles.map((role, idx) => {
                              const color = getRoleColor(role.code, idx)
                              return (
                                <label key={role.sn} className="flex items-center gap-2 px-2 py-1.5 hover:bg-[rgba(255,255,255,0.04)] rounded cursor-pointer">
                                  <input
                                    type="checkbox"
                                    checked={selectedRoleSns.includes(role.sn)}
                                    onChange={() => toggleRoleSelection(role.sn)}
                                    style={{ accentColor: color }}
                                  />
                                  <span className="text-xs font-korean" style={{ color }}>{role.name}</span>
                                  <span className="text-[10px] text-text-3 font-mono">{role.code}</span>
                                </label>
                              )
                            })}
                            <div className="flex justify-end gap-2 mt-2 pt-2 border-t border-border">
                              <button
                                onClick={() => setRoleEditUserId(null)}
                                className="px-3 py-1 text-[10px] text-text-3 border border-border rounded hover:bg-bg-hover font-korean"
                              >
                                취소
                              </button>
                              <button
                                onClick={() => handleSaveRoles(user.id)}
                                disabled={selectedRoleSns.length === 0}
                                className="px-3 py-1 text-[10px] font-semibold rounded bg-primary-cyan text-bg-0 hover:shadow-[0_0_8px_rgba(6,182,212,0.3)] disabled:opacity-50 font-korean"
                              >
                                저장
                              </button>
                            </div>
                          </div>
                        )}
                      </div>
                    </td>
                    <td className="px-6 py-3">
                      {user.oauthProvider ? (
                        <span
                          className="inline-flex items-center gap-1 px-2 py-1 text-[10px] font-semibold rounded-md font-mono"
                          style={{ background: 'rgba(66,133,244,0.15)', color: '#4285F4', border: '1px solid rgba(66,133,244,0.3)' }}
                          title={user.email || undefined}
                        >
                          <svg width="10" height="10" viewBox="0 0 48 48"><path fill="#4285F4" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#34A853" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59A14.5 14.5 0 019.5 24c0-1.59.28-3.14.76-4.59l-7.98-6.19A23.99 23.99 0 000 24c0 3.77.9 7.35 2.56 10.54l7.97-5.95z"/><path fill="#EA4335" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 5.95C6.51 42.62 14.62 48 24 48z"/></svg>
                          Google
                        </span>
                      ) : (
                        <span
                          className="inline-flex items-center gap-1 px-2 py-1 text-[10px] font-semibold rounded-md font-korean"
                          style={{ background: 'rgba(148,163,184,0.15)', color: 'var(--t3)', border: '1px solid rgba(148,163,184,0.2)' }}
                        >
                          <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>
                          ID/PW
                        </span>
                      )}
                    </td>
                    <td className="px-6 py-3">
                      <span className={`inline-flex items-center gap-1.5 text-[10px] font-semibold font-korean ${statusInfo.color}`}>
                        <span className={`w-1.5 h-1.5 rounded-full ${statusInfo.dot}`} />
                        {statusInfo.label}
                      </span>
                    </td>
                    <td className="px-6 py-3 text-[11px] text-text-3 font-mono">{formatDate(user.lastLogin)}</td>
                    <td className="px-6 py-3 text-right">
                      <div className="flex items-center justify-end gap-2">
                        {user.status === 'PENDING' && (
                          <>
                            <button
                              onClick={() => handleApprove(user.id)}
                              className="px-2 py-1 text-[10px] font-semibold text-green-400 border border-green-400 rounded hover:bg-[rgba(74,222,128,0.1)] transition-all font-korean"
                            >
                              승인
                            </button>
                            <button
                              onClick={() => handleReject(user.id)}
                              className="px-2 py-1 text-[10px] font-semibold text-red-400 border border-red-400 rounded hover:bg-[rgba(248,113,113,0.1)] transition-all font-korean"
                            >
                              거절
                            </button>
                          </>
                        )}
                        {user.status === 'LOCKED' && (
                          <button
                            onClick={() => handleUnlock(user.id)}
                            className="px-2 py-1 text-[10px] font-semibold text-yellow-400 border border-yellow-400 rounded hover:bg-[rgba(250,204,21,0.1)] transition-all font-korean"
                          >
                            잠금해제
                          </button>
                        )}
                        {user.status === 'ACTIVE' && (
                          <button
                            onClick={() => handleDeactivate(user.id)}
                            className="px-2 py-1 text-[10px] font-semibold text-text-3 border border-border rounded hover:bg-[rgba(255,255,255,0.04)] transition-all font-korean"
                          >
                            비활성화
                          </button>
                        )}
                        {(user.status === 'INACTIVE' || user.status === 'REJECTED') && (
                          <button
                            onClick={() => handleActivate(user.id)}
                            className="px-2 py-1 text-[10px] font-semibold text-green-400 border border-green-400 rounded hover:bg-[rgba(74,222,128,0.1)] transition-all font-korean"
                          >
                            활성화
                          </button>
                        )}
                      </div>
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  )
}

// ─── 권한 관리 패널 ─────────────────────────────────────────
const PERM_RESOURCES = [
  { id: 'prediction', label: '유출유 확산예측', desc: '확산 예측 실행 및 결과 조회' },
  { id: 'hns', label: 'HNS·대기확산', desc: '대기확산 분석 실행 및 조회' },
  { id: 'rescue', label: '긴급구난', desc: '구난 예측 실행 및 조회' },
  { id: 'reports', label: '보고자료', desc: '보고자료 생성 및 관리' },
  { id: 'aerial', label: '항공탐색', desc: '항공탐색 계획 및 결과 조회' },
  { id: 'assets', label: '방제자산 관리', desc: '방제자산 등록 및 관리' },
  { id: 'scat', label: '해안평가', desc: '해안 SCAT 조사 접근' },
  { id: 'incidents', label: '사고조회', desc: '사고 정보 등록 및 조회' },
  { id: 'board', label: '게시판', desc: '게시판 접근' },
  { id: 'weather', label: '기상정보', desc: '기상 정보 조회' },
  { id: 'admin', label: '관리자 설정', desc: '시스템 관리 기능 접근' },
]

function PermissionsPanel() {
  const [roles, setRoles] = useState<RoleWithPermissions[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [dirty, setDirty] = useState(false)
  const [showCreateForm, setShowCreateForm] = useState(false)
  const [newRoleCode, setNewRoleCode] = useState('')
  const [newRoleName, setNewRoleName] = useState('')
  const [newRoleDesc, setNewRoleDesc] = useState('')
  const [creating, setCreating] = useState(false)
  const [createError, setCreateError] = useState('')
  const [editingRoleSn, setEditingRoleSn] = useState<number | null>(null)
  const [editRoleName, setEditRoleName] = useState('')

  useEffect(() => {
    loadRoles()
  }, [])

  const loadRoles = async () => {
    setLoading(true)
    try {
      const data = await fetchRoles()
      setRoles(data)
      setDirty(false)
    } catch (err) {
      console.error('역할 목록 조회 실패:', err)
    } finally {
      setLoading(false)
    }
  }

  const getPermGranted = (roleSn: number, resourceCode: string): boolean => {
    const role = roles.find(r => r.sn === roleSn)
    if (!role) return false
    const perm = role.permissions.find(p => p.resourceCode === resourceCode)
    return perm?.granted ?? false
  }

  const togglePerm = (roleSn: number, resourceCode: string) => {
    setRoles(prev => prev.map(role => {
      if (role.sn !== roleSn) return role
      const perms = role.permissions.map(p =>
        p.resourceCode === resourceCode ? { ...p, granted: !p.granted } : p
      )
      if (!perms.find(p => p.resourceCode === resourceCode)) {
        perms.push({ sn: 0, resourceCode, granted: true })
      }
      return { ...role, permissions: perms }
    }))
    setDirty(true)
  }

  const toggleDefault = async (roleSn: number) => {
    const role = roles.find(r => r.sn === roleSn)
    if (!role) return
    const newValue = !role.isDefault
    try {
      await updateRoleDefaultApi(roleSn, newValue)
      setRoles(prev => prev.map(r =>
        r.sn === roleSn ? { ...r, isDefault: newValue } : r
      ))
    } catch (err) {
      console.error('기본 역할 변경 실패:', err)
    }
  }

  const handleSave = async () => {
    setSaving(true)
    try {
      for (const role of roles) {
        const permissions = PERM_RESOURCES.map(r => ({
          resourceCode: r.id,
          granted: getPermGranted(role.sn, r.id),
        }))
        await updatePermissionsApi(role.sn, permissions)
      }
      setDirty(false)
    } catch (err) {
      console.error('권한 저장 실패:', err)
    } finally {
      setSaving(false)
    }
  }

  const handleCreateRole = async () => {
    setCreating(true)
    setCreateError('')
    try {
      await createRoleApi({ code: newRoleCode, name: newRoleName, description: newRoleDesc || undefined })
      await loadRoles()
      setShowCreateForm(false)
      setNewRoleCode('')
      setNewRoleName('')
      setNewRoleDesc('')
    } catch (err) {
      const message = err instanceof Error ? err.message : '역할 생성에 실패했습니다.'
      setCreateError(message)
    } finally {
      setCreating(false)
    }
  }

  const handleDeleteRole = async (roleSn: number, roleName: string) => {
    if (!window.confirm(`"${roleName}" 역할을 삭제하시겠습니까?\n이 역할을 가진 모든 사용자에서 해당 역할이 제거됩니다.`)) {
      return
    }
    try {
      await deleteRoleApi(roleSn)
      await loadRoles()
    } catch (err) {
      console.error('역할 삭제 실패:', err)
    }
  }

  const handleStartEditName = (role: RoleWithPermissions) => {
    setEditingRoleSn(role.sn)
    setEditRoleName(role.name)
  }

  const handleSaveRoleName = async (roleSn: number) => {
    if (!editRoleName.trim()) return
    try {
      await updateRoleApi(roleSn, { name: editRoleName.trim() })
      setRoles(prev => prev.map(r =>
        r.sn === roleSn ? { ...r, name: editRoleName.trim() } : r
      ))
      setEditingRoleSn(null)
    } catch (err) {
      console.error('역할 이름 수정 실패:', err)
    }
  }

  if (loading) {
    return <div className="flex items-center justify-center h-32 text-text-3 text-sm font-korean">불러오는 중...</div>
  }

  return (
    <div className="flex flex-col h-full">
      <div className="flex items-center justify-between px-6 py-4 border-b border-border">
        <div>
          <h1 className="text-lg font-bold text-text-1 font-korean">사용자 권한 관리</h1>
          <p className="text-xs text-text-3 mt-1 font-korean">역할별 메뉴 접근 권한을 설정합니다</p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => { setShowCreateForm(true); setCreateError('') }}
            className="px-4 py-2 text-xs font-semibold rounded-md border border-primary-cyan text-primary-cyan hover:bg-[rgba(6,182,212,0.08)] transition-all font-korean"
          >
            + 역할 추가
          </button>
          <button
            onClick={handleSave}
            disabled={!dirty || saving}
            className={`px-4 py-2 text-xs font-semibold rounded-md transition-all font-korean ${
              dirty ? 'bg-primary-cyan text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)]' : 'bg-bg-3 text-text-3 cursor-not-allowed'
            }`}
          >
            {saving ? '저장 중...' : '변경사항 저장'}
          </button>
        </div>
      </div>

      <div className="flex-1 overflow-auto">
        <table className="w-full">
          <thead>
            <tr className="border-b border-border bg-bg-1">
              <th className="px-6 py-3 text-left text-[11px] font-semibold text-text-3 font-korean min-w-[200px]">기능</th>
              {roles.map((role, idx) => {
                const color = getRoleColor(role.code, idx)
                return (
                  <th key={role.sn} className="px-4 py-3 text-center min-w-[100px]">
                    <div className="flex items-center justify-center gap-1">
                      {editingRoleSn === role.sn ? (
                        <input
                          type="text"
                          value={editRoleName}
                          onChange={(e) => setEditRoleName(e.target.value)}
                          onKeyDown={(e) => {
                            if (e.key === 'Enter') handleSaveRoleName(role.sn)
                            if (e.key === 'Escape') setEditingRoleSn(null)
                          }}
                          onBlur={() => handleSaveRoleName(role.sn)}
                          autoFocus
                          className="w-20 px-1 py-0.5 text-[11px] font-semibold bg-bg-2 border border-primary-cyan rounded text-center text-text-1 focus:outline-none font-korean"
                        />
                      ) : (
                        <span
                          className="text-[11px] font-semibold font-korean cursor-pointer hover:underline"
                          style={{ color }}
                          onClick={() => handleStartEditName(role)}
                          title="클릭하여 이름 수정"
                        >
                          {role.name}
                        </span>
                      )}
                      {role.code !== 'ADMIN' && (
                        <button
                          onClick={() => handleDeleteRole(role.sn, role.name)}
                          className="w-4 h-4 flex items-center justify-center text-text-3 hover:text-red-400 transition-colors"
                          title="역할 삭제"
                        >
                          <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                        </button>
                      )}
                    </div>
                    <div className="text-[9px] text-text-3 font-mono mt-0.5">{role.code}</div>
                    <button
                      onClick={() => toggleDefault(role.sn)}
                      className={`mt-1 px-1.5 py-0.5 text-[9px] rounded transition-all font-korean ${
                        role.isDefault
                          ? 'bg-[rgba(6,182,212,0.15)] text-primary-cyan border border-primary-cyan'
                          : 'text-text-3 border border-transparent hover:border-border'
                      }`}
                      title="신규 사용자에게 자동 할당되는 기본 역할"
                    >
                      {role.isDefault ? '기본역할' : '기본역할 설정'}
                    </button>
                  </th>
                )
              })}
            </tr>
          </thead>
          <tbody>
            {PERM_RESOURCES.map((perm) => (
              <tr key={perm.id} className="border-b border-border hover:bg-[rgba(255,255,255,0.02)] transition-colors">
                <td className="px-6 py-3">
                  <div className="text-[12px] text-text-1 font-semibold font-korean">{perm.label}</div>
                  <div className="text-[10px] text-text-3 font-korean mt-0.5">{perm.desc}</div>
                </td>
                {roles.map(role => (
                  <td key={role.sn} className="px-4 py-3 text-center">
                    <button
                      onClick={() => togglePerm(role.sn, perm.id)}
                      className={`w-8 h-8 rounded-md border text-sm transition-all ${
                        getPermGranted(role.sn, perm.id)
                          ? 'bg-[rgba(6,182,212,0.15)] border-primary-cyan text-primary-cyan'
                          : 'bg-bg-2 border-border text-text-3 hover:border-text-3'
                      }`}
                    >
                      {getPermGranted(role.sn, perm.id) ? '✓' : '—'}
                    </button>
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* 역할 생성 모달 */}
      {showCreateForm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="w-[400px] bg-bg-1 rounded-lg border border-border shadow-2xl">
            <div className="px-5 py-4 border-b border-border">
              <h3 className="text-sm font-bold text-text-1 font-korean">새 역할 추가</h3>
            </div>
            <div className="px-5 py-4 flex flex-col gap-3">
              <div>
                <label className="text-[11px] text-text-3 font-korean block mb-1">역할 코드</label>
                <input
                  type="text"
                  value={newRoleCode}
                  onChange={(e) => setNewRoleCode(e.target.value.toUpperCase().replace(/[^A-Z0-9_]/g, ''))}
                  placeholder="CUSTOM_ROLE"
                  className="w-full px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 placeholder-text-3 focus:border-primary-cyan focus:outline-none font-mono"
                />
                <p className="text-[10px] text-text-3 mt-1 font-korean">영문 대문자, 숫자, 언더스코어만 허용 (생성 후 변경 불가)</p>
              </div>
              <div>
                <label className="text-[11px] text-text-3 font-korean block mb-1">역할 이름</label>
                <input
                  type="text"
                  value={newRoleName}
                  onChange={(e) => setNewRoleName(e.target.value)}
                  placeholder="사용자 정의 역할"
                  className="w-full px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 placeholder-text-3 focus:border-primary-cyan focus:outline-none font-korean"
                />
              </div>
              <div>
                <label className="text-[11px] text-text-3 font-korean block mb-1">설명 (선택)</label>
                <input
                  type="text"
                  value={newRoleDesc}
                  onChange={(e) => setNewRoleDesc(e.target.value)}
                  placeholder="역할에 대한 설명"
                  className="w-full px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 placeholder-text-3 focus:border-primary-cyan focus:outline-none font-korean"
                />
              </div>
              {createError && (
                <div className="px-3 py-2 text-[11px] text-red-400 bg-[rgba(239,68,68,0.08)] border border-[rgba(239,68,68,0.2)] rounded-md font-korean">
                  {createError}
                </div>
              )}
            </div>
            <div className="px-5 py-3 border-t border-border flex justify-end gap-2">
              <button
                onClick={() => setShowCreateForm(false)}
                className="px-4 py-2 text-xs text-text-3 border border-border rounded-md hover:bg-bg-hover font-korean"
              >
                취소
              </button>
              <button
                onClick={handleCreateRole}
                disabled={!newRoleCode || !newRoleName || creating}
                className="px-4 py-2 text-xs font-semibold rounded-md bg-primary-cyan text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)] transition-all font-korean disabled:opacity-50"
              >
                {creating ? '생성 중...' : '생성'}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

// ─── 메뉴 항목 (Sortable) ────────────────────────────────────
interface SortableMenuItemProps {
  menu: MenuConfigItem
  idx: number
  totalCount: number
  isEditing: boolean
  emojiPickerId: string | null
  emojiPickerRef: React.RefObject<HTMLDivElement | null>
  onToggle: (id: string) => void
  onMove: (idx: number, direction: -1 | 1) => void
  onEditStart: (id: string) => void
  onEditEnd: () => void
  onEmojiPickerToggle: (id: string | null) => void
  onLabelChange: (id: string, value: string) => void
  onEmojiSelect: (emoji: { native: string }) => void
}

function SortableMenuItem({
  menu, idx, totalCount, isEditing, emojiPickerId, emojiPickerRef,
  onToggle, onMove, onEditStart, onEditEnd, onEmojiPickerToggle, onLabelChange, onEmojiSelect,
}: SortableMenuItemProps) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: menu.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.4 : 1,
    zIndex: isDragging ? 50 : undefined,
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`flex items-center justify-between px-4 py-3 rounded-md border transition-all ${
        menu.enabled
          ? 'bg-bg-1 border-border'
          : 'bg-bg-0 border-border opacity-50'
      }`}
    >
      <div className="flex items-center gap-3 flex-1 min-w-0">
        <button
          {...attributes}
          {...listeners}
          className="cursor-grab active:cursor-grabbing w-6 h-7 flex items-center justify-center text-text-3 hover:text-text-1 transition-all shrink-0"
          title="드래그하여 순서 변경"
        >
          <svg width="12" height="16" viewBox="0 0 12 16" fill="currentColor">
            <circle cx="3" cy="2" r="1.5" /><circle cx="9" cy="2" r="1.5" />
            <circle cx="3" cy="8" r="1.5" /><circle cx="9" cy="8" r="1.5" />
            <circle cx="3" cy="14" r="1.5" /><circle cx="9" cy="14" r="1.5" />
          </svg>
        </button>
        <span className="text-text-3 text-xs font-mono w-6 text-center shrink-0">{idx + 1}</span>
        {isEditing ? (
          <>
            <div className="relative shrink-0">
              <button
                onClick={() => onEmojiPickerToggle(emojiPickerId === menu.id ? null : menu.id)}
                className="w-10 h-10 text-[20px] bg-bg-2 border border-border rounded flex items-center justify-center hover:border-primary-cyan transition-all"
                title="아이콘 변경"
              >
                {menu.icon}
              </button>
              {emojiPickerId === menu.id && (
                <div ref={emojiPickerRef} className="absolute top-12 left-0 z-[300]">
                  <EmojiPicker
                    data={data}
                    onEmojiSelect={onEmojiSelect}
                    theme="dark"
                    locale="kr"
                    previewPosition="none"
                    skinTonePosition="search"
                    perLine={8}
                  />
                </div>
              )}
            </div>
            <div className="flex-1 min-w-0">
              <input
                type="text"
                value={menu.label}
                onChange={(e) => onLabelChange(menu.id, e.target.value)}
                className="w-full h-8 text-[13px] font-semibold font-korean bg-bg-2 border border-border rounded px-2 text-text-1 focus:border-primary-cyan focus:outline-none"
              />
              <div className="text-[10px] text-text-3 font-mono mt-0.5">{menu.id}</div>
            </div>
            <button
              onClick={onEditEnd}
              className="shrink-0 px-2 py-1 text-[10px] font-semibold text-primary-cyan border border-primary-cyan rounded hover:bg-[rgba(6,182,212,0.1)] transition-all font-korean"
            >
              완료
            </button>
          </>
        ) : (
          <>
            <span className="text-[16px] shrink-0">{menu.icon}</span>
            <div className="flex-1 min-w-0">
              <div className={`text-[13px] font-semibold font-korean ${menu.enabled ? 'text-text-1' : 'text-text-3'}`}>
                {menu.label}
              </div>
              <div className="text-[10px] text-text-3 font-mono">{menu.id}</div>
            </div>
            <button
              onClick={() => onEditStart(menu.id)}
              className="shrink-0 w-7 h-7 rounded border border-border bg-bg-2 text-text-3 text-[11px] flex items-center justify-center hover:bg-bg-hover hover:text-text-1 transition-all"
              title="라벨/아이콘 편집"
            >
              ✏️
            </button>
          </>
        )}
      </div>
      <div className="flex items-center gap-3 ml-3 shrink-0">
        <button
          onClick={() => onToggle(menu.id)}
          className={`relative w-10 h-5 rounded-full transition-all ${
            menu.enabled ? 'bg-primary-cyan' : 'bg-bg-3 border border-border'
          }`}
        >
          <span
            className={`absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-all ${
              menu.enabled ? 'left-[22px]' : 'left-0.5'
            }`}
          />
        </button>
        <div className="flex gap-1">
          <button
            onClick={() => onMove(idx, -1)}
            disabled={idx === 0}
            className="w-7 h-7 rounded border border-border bg-bg-2 text-text-3 text-xs flex items-center justify-center hover:bg-bg-hover hover:text-text-1 transition-all disabled:opacity-30 disabled:cursor-not-allowed"
          >
            ▲
          </button>
          <button
            onClick={() => onMove(idx, 1)}
            disabled={idx === totalCount - 1}
            className="w-7 h-7 rounded border border-border bg-bg-2 text-text-3 text-xs flex items-center justify-center hover:bg-bg-hover hover:text-text-1 transition-all disabled:opacity-30 disabled:cursor-not-allowed"
          >
            ▼
          </button>
        </div>
      </div>
    </div>
  )
}

// ─── 메뉴 관리 패널 ─────────────────────────────────────────
function MenusPanel() {
  const [menus, setMenus] = useState<MenuConfigItem[]>([])
  const [originalMenus, setOriginalMenus] = useState<MenuConfigItem[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [emojiPickerId, setEmojiPickerId] = useState<string | null>(null)
  const [activeId, setActiveId] = useState<string | null>(null)
  const emojiPickerRef = useRef<HTMLDivElement>(null)
  const { setMenuConfig } = useMenuStore()

  const hasChanges = JSON.stringify(menus) !== JSON.stringify(originalMenus)

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
  )

  const loadMenus = useCallback(async () => {
    setLoading(true)
    try {
      const config = await fetchMenuConfig()
      setMenus(config)
      setOriginalMenus(config)
    } catch (err) {
      console.error('메뉴 설정 조회 실패:', err)
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    loadMenus()
  }, [loadMenus])

  useEffect(() => {
    if (!emojiPickerId) return
    const handler = (e: MouseEvent) => {
      if (emojiPickerRef.current && !emojiPickerRef.current.contains(e.target as Node)) {
        setEmojiPickerId(null)
      }
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [emojiPickerId])

  const toggleMenu = (id: string) => {
    setMenus(prev => prev.map(m => m.id === id ? { ...m, enabled: !m.enabled } : m))
  }

  const updateMenuField = (id: string, field: 'label' | 'icon', value: string) => {
    setMenus(prev => prev.map(m => m.id === id ? { ...m, [field]: value } : m))
  }

  const handleEmojiSelect = (emoji: { native: string }) => {
    if (emojiPickerId) {
      updateMenuField(emojiPickerId, 'icon', emoji.native)
      setEmojiPickerId(null)
    }
  }

  const moveMenu = (idx: number, direction: -1 | 1) => {
    const targetIdx = idx + direction
    if (targetIdx < 0 || targetIdx >= menus.length) return
    setMenus(prev => {
      const arr = [...prev]
      ;[arr[idx], arr[targetIdx]] = [arr[targetIdx], arr[idx]]
      return arr.map((m, i) => ({ ...m, order: i + 1 }))
    })
  }

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event
    setActiveId(null)
    if (!over || active.id === over.id) return
    setMenus(prev => {
      const oldIndex = prev.findIndex(m => m.id === active.id)
      const newIndex = prev.findIndex(m => m.id === over.id)
      const reordered = arrayMove(prev, oldIndex, newIndex)
      return reordered.map((m, i) => ({ ...m, order: i + 1 }))
    })
  }

  const handleSave = async () => {
    setSaving(true)
    try {
      const updated = await updateMenuConfigApi(menus)
      setMenus(updated)
      setOriginalMenus(updated)
      setMenuConfig(updated)
    } catch (err) {
      console.error('메뉴 설정 저장 실패:', err)
    } finally {
      setSaving(false)
    }
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-text-3 text-sm font-korean">메뉴 설정을 불러오는 중...</div>
      </div>
    )
  }

  const activeMenu = activeId ? menus.find(m => m.id === activeId) : null

  return (
    <div className="flex flex-col h-full">
      <div className="flex items-center justify-between px-6 py-4 border-b border-border">
        <div>
          <h1 className="text-lg font-bold text-text-1 font-korean">메뉴 관리</h1>
          <p className="text-xs text-text-3 mt-1 font-korean">메뉴 표시 여부, 순서, 라벨, 아이콘을 관리합니다</p>
        </div>
        <button
          onClick={handleSave}
          disabled={!hasChanges || saving}
          className={`px-4 py-2 text-xs font-semibold rounded-md transition-all font-korean ${
            hasChanges && !saving
              ? 'bg-primary-cyan text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)]'
              : 'bg-bg-3 text-text-3 cursor-not-allowed'
          }`}
        >
          {saving ? '저장 중...' : '변경사항 저장'}
        </button>
      </div>

      <div className="flex-1 overflow-auto px-6 py-4">
        <DndContext
          sensors={sensors}
          collisionDetection={closestCenter}
          onDragStart={(event) => setActiveId(event.active.id as string)}
          onDragEnd={handleDragEnd}
        >
          <SortableContext items={menus.map(m => m.id)} strategy={verticalListSortingStrategy}>
            <div className="flex flex-col gap-2 max-w-[700px]">
              {menus.map((menu, idx) => (
                <SortableMenuItem
                  key={menu.id}
                  menu={menu}
                  idx={idx}
                  totalCount={menus.length}
                  isEditing={editingId === menu.id}
                  emojiPickerId={emojiPickerId}
                  emojiPickerRef={emojiPickerRef}
                  onToggle={toggleMenu}
                  onMove={moveMenu}
                  onEditStart={setEditingId}
                  onEditEnd={() => { setEditingId(null); setEmojiPickerId(null) }}
                  onEmojiPickerToggle={setEmojiPickerId}
                  onLabelChange={(id, value) => updateMenuField(id, 'label', value)}
                  onEmojiSelect={handleEmojiSelect}
                />
              ))}
            </div>
          </SortableContext>
          <DragOverlay>
            {activeMenu ? (
              <div className="flex items-center gap-3 px-4 py-3 rounded-md border border-primary-cyan bg-bg-1 shadow-lg opacity-90 max-w-[700px]">
                <span className="text-text-3 text-xs">⠿</span>
                <span className="text-[16px]">{activeMenu.icon}</span>
                <span className="text-[13px] font-semibold text-text-1 font-korean">{activeMenu.label}</span>
              </div>
            ) : null}
          </DragOverlay>
        </DndContext>
      </div>
    </div>
  )
}

// ─── 시스템 설정 패널 ────────────────────────────────────────
function SettingsPanel() {
  const [settings, setSettings] = useState<RegistrationSettings | null>(null)
  const [oauthSettings, setOauthSettings] = useState<OAuthSettings | null>(null)
  const [oauthDomainInput, setOauthDomainInput] = useState('')
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [savingOAuth, setSavingOAuth] = useState(false)

  useEffect(() => {
    loadSettings()
  }, [])

  const loadSettings = async () => {
    setLoading(true)
    try {
      const [regData, oauthData] = await Promise.all([
        fetchRegistrationSettings(),
        fetchOAuthSettings(),
      ])
      setSettings(regData)
      setOauthSettings(oauthData)
      setOauthDomainInput(oauthData.autoApproveDomains)
    } catch (err) {
      console.error('설정 조회 실패:', err)
    } finally {
      setLoading(false)
    }
  }

  const handleToggle = async (key: keyof RegistrationSettings) => {
    if (!settings) return
    const newValue = !settings[key]
    setSaving(true)
    try {
      const updated = await updateRegistrationSettingsApi({ [key]: newValue })
      setSettings(updated)
    } catch (err) {
      console.error('설정 변경 실패:', err)
    } finally {
      setSaving(false)
    }
  }

  if (loading) {
    return <div className="flex items-center justify-center h-32 text-text-3 text-sm font-korean">불러오는 중...</div>
  }

  return (
    <div className="flex flex-col h-full">
      <div className="px-6 py-4 border-b border-border">
        <h1 className="text-lg font-bold text-text-1 font-korean">시스템 설정</h1>
        <p className="text-xs text-text-3 mt-1 font-korean">사용자 등록 및 권한 관련 시스템 설정을 관리합니다</p>
      </div>

      <div className="flex-1 overflow-auto px-6 py-6">
        <div className="max-w-[640px] flex flex-col gap-6">
          {/* 사용자 등록 설정 */}
          <div className="rounded-lg border border-border bg-bg-1 overflow-hidden">
            <div className="px-5 py-3 border-b border-border">
              <h2 className="text-sm font-bold text-text-1 font-korean">사용자 등록 설정</h2>
              <p className="text-[11px] text-text-3 mt-0.5 font-korean">신규 사용자 등록 시 적용되는 정책을 설정합니다</p>
            </div>

            <div className="divide-y divide-border">
              {/* 자동 승인 */}
              <div className="px-5 py-4 flex items-center justify-between">
                <div className="flex-1 mr-4">
                  <div className="text-[13px] font-semibold text-text-1 font-korean">자동 승인</div>
                  <p className="text-[11px] text-text-3 mt-1 font-korean leading-relaxed">
                    활성화하면 신규 사용자가 등록 즉시 <span className="text-green-400 font-semibold">ACTIVE</span> 상태가 됩니다.
                    비활성화하면 관리자 승인 전까지 <span className="text-yellow-400 font-semibold">PENDING</span> 상태로 대기합니다.
                  </p>
                </div>
                <button
                  onClick={() => handleToggle('autoApprove')}
                  disabled={saving}
                  className={`relative w-12 h-6 rounded-full transition-all flex-shrink-0 ${
                    settings?.autoApprove ? 'bg-primary-cyan' : 'bg-bg-3 border border-border'
                  } ${saving ? 'opacity-50' : ''}`}
                >
                  <span
                    className={`absolute top-0.5 w-5 h-5 rounded-full bg-white shadow transition-all ${
                      settings?.autoApprove ? 'left-[26px]' : 'left-0.5'
                    }`}
                  />
                </button>
              </div>

              {/* 기본 역할 자동 할당 */}
              <div className="px-5 py-4 flex items-center justify-between">
                <div className="flex-1 mr-4">
                  <div className="text-[13px] font-semibold text-text-1 font-korean">기본 역할 자동 할당</div>
                  <p className="text-[11px] text-text-3 mt-1 font-korean leading-relaxed">
                    활성화하면 신규 사용자에게 <span className="text-primary-cyan font-semibold">기본 역할</span>이 자동으로 할당됩니다.
                    기본 역할은 권한 관리 탭에서 설정할 수 있습니다.
                  </p>
                </div>
                <button
                  onClick={() => handleToggle('defaultRole')}
                  disabled={saving}
                  className={`relative w-12 h-6 rounded-full transition-all flex-shrink-0 ${
                    settings?.defaultRole ? 'bg-primary-cyan' : 'bg-bg-3 border border-border'
                  } ${saving ? 'opacity-50' : ''}`}
                >
                  <span
                    className={`absolute top-0.5 w-5 h-5 rounded-full bg-white shadow transition-all ${
                      settings?.defaultRole ? 'left-[26px]' : 'left-0.5'
                    }`}
                  />
                </button>
              </div>
            </div>
          </div>

          {/* OAuth 설정 */}
          <div className="rounded-lg border border-border bg-bg-1 overflow-hidden">
            <div className="px-5 py-3 border-b border-border">
              <h2 className="text-sm font-bold text-text-1 font-korean">Google OAuth 설정</h2>
              <p className="text-[11px] text-text-3 mt-0.5 font-korean">Google 계정 로그인 시 자동 승인할 이메일 도메인을 설정합니다</p>
            </div>
            <div className="px-5 py-4">
              <div className="flex-1 mr-4 mb-3">
                <div className="text-[13px] font-semibold text-text-1 font-korean mb-1">자동 승인 도메인</div>
                <p className="text-[11px] text-text-3 font-korean leading-relaxed mb-3">
                  지정된 도메인의 Google 계정은 가입 즉시 <span className="text-green-400 font-semibold">ACTIVE</span> 상태가 됩니다.
                  미지정 도메인은 <span className="text-yellow-400 font-semibold">PENDING</span> 상태로 관리자 승인이 필요합니다.
                  여러 도메인은 쉼표(,)로 구분합니다.
                </p>
                <div className="flex gap-2">
                  <input
                    type="text"
                    value={oauthDomainInput}
                    onChange={(e) => setOauthDomainInput(e.target.value)}
                    placeholder="gcsc.co.kr, example.com"
                    className="flex-1 px-3 py-2 text-xs bg-bg-2 border border-border rounded-md text-text-1 placeholder-text-3 focus:border-primary-cyan focus:outline-none font-mono"
                  />
                  <button
                    onClick={async () => {
                      setSavingOAuth(true)
                      try {
                        const updated = await updateOAuthSettingsApi({ autoApproveDomains: oauthDomainInput.trim() })
                        setOauthSettings(updated)
                        setOauthDomainInput(updated.autoApproveDomains)
                      } catch (err) {
                        console.error('OAuth 설정 변경 실패:', err)
                      } finally {
                        setSavingOAuth(false)
                      }
                    }}
                    disabled={savingOAuth || oauthDomainInput.trim() === (oauthSettings?.autoApproveDomains || '')}
                    className={`px-4 py-2 text-xs font-semibold rounded-md transition-all font-korean whitespace-nowrap ${
                      oauthDomainInput.trim() !== (oauthSettings?.autoApproveDomains || '')
                        ? 'bg-primary-cyan text-bg-0 hover:shadow-[0_0_12px_rgba(6,182,212,0.3)]'
                        : 'bg-bg-3 text-text-3 cursor-not-allowed'
                    }`}
                  >
                    {savingOAuth ? '저장 중...' : '저장'}
                  </button>
                </div>
              </div>
              {oauthSettings?.autoApproveDomains && (
                <div className="flex flex-wrap gap-1.5 mt-3">
                  {oauthSettings.autoApproveDomains.split(',').map(d => d.trim()).filter(Boolean).map(domain => (
                    <span
                      key={domain}
                      className="inline-flex items-center gap-1 px-2 py-1 text-[10px] font-mono rounded-md"
                      style={{ background: 'rgba(6,182,212,0.1)', color: 'var(--cyan)', border: '1px solid rgba(6,182,212,0.25)' }}
                    >
                      @{domain}
                    </span>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* 현재 설정 상태 요약 */}
          <div className="rounded-lg border border-border bg-bg-1 overflow-hidden">
            <div className="px-5 py-3 border-b border-border">
              <h2 className="text-sm font-bold text-text-1 font-korean">설정 상태 요약</h2>
            </div>
            <div className="px-5 py-4">
              <div className="flex flex-col gap-3 text-[12px] font-korean">
                <div className="flex items-center gap-2">
                  <span className={`w-2 h-2 rounded-full ${settings?.autoApprove ? 'bg-green-400' : 'bg-yellow-400'}`} />
                  <span className="text-text-2">
                    신규 사용자 등록 시{' '}
                    {settings?.autoApprove ? (
                      <span className="text-green-400 font-semibold">즉시 활성화</span>
                    ) : (
                      <span className="text-yellow-400 font-semibold">관리자 승인 필요</span>
                    )}
                  </span>
                </div>
                <div className="flex items-center gap-2">
                  <span className={`w-2 h-2 rounded-full ${settings?.defaultRole ? 'bg-green-400' : 'bg-text-3'}`} />
                  <span className="text-text-2">
                    기본 역할 자동 할당{' '}
                    {settings?.defaultRole ? (
                      <span className="text-green-400 font-semibold">활성</span>
                    ) : (
                      <span className="text-text-3 font-semibold">비활성</span>
                    )}
                  </span>
                </div>
                <div className="flex items-center gap-2">
                  <span className={`w-2 h-2 rounded-full ${oauthSettings?.autoApproveDomains ? 'bg-blue-400' : 'bg-text-3'}`} />
                  <span className="text-text-2">
                    Google OAuth 자동 승인 도메인{' '}
                    {oauthSettings?.autoApproveDomains ? (
                      <span className="text-blue-400 font-semibold font-mono">{oauthSettings.autoApproveDomains}</span>
                    ) : (
                      <span className="text-text-3 font-semibold">미설정</span>
                    )}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

// ─── AdminView ────────────────────────────────────────────
export function AdminView() {
  const { activeSubTab } = useSubMenu('admin')

  return (
    <div className="flex flex-1 overflow-hidden bg-bg-0">
      <div className="flex-1 flex flex-col overflow-hidden">
        {activeSubTab === 'users' && <UsersPanel />}
        {activeSubTab === 'permissions' && <PermissionsPanel />}
        {activeSubTab === 'menus' && <MenusPanel />}
        {activeSubTab === 'settings' && <SettingsPanel />}
      </div>
    </div>
  )
}
