"use client";

/**
 * 관리자 — 부서관리 (로그인 관리자 회사 컨텍스트)
 *
 * 경로: /admin/userMng/departments
 * 데이터 범위: 로그인한 관리자의 company_code
 *
 * 좌측: 부서 목록 (dept_info)
 * 우측: 선택한 부서의 인원 목록 (user_info) — 재직/퇴사 탭 분리
 *
 * 사용자 측 하드코딩 페이지(/COMPANY_7/master-data/department)에서 기능 이식.
 * 회사 선택/전환 없음 — useAuth().user.companyCode 단일 고정.
 */

import React, { useState, useEffect, useCallback, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription,
} from "@/components/ui/dialog";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import {
  Plus, Trash2, Save, Loader2, FileSpreadsheet, Download, Pencil,
  Users, ChevronDown, ChevronRight,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import * as departmentAPI from "@/lib/api/department";
import { allocateNumberingCode } from "@/lib/api/numberingRule";
import { useAuth } from "@/hooks/useAuth";
import { toast } from "sonner";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
import { ExcelUploadModal } from "@/components/common/ExcelUploadModal";
import { exportToExcel } from "@/lib/utils/excelExport";
import { formatField, validateField, validateForm } from "@/lib/utils/validation";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";

const DEPT_TABLE = "dept_info";
const USER_TABLE = "user_info";

export default function AdminDepartmentPage() {
  const { user } = useAuth();
  const { confirm, ConfirmDialogComponent } = useConfirmDialog();

  // 로그인 관리자 회사 컨텍스트
  const companyCode = user?.companyCode || "";

  // 검색 필터
  const [searchFilters, setSearchFilters] = useState<FilterValue[]>([]);

  // 좌측: 부서
  const [depts, setDepts] = useState<any[]>([]);
  const [deptLoading, setDeptLoading] = useState(false);
  const [deptCount, setDeptCount] = useState(0);
  const [selectedDeptId, setSelectedDeptId] = useState<string | null>(null);

  // 우측: 사원
  const [members, setMembers] = useState<any[]>([]);
  const [memberLoading, setMemberLoading] = useState(false);

  // 부서 모달
  const [deptModalOpen, setDeptModalOpen] = useState(false);
  const [deptEditMode, setDeptEditMode] = useState(false);
  const [deptForm, setDeptForm] = useState<Record<string, any>>({});
  const [saving, setSaving] = useState(false);

  // 채번 시스템 (UI 노출 없이 저장 시점에만 allocate)
  const [numberingRuleId, setNumberingRuleId] = useState<string | null>(null);

  // 사원 모달
  const [userModalOpen, setUserModalOpen] = useState(false);
  const [userEditMode, setUserEditMode] = useState(false);
  const [userForm, setUserForm] = useState<Record<string, any>>({});
  const [formErrors, setFormErrors] = useState<Record<string, string>>({});
  const [idChecked, setIdChecked] = useState(false);
  const [idChecking, setIdChecking] = useState(false);

  // 사원 탭 (재직중/퇴사)
  const [memberTab, setMemberTab] = useState<"active" | "resigned">("active");

  // 엑셀
  const [excelUploadOpen, setExcelUploadOpen] = useState(false);

  // 트리 확장/축소 상태
  const [expandedDepts, setExpandedDepts] = useState<Set<string>>(new Set());
  const didInitExpandRef = useRef(false);

  // 부서 조회 — autoFilter + 로그인 회사 기준
  const fetchDepts = useCallback(async () => {
    if (!companyCode) return;
    setDeptLoading(true);
    try {
      const filters = searchFilters.map((f) => ({ columnName: f.columnName, operator: f.operator, value: f.value }));
      const res = await apiClient.post(`/table-management/tables/${DEPT_TABLE}/data`, {
        page: 1, size: 0,
        dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
        autoFilter: true,
      });
      const raw = res.data?.data?.data || res.data?.data?.rows || [];
      const data = raw.map((d: any) => ({ ...d, id: d.id || d.dept_code }));
      setDepts(data);
      setDeptCount(res.data?.data?.total || data.length);
    } catch (err) {
      toast.error("부서 목록을 불러오는데 실패했습니다.");
    } finally {
      setDeptLoading(false);
    }
  }, [searchFilters, companyCode]);

  useEffect(() => { fetchDepts(); }, [fetchDepts]);

  // 트리 초기 로드 시 모든 상위부서 펼침 (최초 1회)
  useEffect(() => {
    if (!didInitExpandRef.current && depts.length > 0) {
      const parents = new Set<string>();
      depts.forEach((d) => { if (d.parent_dept_code) parents.add(d.parent_dept_code); });
      setExpandedDepts(parents);
      didInitExpandRef.current = true;
    }
  }, [depts]);

  const toggleExpand = (deptCode: string) => {
    setExpandedDepts((prev) => {
      const next = new Set(prev);
      if (next.has(deptCode)) next.delete(deptCode);
      else next.add(deptCode);
      return next;
    });
  };

  // 선택된 부서
  const selectedDept = depts.find((d) => d.id === selectedDeptId);
  const selectedDeptCode = selectedDept?.dept_code || null;

  // 우측: 사원 조회
  const fetchMembers = useCallback(async () => {
    if (!companyCode) return;
    setMemberLoading(true);
    try {
      const baseFilters: any[] = [];
      if (selectedDeptCode) {
        baseFilters.push({ columnName: "dept_code", operator: "equals", value: selectedDeptCode });
      }
      const res = await apiClient.post(`/table-management/tables/${USER_TABLE}/data`, {
        page: 1, size: 0,
        dataFilter: baseFilters.length > 0 ? { enabled: true, filters: baseFilters } : undefined,
        autoFilter: true,
      });
      setMembers(res.data?.data?.data || res.data?.data?.rows || []);
    } catch { setMembers([]); } finally { setMemberLoading(false); }
  }, [selectedDeptCode, companyCode]);

  useEffect(() => { fetchMembers(); }, [fetchMembers]);

  // 부서 등록
  const openDeptRegister = async () => {
    setDeptForm({});
    setDeptEditMode(false);
    setNumberingRuleId(null);
    setDeptModalOpen(true);

    // 채번 규칙 조회 (UI preview 없이 규칙 존재 여부만 확인)
    try {
      const ruleRes = await apiClient.get(`/numbering-rules/by-column/dept_info/dept_code`);
      const ruleData = ruleRes.data;
      if (ruleData?.success && ruleData?.data?.ruleId) {
        setNumberingRuleId(ruleData.data.ruleId);
      }
    } catch {
      // 채번 규칙 없으면 무시 (백엔드가 자동 생성)
    }
  };

  const openDeptEdit = () => {
    if (!selectedDept) return;
    setDeptForm({ ...selectedDept });
    setDeptEditMode(true);
    setDeptModalOpen(true);
  };

  const handleDeptSave = async () => {
    if (!deptForm.dept_name) { toast.error("부서명은 필수입니다."); return; }
    if (!companyCode) { toast.error("회사 정보를 확인할 수 없습니다."); return; }
    const parentCode = (deptForm.parent_dept_code && deptForm.parent_dept_code !== "none") ? deptForm.parent_dept_code : null;
    setSaving(true);
    try {
      if (deptEditMode && deptForm.dept_code) {
        const response = await departmentAPI.updateDepartment(deptForm.dept_code, {
          dept_name: deptForm.dept_name,
          parent_dept_code: parentCode,
        });
        if (!response.success) { toast.error((response as any).error || "수정에 실패했습니다."); return; }
        toast.success("수정되었습니다.");
      } else {
        // 채번 규칙이 있으면 allocate, 없으면 클라이언트에서 D### 포맷 자동 생성
        let allocatedCode: string | undefined;
        if (numberingRuleId) {
          const allocRes = await allocateNumberingCode(numberingRuleId);
          if (allocRes.success && allocRes.data?.generatedCode) {
            allocatedCode = allocRes.data.generatedCode;
          } else {
            toast.error("채번 코드 할당에 실패했습니다.");
            return;
          }
        } else {
          // 채번 규칙 미존재 — 기존 부서의 D### 최대 순번 +1로 자동 생성
          const prefix = "D";
          const maxNum = depts
            .map((d) => d.dept_code || "")
            .filter((c: string) => typeof c === "string" && c.startsWith(prefix))
            .map((c: string) => parseInt(c.substring(prefix.length), 10))
            .filter((n) => !isNaN(n))
            .reduce((max, n) => Math.max(max, n), 0);
          allocatedCode = `${prefix}${String(maxNum + 1).padStart(3, "0")}`;
        }

        const response = await departmentAPI.createDepartment(companyCode, {
          dept_name: deptForm.dept_name,
          parent_dept_code: parentCode,
          dept_code: allocatedCode,
        });
        if (!response.success) {
          toast.error((response as any).error || "등록에 실패했습니다.");
          return;
        }
        toast.success("등록되었습니다.");
      }
      setDeptModalOpen(false);
      fetchDepts();
    } catch (err: any) {
      toast.error(err.response?.data?.message || "저장에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  };

  // 부서 삭제
  const handleDeptDelete = async () => {
    if (!selectedDeptCode) return;
    const ok = await confirm("부서를 삭제하시겠습니까?", {
      description: "해당 부서에 소속된 사원 정보는 유지됩니다.",
      variant: "destructive", confirmText: "삭제",
    });
    if (!ok) return;
    try {
      const response = await departmentAPI.deleteDepartment(selectedDeptCode);
      if (!response.success) { toast.error((response as any).error || "삭제에 실패했습니다."); return; }
      toast.success(response.message || "삭제되었습니다.");
      setSelectedDeptId(null);
      fetchDepts();
    } catch { toast.error("삭제에 실패했습니다."); }
  };

  // 사원 추가/수정
  const openUserModal = (editData?: any) => {
    if (editData) {
      setUserEditMode(true);
      setUserForm({ ...editData, user_password: "" });
      setIdChecked(true);
    } else {
      setUserEditMode(false);
      setUserForm({ dept_code: selectedDeptCode || "", user_password: "" });
      setIdChecked(false);
    }
    setFormErrors({});
    setUserModalOpen(true);
  };

  // 사용자 ID 중복 확인
  const handleCheckUserId = async () => {
    const uid = (userForm.user_id || "").trim();
    if (!uid) { toast.error("사용자 ID를 입력해주세요."); return; }
    setIdChecking(true);
    try {
      const res = await apiClient.post("/admin/users/check-duplicate", { userId: uid });
      const isDuplicate = res.data?.data?.isDuplicate;
      if (isDuplicate) {
        toast.error("이미 사용 중인 사용자 ID입니다.");
        setIdChecked(false);
      } else {
        toast.success("사용 가능한 사용자 ID입니다.");
        setIdChecked(true);
      }
    } catch {
      toast.error("중복 확인에 실패했습니다.");
      setIdChecked(false);
    } finally {
      setIdChecking(false);
    }
  };

  const handleUserFormChange = (field: string, value: string) => {
    const formatted = formatField(field, value);
    setUserForm((prev) => ({ ...prev, [field]: formatted }));
    const error = validateField(field, formatted);
    setFormErrors((prev) => { const n = { ...prev }; if (error) n[field] = error; else delete n[field]; return n; });
  };

  const handleUserSave = async () => {
    if (!userForm.user_id) { toast.error("사용자 ID는 필수입니다."); return; }
    if (!userEditMode && !idChecked) { toast.error("사용자 ID 중복 확인을 해주세요."); return; }
    if (!userForm.user_name) { toast.error("사용자 이름은 필수입니다."); return; }
    if (!userForm.dept_code) { toast.error("부서는 필수입니다."); return; }
    const errors = validateForm(userForm, ["cell_phone", "email"]);
    setFormErrors(errors);
    if (Object.keys(errors).length > 0) { toast.error("입력 형식을 확인해주세요."); return; }

    setSaving(true);
    try {
      // 비밀번호 미입력 시 기본값 (신규만)
      const password = userForm.user_password || (!userEditMode ? "qlalfqjsgh11" : undefined);

      await apiClient.post("/admin/users/with-dept", {
        userInfo: {
          user_id: userForm.user_id,
          user_name: userForm.user_name,
          user_name_eng: userForm.user_name_eng || undefined,
          user_password: password || undefined,
          email: userEditMode ? (userForm.email || null) : (userForm.email || undefined),
          tel: userForm.tel || undefined,
          cell_phone: userEditMode ? (userForm.cell_phone || null) : (userForm.cell_phone || undefined),
          sabun: userEditMode ? (userForm.sabun || null) : (userForm.sabun || undefined),
          position_name: userForm.position_name || undefined,
          dept_code: userForm.dept_code || undefined,
          dept_name: depts.find((d) => d.dept_code === userForm.dept_code)?.dept_name || undefined,
          status: userForm.status || "active",
          end_date: userForm.end_date || null,
        },
        mainDept: userForm.dept_code ? {
          dept_code: userForm.dept_code,
          dept_name: depts.find((d) => d.dept_code === userForm.dept_code)?.dept_name,
          position_name: userForm.position_name || undefined,
        } : undefined,
        isUpdate: userEditMode,
      });
      toast.success(userEditMode ? "사원 정보가 수정되었습니다." : "사원이 추가되었습니다.");
      setUserModalOpen(false);
      fetchMembers();
    } catch (err: any) {
      toast.error(err.response?.data?.message || "저장에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  };

  // 엑셀 다운로드
  const handleExcelDownload = async () => {
    if (depts.length === 0) return;
    const data = depts.map((d) => ({
      부서코드: d.dept_code, 부서명: d.dept_name, 상위부서: d.parent_dept_code, 상태: d.status,
    }));
    await exportToExcel(data, "부서관리.xlsx", "부서");
    toast.success("다운로드 완료");
  };

  // 퇴사일 기반 재직/퇴사 분리
  const _now = new Date();
  const today = `${_now.getFullYear()}-${String(_now.getMonth() + 1).padStart(2, "0")}-${String(_now.getDate()).padStart(2, "0")}`;
  const activeMembers = members.filter((m) => !m.end_date || m.end_date.substring(0, 10) >= today);
  const resignedMembers = members.filter((m) => m.end_date && m.end_date.substring(0, 10) < today);

  // 트리 빌드: 부모-자식 관계 기준. 고아 노드는 루트로 처리.
  const allDeptCodes = new Set(depts.map((d) => d.dept_code));
  const buildTreeChildren = (parentCode: string | null) => {
    if (parentCode === null) {
      return depts.filter((d) => !d.parent_dept_code || !allDeptCodes.has(d.parent_dept_code));
    }
    return depts.filter((d) => d.parent_dept_code === parentCode);
  };

  const renderTreeNode = (parentCode: string | null, level: number = 0): React.ReactNode => {
    const children = buildTreeChildren(parentCode);
    return children.map((dept) => {
      const hasChildren = depts.some((d) => d.parent_dept_code === dept.dept_code);
      const isExpanded = expandedDepts.has(dept.dept_code);
      const isSelected = selectedDeptId === dept.id;
      return (
        <React.Fragment key={dept.id}>
          <div
            className={cn(
              "flex items-center gap-2 px-3 py-2 border-b text-[13px] cursor-pointer select-none transition-colors",
              isSelected ? "bg-primary/10 text-primary" : "hover:bg-muted/40"
            )}
            style={{ paddingLeft: 12 + level * 20 }}
            onClick={() => setSelectedDeptId(dept.id)}
            onDoubleClick={() => { setSelectedDeptId(dept.id); openDeptEdit(); }}
          >
            {hasChildren ? (
              <button
                type="button"
                className="h-4 w-4 shrink-0 flex items-center justify-center text-muted-foreground hover:text-foreground"
                onClick={(e) => { e.stopPropagation(); toggleExpand(dept.dept_code); }}
              >
                {isExpanded ? <ChevronDown className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />}
              </button>
            ) : (
              <div className="h-4 w-4 shrink-0" />
            )}
            <span className="flex-1 font-medium truncate">{dept.dept_name || "—"}</span>
            <span className="font-mono text-[11px] text-muted-foreground shrink-0">{dept.dept_code}</span>
            {dept.status && (
              <Badge
                variant={dept.status === "active" ? "default" : "outline"}
                className="text-[10px] px-1.5 py-0 h-5 shrink-0"
              >
                {dept.status === "active" ? "활성" : dept.status}
              </Badge>
            )}
          </div>
          {hasChildren && isExpanded && renderTreeNode(dept.dept_code, level + 1)}
        </React.Fragment>
      );
    });
  };

  return (
    <div className="flex h-full flex-col gap-3 p-4">
      {/* 검색 필터 바 */}
      <DynamicSearchFilter
        tableName={DEPT_TABLE}
        filterId="admin-department"
        onFilterChange={setSearchFilters}
        dataCount={deptCount}
        extraActions={
          <div className="flex gap-1.5">
            <Button variant="outline" size="sm" className="h-8" onClick={() => setExcelUploadOpen(true)}>
              <FileSpreadsheet className="w-3.5 h-3.5 mr-1" />
              엑셀 업로드
            </Button>
            <Button variant="outline" size="sm" className="h-8" onClick={() => void handleExcelDownload()}>
              <Download className="w-3.5 h-3.5 mr-1" /> 엑셀 다운로드
            </Button>
          </div>
        }
      />

      {/* 마스터-디테일 분할 패널 */}
      <div className="flex-1 overflow-hidden border rounded-lg bg-background shadow-sm">
        <ResizablePanelGroup direction="horizontal">
          {/* 좌측: 부서 목록 */}
          <ResizablePanel defaultSize={40} minSize={25}>
            <div className="flex flex-col h-full">
              <div className="flex items-center justify-between px-4 py-3 border-b bg-muted shrink-0">
                <div className="flex items-center gap-2.5">
                  <span className="text-[13px] font-bold">부서 목록</span>
                  <span className="text-[11px] font-semibold text-primary bg-primary/[0.08] px-2 py-0.5 rounded-full">
                    {deptCount}건
                  </span>
                </div>
                <div className="flex gap-1.5">
                  <Button size="sm" onClick={() => void openDeptRegister()}>
                    <Plus className="w-3.5 h-3.5 mr-1" /> 등록
                  </Button>
                  <Button variant="outline" size="sm" disabled={!selectedDeptCode} onClick={openDeptEdit}>
                    <Pencil className="w-3.5 h-3.5 mr-1" /> 수정
                  </Button>
                  <Button variant="destructive" size="sm" disabled={!selectedDeptCode} onClick={() => void handleDeptDelete()}>
                    <Trash2 className="w-3.5 h-3.5 mr-1" /> 삭제
                  </Button>
                </div>
              </div>

              {/* 부서 트리 */}
              <div className="flex-1 overflow-auto">
                {deptLoading ? (
                  <div className="flex items-center justify-center py-12">
                    <Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
                  </div>
                ) : depts.length === 0 ? (
                  <div className="text-center py-10 text-sm text-muted-foreground">등록된 부서가 없어요</div>
                ) : (
                  <div>{renderTreeNode(null)}</div>
                )}
              </div>

            </div>
          </ResizablePanel>

          <ResizableHandle withHandle />

          {/* 우측: 사원 목록 */}
          <ResizablePanel defaultSize={60} minSize={30}>
            <div className="flex flex-col h-full">
              {!selectedDeptId ? (
                <div className="flex-1 flex items-center justify-center p-5">
                  <div className="flex flex-col items-center justify-center text-center border-2 border-dashed border-border rounded-lg px-10 py-16">
                    <Users className="w-12 h-12 text-muted-foreground/40 mb-4" />
                    <div className="text-sm font-semibold text-muted-foreground mb-1.5">부서를 선택해주세요</div>
                    <div className="text-xs text-muted-foreground">좌측에서 부서를 선택하면 소속 사원 목록이 표시돼요</div>
                  </div>
                </div>
              ) : (
                <>
                  <div className="flex items-center gap-3 px-4 py-3 border-b bg-muted shrink-0">
                    <span className="text-[13px] font-bold">{selectedDept?.dept_name || "-"}</span>
                    <span className="font-mono text-[11px] font-semibold text-primary bg-primary/[0.08] px-2 py-0.5 rounded-full">
                      {selectedDept?.dept_code || "-"}
                    </span>
                    <div className="ml-auto">
                      <Button variant="outline" size="sm" onClick={() => openUserModal()}>
                        <Plus className="w-3.5 h-3.5 mr-1" />
                        사원 추가
                      </Button>
                    </div>
                  </div>

                  {/* 재직/퇴사 탭 */}
                  <div className="flex border-b border-border px-4 shrink-0 bg-muted">
                    <button
                      onClick={() => setMemberTab("active")}
                      className={cn("px-4 py-2.5 text-xs font-semibold border-b-2 transition-colors",
                        memberTab === "active" ? "border-primary text-foreground" : "border-transparent text-muted-foreground"
                      )}
                    >
                      재직중
                      {activeMembers.length > 0 && (
                        <Badge variant="secondary" className="ml-1.5 text-[10px] px-1.5 py-0">{activeMembers.length}</Badge>
                      )}
                    </button>
                    <button
                      onClick={() => setMemberTab("resigned")}
                      className={cn("px-4 py-2.5 text-xs font-semibold border-b-2 transition-colors",
                        memberTab === "resigned" ? "border-primary text-foreground" : "border-transparent text-muted-foreground"
                      )}
                    >
                      퇴사
                      {resignedMembers.length > 0 && (
                        <Badge variant="secondary" className="ml-1.5 text-[10px] px-1.5 py-0">{resignedMembers.length}</Badge>
                      )}
                    </button>
                  </div>

                  <div className="flex-1 overflow-auto">
                    {memberLoading ? (
                      <div className="flex flex-col items-center justify-center py-12">
                        <Loader2 className="w-5 h-5 animate-spin mx-auto text-muted-foreground" />
                      </div>
                    ) : memberTab === "active" ? (
                      activeMembers.length === 0 ? (
                        <div className="text-center py-8 text-muted-foreground text-sm">재직중인 사원이 없어요</div>
                      ) : (
                        <Table noWrapper>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="w-[40px] text-center px-2 text-[11px] font-bold uppercase tracking-wide text-muted-foreground">No</TableHead>
                              <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">사번</TableHead>
                              <TableHead className="w-[90px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">이름</TableHead>
                              <TableHead className="w-[110px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">사용자ID</TableHead>
                              <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">직급</TableHead>
                              <TableHead className="w-[120px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">휴대폰</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">이메일</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {activeMembers.map((member, idx) => (
                              <TableRow
                                key={member.id || member.user_id}
                                className="cursor-pointer select-none hover:bg-muted/50"
                                onDoubleClick={() => openUserModal(member)}
                              >
                                <TableCell className="text-center text-[13px] text-muted-foreground px-2">{idx + 1}</TableCell>
                                <TableCell className="font-mono text-[13px] text-muted-foreground">{member.sabun || "—"}</TableCell>
                                <TableCell className="text-sm font-medium">{member.user_name}</TableCell>
                                <TableCell className="text-[13px] text-muted-foreground">{member.user_id}</TableCell>
                                <TableCell className="text-[13px]">{member.position_name || "—"}</TableCell>
                                <TableCell className="text-[13px]">{member.cell_phone || "—"}</TableCell>
                                <TableCell className="text-[13px]">{member.email || "—"}</TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      )
                    ) : (
                      resignedMembers.length === 0 ? (
                        <div className="text-center py-8 text-muted-foreground text-sm">퇴사한 사원이 없어요</div>
                      ) : (
                        <Table noWrapper>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="w-[40px] text-center px-2 text-[11px] font-bold uppercase tracking-wide text-muted-foreground">No</TableHead>
                              <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">사번</TableHead>
                              <TableHead className="w-[90px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">이름</TableHead>
                              <TableHead className="w-[110px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">사용자ID</TableHead>
                              <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">직급</TableHead>
                              <TableHead className="w-[120px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">휴대폰</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">이메일</TableHead>
                              <TableHead className="w-[110px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">퇴사일</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {resignedMembers.map((member, idx) => (
                              <TableRow
                                key={member.id || member.user_id}
                                className="cursor-pointer select-none hover:bg-muted/50"
                                onDoubleClick={() => openUserModal(member)}
                              >
                                <TableCell className="text-center text-[13px] text-muted-foreground px-2">{idx + 1}</TableCell>
                                <TableCell className="font-mono text-[13px] text-muted-foreground">{member.sabun || "—"}</TableCell>
                                <TableCell className="text-sm font-medium">{member.user_name}</TableCell>
                                <TableCell className="text-[13px] text-muted-foreground">{member.user_id}</TableCell>
                                <TableCell className="text-[13px]">{member.position_name || "—"}</TableCell>
                                <TableCell className="text-[13px]">{member.cell_phone || "—"}</TableCell>
                                <TableCell className="text-[13px]">{member.email || "—"}</TableCell>
                                <TableCell className="text-[13px] text-muted-foreground">{member.end_date ? member.end_date.substring(0, 10) : "—"}</TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      )
                    )}
                  </div>
                </>
              )}
            </div>
          </ResizablePanel>
        </ResizablePanelGroup>
      </div>

      {/* 부서 등록/수정 모달 */}
      <Dialog open={deptModalOpen} onOpenChange={setDeptModalOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>{deptEditMode ? "부서 수정" : "부서 등록"}</DialogTitle>
            <DialogDescription>{deptEditMode ? "부서 정보를 수정합니다." : "새로운 부서를 등록합니다."}</DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
                부서명 <span className="text-destructive">*</span>
              </span>
              <Input
                value={deptForm.dept_name || ""}
                onChange={(e) => setDeptForm((p) => ({ ...p, dept_name: e.target.value }))}
                placeholder="부서명을 입력해 주세요"
                className="h-9"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">상위부서</span>
              <Select
                value={deptForm.parent_dept_code || ""}
                onValueChange={(v) => setDeptForm((p) => ({ ...p, parent_dept_code: v }))}
              >
                <SelectTrigger className="h-9">
                  <SelectValue placeholder="상위부서 선택 (선택사항)" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">없음</SelectItem>
                  {depts.filter((d) => d.dept_code !== deptForm.dept_code).map((d) => (
                    <SelectItem key={d.dept_code} value={d.dept_code}>{d.dept_name} ({d.dept_code})</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeptModalOpen(false)}>취소</Button>
            <Button onClick={() => void handleDeptSave()} disabled={saving}>
              {saving ? <Loader2 className="w-4 h-4 mr-1.5 animate-spin" /> : <Save className="w-4 h-4 mr-1.5" />}
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 사원 추가/수정 모달 */}
      <Dialog open={userModalOpen} onOpenChange={setUserModalOpen}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>{userEditMode ? "사원 정보 수정" : "사원 추가"}</DialogTitle>
            <DialogDescription>
              {userEditMode
                ? `${userForm.user_name} (${userForm.user_id}) 사원 정보를 수정합니다.`
                : selectedDept ? `${selectedDept.dept_name} 부서에 사원을 추가합니다.` : "사원을 추가합니다."}
            </DialogDescription>
          </DialogHeader>
          <div className="grid grid-cols-2 gap-4 py-2">
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
                사용자 ID <span className="text-destructive">*</span>
                {!userEditMode && idChecked && (
                  <span className="ml-2 text-[11px] font-semibold text-emerald-600">✓ 사용 가능</span>
                )}
              </span>
              <div className="flex gap-1.5">
                <Input
                  value={userForm.user_id || ""}
                  onChange={(e) => {
                    setUserForm((p) => ({ ...p, user_id: e.target.value }));
                    if (!userEditMode) setIdChecked(false);
                  }}
                  placeholder="사용자 ID를 입력해 주세요"
                  className="h-9 flex-1"
                  disabled={userEditMode}
                />
                {!userEditMode && (
                  <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    className="h-9 shrink-0"
                    onClick={handleCheckUserId}
                    disabled={idChecking || !userForm.user_id}
                  >
                    {idChecking ? "확인중" : "중복확인"}
                  </Button>
                )}
              </div>
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
                이름 <span className="text-destructive">*</span>
              </span>
              <Input
                value={userForm.user_name || ""}
                onChange={(e) => setUserForm((p) => ({ ...p, user_name: e.target.value }))}
                placeholder="이름을 입력해 주세요"
                className="h-9"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">사번</span>
              <Input
                value={userForm.sabun || ""}
                onChange={(e) => setUserForm((p) => ({ ...p, sabun: e.target.value }))}
                placeholder="사번"
                className="h-9"
                autoComplete="off"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">비밀번호</span>
              <Input
                value={userForm.user_password || ""}
                onChange={(e) => setUserForm((p) => ({ ...p, user_password: e.target.value }))}
                placeholder={userEditMode ? "변경 시에만 입력해 주세요" : "미입력 시 기본값이 설정돼요"}
                className="h-9"
                type="password"
                autoComplete="new-password"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">직급</span>
              <Input
                value={userForm.position_name || ""}
                onChange={(e) => setUserForm((p) => ({ ...p, position_name: e.target.value }))}
                placeholder="직급"
                className="h-9"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
                부서 <span className="text-destructive">*</span>
              </span>
              <Select value={userForm.dept_code || ""} onValueChange={(v) => setUserForm((p) => ({ ...p, dept_code: v }))}>
                <SelectTrigger className="h-9">
                  <SelectValue placeholder="부서를 선택해 주세요" />
                </SelectTrigger>
                <SelectContent>
                  {depts.map((d) => (
                    <SelectItem key={d.dept_code} value={d.dept_code}>{d.dept_name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">휴대폰</span>
              <Input
                value={userForm.cell_phone || ""}
                onChange={(e) => handleUserFormChange("cell_phone", e.target.value)}
                placeholder="010-0000-0000"
                className={cn("h-9", formErrors.cell_phone && "border-destructive")}
              />
              {formErrors.cell_phone && <p className="text-xs text-destructive">{formErrors.cell_phone}</p>}
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">이메일</span>
              <Input
                value={userForm.email || ""}
                onChange={(e) => handleUserFormChange("email", e.target.value)}
                placeholder="example@email.com"
                className={cn("h-9", formErrors.email && "border-destructive")}
              />
              {formErrors.email && <p className="text-xs text-destructive">{formErrors.email}</p>}
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">입사일</span>
              <Input
                type="date"
                value={userForm.regdate ? userForm.regdate.substring(0, 10) : ""}
                onChange={(e) => setUserForm((p) => ({ ...p, regdate: e.target.value }))}
                className="h-9"
              />
            </div>
            <div className="space-y-1.5">
              <span className="block text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">퇴사일</span>
              <Input
                type="date"
                value={userForm.end_date ? userForm.end_date.substring(0, 10) : ""}
                onChange={(e) => setUserForm((p) => ({ ...p, end_date: e.target.value }))}
                className="h-9"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setUserModalOpen(false)}>취소</Button>
            <Button onClick={() => void handleUserSave()} disabled={saving}>
              {saving ? <Loader2 className="w-4 h-4 mr-1.5 animate-spin" /> : <Save className="w-4 h-4 mr-1.5" />}
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 엑셀 업로드 */}
      <ExcelUploadModal
        open={excelUploadOpen}
        onOpenChange={setExcelUploadOpen}
        tableName={DEPT_TABLE}
        userId={user?.userId}
        onSuccess={() => fetchDepts()}
      />

      {ConfirmDialogComponent}
    </div>
  );
}
