"use client";

/**
 * 부서관리 — 하드코딩 페이지
 *
 * 좌측: 부서 목록 (dept_info)
 * 우측: 선택한 부서의 인원 목록 (user_info)
 *
 * 모달: 부서 등록(dept_info), 사원 추가(user_info)
 */

import React, { useState, useEffect, useCallback } 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 { Label } from "@/components/ui/label";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import {
  Plus, Trash2, Save, Loader2, FileSpreadsheet, Download, Pencil,
  Building2, Users, Settings2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import * as departmentAPI from "@/lib/api/department";
import { previewNumberingCode, allocateNumberingCode } from "@/lib/api/numberingRule";
import { useAuth } from "@/hooks/useAuth";
import { toast } from "sonner";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";
import { TableSettingsModal, TableSettings, loadTableSettings } from "@/components/common/TableSettingsModal";
import { DataGrid, DataGridColumn } from "@/components/common/DataGrid";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
import { ExcelUploadModal } from "@/components/common/ExcelUploadModal";
import { exportToExcel } from "@/lib/utils/excelExport";
import { FormDatePicker } from "@/components/screen/filters/FormDatePicker";
import { formatField, validateField, validateForm } from "@/lib/utils/validation";

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

const LEFT_COLUMNS: DataGridColumn[] = [
  { key: "dept_code", label: "부서코드", width: "w-[120px]" },
  { key: "dept_name", label: "부서명", minWidth: "min-w-[150px]" },
  { key: "parent_dept_code", label: "상위부서", width: "w-[100px]" },
  { key: "status", label: "상태", width: "w-[70px]" },
];

const RIGHT_COLUMNS: DataGridColumn[] = [
  { key: "sabun", label: "사번", width: "w-[80px]" },
  { key: "user_name", label: "이름", width: "w-[90px]" },
  { key: "user_id", label: "사용자ID", width: "w-[100px]" },
  { key: "position_name", label: "직급", width: "w-[80px]" },
  { key: "cell_phone", label: "휴대폰", width: "w-[120px]" },
  { key: "email", label: "이메일", minWidth: "min-w-[150px]" },
];

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

  // 좌측: 부서
  const [depts, setDepts] = useState<any[]>([]);
  const [deptLoading, setDeptLoading] = useState(false);
  const [deptCount, setDeptCount] = useState(0);
  const [searchFilters, setSearchFilters] = useState<FilterValue[]>([]);
  const [selectedDeptId, setSelectedDeptId] = useState<string | null>(null);
  const [tableSettingsOpen, setTableSettingsOpen] = useState(false);
  const [filterConfig, setFilterConfig] = useState<TableSettings["filters"] | undefined>();

  // 우측: 사원
  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);

  // 채번 시스템
  const [numberingRuleId, setNumberingRuleId] = useState<string | null>(null);
  const [previewCode, setPreviewCode] = 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 [excelUploadOpen, setExcelUploadOpen] = useState(false);

  const applyTableSettings = useCallback((settings: TableSettings) => {
    setFilterConfig(settings.filters);
  }, []);

  useEffect(() => {
    const saved = loadTableSettings("department");
    if (saved) applyTableSettings(saved);
  }, []);

  // 부서 조회
  const fetchDepts = useCallback(async () => {
    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: 500,
        dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
        autoFilter: true,
      });
      const raw = res.data?.data?.data || res.data?.data?.rows || [];
      // dept_info에 id 컬럼이 없으므로 dept_code를 id로 매핑
      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]);

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

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

  // 우측: 사원 조회 (부서 미선택 → 전체, 선택 → 해당 부서)
  const fetchMembers = useCallback(async () => {
    setMemberLoading(true);
    try {
      const filters = selectedDeptCode
        ? [{ columnName: "dept_code", operator: "equals", value: selectedDeptCode }]
        : [];
      const res = await apiClient.post(`/table-management/tables/${USER_TABLE}/data`, {
        page: 1, size: 500,
        dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
        autoFilter: true,
      });
      setMembers(res.data?.data?.data || res.data?.data?.rows || []);
    } catch { setMembers([]); } finally { setMemberLoading(false); }
  }, [selectedDeptCode]);

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

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

    // 채번 규칙 조회 (dept_info.dept_code) — path params로 직접 호출
    try {
      const ruleRes = await apiClient.get(`/numbering-rules/by-column/dept_info/dept_code`);
      const ruleData = ruleRes.data;
      if (ruleData?.success && ruleData?.data?.ruleId) {
        const ruleId = ruleData.data.ruleId;
        setNumberingRuleId(ruleId);
        const previewRes = await previewNumberingCode(ruleId);
        if (previewRes.success && previewRes.data?.generatedCode) {
          setPreviewCode(previewRes.data.generatedCode);
        }
      }
    } catch {
      // 채번 규칙 없으면 무시
    }
  };

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

  const handleDeptSave = async () => {
    if (!deptForm.dept_name) { 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 {
        const companyCode = user?.companyCode || "";

        // 채번 규칙이 있으면 allocate로 실제 코드 할당
        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;
          }
        }

        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: "" });
    } else {
      setUserEditMode(false);
      setUserForm({ dept_code: selectedDeptCode || "", user_password: "" });
    }
    setFormErrors({});
    setUserModalOpen(true);
  };

  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 (!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",
        },
        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("다운로드 완료");
  };

  return (
    <div className="flex h-full flex-col gap-3 p-3">
      {/* 검색 */}
      <DynamicSearchFilter
        tableName={DEPT_TABLE}
        filterId="department"
        onFilterChange={setSearchFilters}
        dataCount={deptCount}
        externalFilterConfig={filterConfig}
        extraActions={
          <div className="flex gap-1.5">
            <Button variant="outline" size="sm" className="h-9" onClick={() => setTableSettingsOpen(true)}>
              <Settings2 className="w-4 h-4 mr-1.5" /> 테이블 설정
            </Button>
            <Button variant="outline" size="sm" className="h-9" onClick={() => setExcelUploadOpen(true)}>
              <FileSpreadsheet className="w-3.5 h-3.5 mr-1" /> 엑셀 업로드
            </Button>
            <Button variant="outline" size="sm" className="h-9" onClick={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 p-3 border-b bg-muted/10 shrink-0">
                <div className="font-semibold flex items-center gap-2 text-sm">
                  <Building2 className="w-4 h-4" /> 부서
                  <Badge variant="secondary" className="font-normal">{deptCount}건</Badge>
                </div>
                <div className="flex gap-1.5">
                  <Button size="sm" onClick={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={handleDeptDelete}><Trash2 className="w-3.5 h-3.5 mr-1" /> 삭제</Button>
                </div>
              </div>
              <DataGrid
                gridId="dept-left"
                columns={LEFT_COLUMNS}
                data={depts}
                loading={deptLoading}
                selectedId={selectedDeptId}
                onSelect={(id) => {
                  setSelectedDeptId((prev) => (prev === id ? null : id));
                }}
                onRowDoubleClick={() => openDeptEdit()}
                emptyMessage="등록된 부서가 없습니다"
              />
            </div>
          </ResizablePanel>

          <ResizableHandle withHandle />

          {/* 우측: 사원 */}
          <ResizablePanel defaultSize={60} minSize={30}>
            <div className="flex flex-col h-full">
              <div className="flex items-center justify-between p-3 border-b bg-muted/10 shrink-0">
                <div className="font-semibold flex items-center gap-2 text-sm">
                  <Users className="w-4 h-4" />
                  {selectedDept ? "부서 인원" : "전체 사원"}
                  {selectedDept && <Badge variant="outline" className="font-normal">{selectedDept.dept_name}</Badge>}
                  {members.length > 0 && <Badge variant="secondary" className="font-normal">{members.length}명</Badge>}
                </div>
                <Button variant="outline" size="sm" onClick={() => openUserModal()}>
                  <Plus className="w-3.5 h-3.5 mr-1" /> 사원 추가
                </Button>
              </div>
              <DataGrid
                gridId="dept-right"
                columns={RIGHT_COLUMNS}
                data={members}
                loading={memberLoading}
                showRowNumber={false}
                tableName={USER_TABLE}
                emptyMessage={selectedDeptCode ? "소속 사원이 없습니다" : "등록된 사원이 없습니다"}
                onRowDoubleClick={(row) => openUserModal(row)}
              />
            </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-4">
            <div className="space-y-1.5">
              <Label className="text-sm">부서코드</Label>
              <Input value={deptEditMode ? (deptForm.dept_code || "") : (previewCode || "")}
                placeholder={deptEditMode ? "" : (numberingRuleId ? "채번 조회 중..." : "자동 생성됩니다")}
                className="h-9" disabled readOnly />
            </div>
            <div className="space-y-1.5">
              <Label className="text-sm">부서명 <span className="text-destructive">*</span></Label>
              <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">
              <Label className="text-sm">상위부서</Label>
              <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={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-4">
            <div className="space-y-1.5">
              <Label className="text-sm">사용자 ID <span className="text-destructive">*</span></Label>
              <Input value={userForm.user_id || ""} onChange={(e) => setUserForm((p) => ({ ...p, user_id: e.target.value }))}
                placeholder="사용자 ID" className="h-9" disabled={userEditMode} />
            </div>
            <div className="space-y-1.5">
              <Label className="text-sm">이름 <span className="text-destructive">*</span></Label>
              <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">
              <Label className="text-sm">사번</Label>
              <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">
              <Label className="text-sm">비밀번호</Label>
              <Input value={userForm.user_password || ""} onChange={(e) => setUserForm((p) => ({ ...p, user_password: e.target.value }))}
                placeholder={userEditMode ? "변경 시에만 입력" : "미입력 시 qlalfqjsgh11"} className="h-9" type="password" autoComplete="new-password" />
            </div>
            <div className="space-y-1.5">
              <Label className="text-sm">직급</Label>
              <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">
              <Label className="text-sm">부서 <span className="text-destructive">*</span></Label>
              <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">
              <Label className="text-sm">휴대폰</Label>
              <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">
              <Label className="text-sm">이메일</Label>
              <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">
              <Label className="text-sm">입사일</Label>
              <FormDatePicker value={userForm.regdate || ""} onChange={(v) => setUserForm((p) => ({ ...p, regdate: v }))} placeholder="입사일" />
            </div>
            <div className="space-y-1.5">
              <Label className="text-sm">퇴사일</Label>
              <FormDatePicker value={userForm.end_date || ""} onChange={(v) => setUserForm((p) => ({ ...p, end_date: v }))} placeholder="퇴사일" />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setUserModalOpen(false)}>취소</Button>
            <Button onClick={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}

      <TableSettingsModal
        open={tableSettingsOpen}
        onOpenChange={setTableSettingsOpen}
        tableName={DEPT_TABLE}
        settingsId="department"
        onSave={applyTableSettings}
      />
    </div>
  );
}
