"use client";

import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from "@/components/ui/card";
import {
    Form,
    FormControl,
    FormDescription,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";

import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
import { Checkbox } from "@/components/ui/checkbox";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { toast } from "sonner";
import {
    Loader2,
    Trash2,
    FileText,
    AlertCircle,
    GripVertical,
} from "lucide-react";
import { debugLog, debugError } from "@/lib/debug-utils";

// dnd-kit imports for drag and drop
import {
    DndContext,
    closestCenter,
    KeyboardSensor,
    PointerSensor,
    useSensor,
    useSensors,
    type DragEndEvent,
} from "@dnd-kit/core";

// 드래그 이동을 수직 축으로 제한하고, 리스트 영역 밖으로 벗어나지 않도록 하는 modifier
import {
    restrictToVerticalAxis,
    restrictToParentElement,
} from "@dnd-kit/modifiers";
import {
    arrayMove,
    SortableContext,
    sortableKeyboardCoordinates,
    verticalListSortingStrategy,
    useSortable,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

// API 함수 및 타입
import {
    submitApproval,
    submitSecurityApproval,
    createSubmitApprovalRequest,
    createApprovalLine,
} from "@/lib/knox-api/approval/approval";
import type {
    ApprovalLine,
    SubmitApprovalRequest,
} from "@/lib/knox-api/approval/approval";

// 역할 텍스트 매핑 (기존 mock util 대체)
const getRoleText = (role: string) => {
    const map: Record<string, string> = {
        "0": "기안",
        "1": "결재",
        "2": "합의",
        "3": "후결",
        "4": "병렬합의",
        "7": "병렬결재",
        "9": "통보",
    };
    return map[role] || role;
};

// TiptapEditor 컴포넌트
import RichTextEditor from "@/components/rich-text-editor/RichTextEditor";

// UserSelector 컴포넌트
import {
    UserSelector,
    type UserSelectItem,
} from "@/components/common/user/user-selector";
// next-auth 세션 의존 제거

// UserSelector에서 반환되는 사용자에 epId가 포함될 수 있으므로 확장 타입 정의
interface ExtendedUserSelectItem extends UserSelectItem {
    epId?: string;
}

// 역할 코드 타입 정의
type ApprovalRole = "0" | "1" | "2" | "3" | "4" | "7" | "9";

// 결재 라인 아이템 타입 정의 (고유 ID 포함)
interface ApprovalLineItem {
    id: string; // 내부 고유 식별자
    epId?: string; // Knox 고유 ID (전사 고유)
    userId?: string; // DB User PK
    emailAddress?: string;
    name?: string; // 사용자 이름
    deptName?: string; // 부서명
    role: ApprovalRole;
    seq: string;
    opinion?: string;
}

const formSchema = z.object({
    subject: z.string().min(1, "제목은 필수입니다"),
    contents: z.string().min(1, "내용은 필수입니다"),
    contentsType: z.literal("HTML"),
    docSecuType: z.enum(["PERSONAL", "CONFIDENTIAL", "CONFIDENTIAL_STRICT"]),
    urgYn: z.boolean(),
    importantYn: z.boolean(),
    notifyOption: z.enum(["0", "1", "2", "3"]),
    docMngSaveCode: z.enum(["0", "1"]),
    sbmLang: z.enum(["ko", "ja", "zh", "en"]),
    timeZone: z.string().default("GMT+9"),
    aplns: z
        .array(
            z.object({
                id: z.string(), // 고유 식별자
                epId: z.string().optional(),
                userId: z.string().optional(),
                emailAddress: z
                    .string()
                    .email("유효한 이메일 주소를 입력해주세요")
                    .optional(),
                name: z.string().optional(),
                deptName: z.string().optional(),
                role: z.enum(["0", "1", "2", "3", "4", "7", "9"]),
                seq: z.string(),
                opinion: z.string().optional(),
            }),
        )
        .min(1, "최소 1개의 결재 경로가 필요합니다"),
    // 첨부파일 (선택)
    attachments: z.any().optional(),
});

type FormData = z.infer<typeof formSchema>;

interface ApprovalSubmitProps {
    onSubmitSuccess?: (apInfId: string) => void;
}

// Sortable한 결재 라인 컴포넌트
interface SortableApprovalLineProps {
    apln: ApprovalLineItem;
    index: number;
    form: ReturnType<typeof useForm<FormData>>;
    onRemove: () => void;
    canRemove: boolean;
    selected: boolean;
    onSelect: () => void;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function SortableApprovalLine({
    apln,
    index,
    form,
    onRemove,
    canRemove,
    selected,
    onSelect,
}: SortableApprovalLineProps) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: apln.id }); // 고유 ID 사용

    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
        opacity: isDragging ? 0.5 : 1, // 드래그 중일 때 투명도 조절
    };

    return (
        <div
            ref={setNodeRef}
            style={style}
            className={`flex items-center gap-3 p-3 border rounded-lg bg-white shadow-sm ${selected ? "ring-2 ring-primary" : ""}`}
        >
            {/* 드래그 핸들 */}
            <div
                {...attributes}
                {...listeners}
                className="cursor-grab hover:cursor-grabbing text-gray-400 hover:text-gray-600"
            >
                <GripVertical className="w-5 h-5" />
            </div>

            {/* 선택 체크박스 (상신자는 제외하지만 공간은 확보) */}
            {index !== 0 ? (
                <Checkbox
                    checked={selected}
                    onCheckedChange={() => onSelect()}
                    onClick={(e) => e.stopPropagation()}
                />
            ) : (
                <div className="w-4 h-4" /> // 기안자용 빈 공간 (체크박스가 없으므로)
            )}

            {/* 실제 seq 기준 표시 */}
            <Badge variant="outline">{parseInt(apln.seq) + 1}</Badge>

            <div className="flex-1 grid grid-cols-4 gap-3">
                {/* 사용자 정보 표시 */}
                <div className="flex items-center space-x-2">
                    <div>
                        <div className="font-medium text-sm">
                            {apln.name || "Knox 이름 없음"}
                            {apln.deptName ? ` / ${apln.deptName}` : ""}
                        </div>
                    </div>
                    <FormField
                        control={form.control}
                        name={`aplns.${index}.id`}
                        render={() => (
                            <FormItem className="hidden">
                                <FormControl>
                                    <Input type="hidden" />
                                </FormControl>
                                <FormMessage />
                            </FormItem>
                        )}
                    />
                    <FormField
                        control={form.control}
                        name={`aplns.${index}.epId`}
                        render={() => (
                            <FormItem className="hidden">
                                <FormControl>
                                    <Input type="hidden" />
                                </FormControl>
                                <FormMessage />
                            </FormItem>
                        )}
                    />
                    <FormField
                        control={form.control}
                        name={`aplns.${index}.userId`}
                        render={() => (
                            <FormItem className="hidden">
                                <FormControl>
                                    <Input type="hidden" />
                                </FormControl>
                                <FormMessage />
                            </FormItem>
                        )}
                    />
                    <FormField
                        control={form.control}
                        name={`aplns.${index}.emailAddress`}
                        render={() => (
                            <FormItem className="hidden">
                                <FormControl>
                                    <Input type="hidden" />
                                </FormControl>
                                <FormMessage />
                            </FormItem>
                        )}
                    />
                </div>

                {/* 역할 선택 */}
                {index === 0 ? (
                    // 상신자는 역할 선택 대신 고정 표시
                    <div className="flex items-center">
                        <Badge variant="secondary">기안</Badge>
                    </div>
                ) : (
                    <FormField
                        control={form.control}
                        name={`aplns.${index}.role`}
                        render={({ field }) => {
                            // 병렬 여부 판단
                            const isParallel =
                                field.value === "4" || field.value === "7";

                            // 병렬, 후결 값을 제외한 기본 역할
                            const baseRole: ApprovalRole =
                                field.value === "7"
                                    ? "1"
                                    : field.value === "4"
                                      ? "2"
                                      : field.value === "3"
                                        ? "1"
                                        : (field.value as ApprovalRole);

                            // 기본 역할 변경 핸들러
                            const handleBaseRoleChange = (val: string) => {
                                if (!val) return;
                                let newRole = val;
                                if (isParallel) {
                                    if (val === "1") newRole = "7";
                                    else if (val === "2") newRole = "4";
                                }
                                field.onChange(newRole);
                            };

                            // 병렬인 경우 한 개 버튼으로 표시
                            if (isParallel) {
                                return (
                                    <FormItem className="w-full">
                                        <Badge
                                            className="w-full justify-center"
                                            variant="secondary"
                                        >
                                            {getRoleText(field.value)}
                                        </Badge>
                                    </FormItem>
                                );
                            }

                            return (
                                <FormItem>
                                    <div className="flex flex-col gap-2">
                                        <ToggleGroup
                                            type="single"
                                            value={baseRole}
                                            onValueChange={handleBaseRoleChange}
                                        >
                                            <ToggleGroupItem value="1">
                                                결재
                                            </ToggleGroupItem>
                                            <ToggleGroupItem value="2">
                                                합의
                                            </ToggleGroupItem>
                                            <ToggleGroupItem value="9">
                                                통보
                                            </ToggleGroupItem>
                                        </ToggleGroup>
                                    </div>
                                    <FormMessage />
                                </FormItem>
                            );
                        }}
                    />
                )}

                {/* 의견 입력란 제거됨 */}

                {/* 역할 표시 */}
                <div className="flex items-center justify-between">
                    <Badge variant="secondary">{getRoleText(apln.role)}</Badge>

                    {canRemove && (
                        <Button
                            type="button"
                            variant="ghost"
                            size="sm"
                            onClick={onRemove}
                        >
                            <Trash2 className="w-4 h-4" />
                        </Button>
                    )}
                </div>
            </div>
        </div>
    );
}

// Sortable Approval Group (seq 단위 카드)
interface SortableApprovalGroupProps {
    group: ApprovalLineItem[]; // 동일 seq 항목들
    index: number;
    form: ReturnType<typeof useForm<FormData>>;
    onRemoveGroup: () => void;
    canRemove: boolean;
    selected: boolean;
    onSelect: () => void;
}

function SortableApprovalGroup({
    group,
    index,
    form,
    onRemoveGroup,
    canRemove,
    selected,
    onSelect,
}: SortableApprovalGroupProps) {
    const seq = group[0].seq;
    const role = group[0].role;
    // 그룹을 식별할 안정적인 고유 키(첫 구성원의 id 활용)
    const groupKey = group[0].id;

    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: groupKey });

    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
        opacity: isDragging ? 0.5 : 1,
    };

    return (
        <div
            ref={setNodeRef}
            style={style}
            className={`flex items-center gap-3 p-3 border rounded-lg bg-white shadow-sm ${selected ? "ring-2 ring-primary" : ""}`}
        >
            {/* 드래그 핸들 */}
            <div
                {...attributes}
                {...listeners}
                className="cursor-grab hover:cursor-grabbing text-gray-400 hover:text-gray-600"
            >
                <GripVertical className="w-5 h-5" />
            </div>

            {/* 그룹 선택 체크박스 (상신자 제외하지만 공간은 확보) */}
            {index !== 0 ? (
                <Checkbox
                    checked={selected}
                    onCheckedChange={onSelect}
                    onClick={(e) => e.stopPropagation()}
                />
            ) : (
                <div className="w-4 h-4" /> // 기안자용 빈 공간
            )}

            {/* seq 표시 */}
            <Badge variant="outline">{parseInt(seq) + 1}</Badge>

            {/* 그룹 상세 정보 */}
            <div className="flex-1 grid grid-cols-3 gap-3">
                {/* 사용자 목록 */}
                <div className="flex flex-col justify-center gap-1">
                    {group.map((u) => (
                        <div key={u.id} className="text-sm">
                            {u.name || "Knox 이름 없음"}
                            {u.deptName ? ` / ${u.deptName}` : ""}
                        </div>
                    ))}
                </div>

                {/* 역할 */}
                <div className="flex items-center">
                    {seq === "0" ? (
                        <Badge
                            variant="secondary"
                            className="w-full justify-center"
                        >
                            기안
                        </Badge>
                    ) : role === "7" || role === "4" ? (
                        <Badge
                            variant="secondary"
                            className="w-full justify-center"
                        >
                            {getRoleText(role)}
                        </Badge>
                    ) : (
                        // 단일일 때는 기존 토글 재사용 (첫 항목 기준)
                        <FormField
                            control={form.control}
                            name={`aplns.${form.getValues("aplns").findIndex((a) => a.id === group[0].id)}.role`}
                            render={({ field }) => (
                                <ToggleGroup
                                    type="single"
                                    value={field.value}
                                    onValueChange={field.onChange}
                                >
                                    <ToggleGroupItem value="1">
                                        결재
                                    </ToggleGroupItem>
                                    <ToggleGroupItem value="2">
                                        합의
                                    </ToggleGroupItem>
                                    <ToggleGroupItem value="9">
                                        통보
                                    </ToggleGroupItem>
                                </ToggleGroup>
                            )}
                        />
                    )}
                </div>

                {/* 삭제 버튼 */}
                <div className="flex items-center justify-end">
                    {canRemove && (
                        <Button
                            type="button"
                            variant="ghost"
                            size="sm"
                            onClick={onRemoveGroup}
                        >
                            <Trash2 className="w-4 h-4" />
                        </Button>
                    )}
                </div>
            </div>
        </div>
    );
}

export default function ApprovalSubmit({
    onSubmitSuccess,
    currentUser,
}: ApprovalSubmitProps & { currentUser?: { id: number | string; name: string | null | undefined; email: string; epId?: string | null } }) {
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [submitResult, setSubmitResult] = useState<{
        apInfId: string;
    } | null>(null);

    const [selectedSeqs, setSelectedSeqs] = useState<string[]>([]);

    // 그룹 단위 선택/해제
    const toggleSelectGroup = (seq: string) => {
        setSelectedSeqs((prev) =>
            prev.includes(seq) ? prev.filter((s) => s !== seq) : [...prev, seq],
        );
    };
    const clearSelection = () => setSelectedSeqs([]);

    const form = useForm<FormData>({
        resolver: zodResolver(formSchema),
        defaultValues: {
            subject: "",
            contents: "",
            contentsType: "HTML",
            docSecuType: "PERSONAL",
            urgYn: false,
            importantYn: false,
            notifyOption: "0",
            docMngSaveCode: "0",
            sbmLang: "ko",
            timeZone: "GMT+9",
            aplns: [],
            attachments: undefined,
        },
    });

    const aplns = form.watch("aplns");

    // 병렬 전환 핸들러
    const applyParallel = () => {
        if (selectedSeqs.length < 2) {
            toast.error("두 명 이상 선택해야 병렬 지정이 가능합니다.");
            return;
        }

        const current = form.getValues("aplns");
        const selectedAplns = current.filter((a) => selectedSeqs.includes(a.seq));

        const roles = Array.from(new Set(selectedAplns.map((a) => a.role)));
        if (roles.length !== 1) {
            toast.error("선택된 항목의 역할이 동일해야 합니다.");
            return;
        }

        const role = roles[0];
        let newRole: ApprovalRole;
        if (role === "1") {
            newRole = "7"; // 병렬 결재
        } else if (role === "2") {
            newRole = "4"; // 병렬 합의
        } else if (role === "9") {
            newRole = "9"; // 병렬 통보(역할 코드 유지)
        } else {
            toast.error("결재, 합의 또는 통보만 병렬 지정 가능합니다.");
            return;
        }

        const minSeq = Math.min(...selectedAplns.map((a) => parseInt(a.seq)));

        const updated = current.map((a) => {
            if (selectedSeqs.includes(a.seq)) {
                return { ...a, role: newRole as ApprovalRole, seq: minSeq.toString() };
            }
            return a;
        });

        form.setValue("aplns", reorderBySeq(updated), { shouldDirty: true });
        clearSelection();
    };

    // 후결 전환 핸들러
    const applyAfter = () => {
        if (selectedSeqs.length !== 1) {
            toast.error("후결은 한 명만 지정할 수 있습니다.");
            return;
        }

        const targetSeq = selectedSeqs[0];

        // 병렬 그룹(결재:7, 합의:4)은 후결 전환 불가
        const targetRole = form.getValues("aplns").find((a) => a.seq === targetSeq)?.role;
        if (targetRole === "7" || targetRole === "4") {
            toast.error("병렬 그룹은 후결로 전환할 수 없습니다.");
            return;
        }

        const updated = form.getValues("aplns").map((a) => {
            if (a.seq === targetSeq) {
                return { ...a, role: (a.role === "3" ? "1" : "3") as ApprovalRole };
            }
            return a;
        });

        form.setValue("aplns", reorderBySeq(updated), { shouldDirty: true });
        clearSelection();
    };

    // 병렬 해제 핸들러
    const ungroupParallel = () => {
        if (selectedSeqs.length === 0) {
            toast.error("해제할 결재선을 선택하세요.");
            return;
        }

        let newSeqCounter = 1; // 0은 상신자 유지
        const updated = form.getValues("aplns").map((a) => {
            if (selectedSeqs.includes(a.seq)) {
                let newRole: ApprovalRole = a.role;
                if (a.role === "7") newRole = "1";
                if (a.role === "4") newRole = "2";

                return { ...a, role: newRole, seq: "" }; // seq 임시 비움
            }
            return { ...a };
        });

        // seq 재할당 (상신자 제외하고 순차)
        const reassigned = updated
            .sort((x, y) => parseInt(x.seq || "0") - parseInt(y.seq || "0"))
            .map((a) => {
                if (a.seq === "0") return a; // 상신자
                const newItem = { ...a, seq: newSeqCounter.toString() };
                newSeqCounter += 1;
                return newItem;
            });

        form.setValue("aplns", reassigned as FormData["aplns"], { shouldDirty: true });
        clearSelection();
    };

    // seq 기준 정렬 및 재번호 부여 (병렬 그룹은 동일 seq 유지)
    const reorderBySeq = (list: FormData["aplns"]): FormData["aplns"] => {
        const sorted = [...list].sort((a, b) => parseInt(a.seq) - parseInt(b.seq));

        // 기존 seq -> 새 seq 매핑. 병렬 그룹(동일 seq)은 동일한 새 seq 를 갖도록 처리
        const seqMap = new Map<string, string>();
        let nextSeq = 0;

        return sorted.map((apln) => {
            if (!seqMap.has(apln.seq)) {
                seqMap.set(apln.seq, nextSeq.toString());
                nextSeq += 1;
            }
            return { ...apln, seq: seqMap.get(apln.seq)! };
        });
    };

    // 로그인 사용자를 첫 번째 결재자로 보장하는 effect (prop만 사용)
    useEffect(() => {
        if (!currentUser?.email) return;
        const effectiveEmail = currentUser.email;
        const effectiveEpId = currentUser.epId ?? undefined;
        const effectiveUserId = currentUser.id as string | number | undefined;

        let currentAplns = form.getValues("aplns");

        // 이미 포함되어 있는지 확인 (epId 또는 email 기준)
        const selfIndex = currentAplns.findIndex(
            (a) => (effectiveEpId && a.epId === effectiveEpId) || a.emailAddress === effectiveEmail,
        );

        if (selfIndex === -1) {
            // 맨 앞에 상신자 추가
            const newSelf: FormData["aplns"][number] = {
                id: generateUniqueId(),
                epId: effectiveEpId,
                userId: effectiveUserId ? effectiveUserId.toString() : undefined,
                emailAddress: effectiveEmail,
                name: currentUser?.name ?? undefined,
                role: "0", // 기안
                seq: "0",
                opinion: "",
            };

            currentAplns = [newSelf, ...currentAplns];
        }

        // seq 재정렬 보장
        currentAplns = currentAplns.map((apln, idx) => ({ ...apln, seq: idx.toString() }));

        form.setValue("aplns", currentAplns, { shouldValidate: false, shouldDirty: true });
    }, [currentUser, form]);

    // dnd-kit sensors
    const sensors = useSensors(
        useSensor(PointerSensor, {
            activationConstraint: {
                distance: 8,
            },
        }),
        useSensor(KeyboardSensor, {
            coordinateGetter: sortableKeyboardCoordinates,
        })
    );

    // 고유 ID 생성 함수
    const generateUniqueId = () => {
        return `apln-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    };

    // 결재자 추가 (UserSelector를 통해)
    const addApprovalUsers = (users: UserSelectItem[]) => {
        const newAplns = [...aplns];

        users.forEach((user) => {
            // 이미 추가된 사용자인지 확인
            const existingIndex = newAplns.findIndex(apln => apln.userId === user.id.toString());
            if (existingIndex === -1) {
                // 새 사용자 추가
                const newSeq = (newAplns.length).toString(); // 0은 상신자
                const newApln: FormData["aplns"][number] = {
                    id: generateUniqueId(), // 고유 ID 생성
                    epId: (user as ExtendedUserSelectItem).epId, // epId가 전달되면 사용
                    userId: user.id.toString(),
                    emailAddress: user.email,
                    name: user.name,
                    deptName: (user as ExtendedUserSelectItem).deptName ?? undefined,
                    role: "1", // 기본값: 결재
                    seq: newSeq,
                    opinion: "",
                };
                newAplns.push(newApln);
            }
        });

        form.setValue("aplns", newAplns);
    };

    // 그룹 삭제 (seq 기반)
    const removeApprovalGroup = (seq: string) => {
        if (seq === "0") return; // 상신자 삭제 불가

        const remaining = aplns.filter((a) => a.seq !== seq);

        // seq 재정렬 (병렬 그룹 유지)
        const reordered = reorderBySeq(remaining);
        form.setValue("aplns", reordered);
    };

    // 기존 단일 삭제 로직은 더 이상 사용하지 않음 (호환 위해 남겨둠)
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const removeApprovalLine = (index: number) => {
        // 첫 번째(상신자)는 삭제 불가
        if (index === 0) return;

        if (aplns.length > 1) {
            const newAplns = aplns.filter((_: FormData["aplns"][number], i: number) => i !== index);
            // 순서 재정렬 (ID는 유지)
            const reorderedAplns = newAplns.map((apln: FormData["aplns"][number], i: number) => ({
                ...apln,
                seq: (i).toString(),
            }));
            form.setValue("aplns", reorderedAplns);
        }
    };

    // 드래그앤드롭 핸들러 (그룹 이동 지원)
    const handleDragEnd = (event: DragEndEvent) => {
        const { active, over } = event;

        if (!over || active.id === over.id) return;

        // 현재 id는 그룹의 고유 key(첫 라인 id)
        const activeKey = active.id as string;
        const overKey = over.id as string;

        // key → seq 매핑 생성
        const idToSeq = new Map<string, string>();
        aplns.forEach((a) => {
            // 같은 seq 내 첫 번째 id만 매핑하면 충분하지만, 안전하게 모두 매핑
            idToSeq.set(a.id, a.seq);
        });

        const activeSeq = idToSeq.get(activeKey);
        const overSeq = idToSeq.get(overKey);

        if (!activeSeq || !overSeq) return;

        if (activeSeq === "0" || overSeq === "0") return; // 상신자는 이동 불가

        // 현재 그룹 순서를 key 기반으로 계산
        const seqOrder = Array.from(new Set(aplns.map((a) => a.seq)));
        const keyOrder = seqOrder.map((seq) => {
            return aplns.find((a) => a.seq === seq)!.id;
        });

        const oldIndex = keyOrder.indexOf(activeKey);
        const newIndex = keyOrder.indexOf(overKey);

        const newKeyOrder = arrayMove(keyOrder, oldIndex, newIndex);

        // key → 새 seq 매핑
        const keyToNewSeq = new Map<string, string>();
        newKeyOrder.forEach((k, idx) => {
            keyToNewSeq.set(k, idx.toString());
        });

        // aplns 재구성 + seq 재할당
        const updatedAplns: FormData["aplns"] = [];
        newKeyOrder.forEach((k) => {
            const oldSeq = idToSeq.get(k)!;
            const groupItems = aplns.filter((a) => a.seq === oldSeq);
            groupItems.forEach((item) => {
                updatedAplns.push({ ...item, seq: keyToNewSeq.get(k)! });
            });
        });

        form.setValue("aplns", updatedAplns, { shouldValidate: false, shouldDirty: true });
    };

    const onSubmit = async (data: FormData) => {
        setIsSubmitting(true);
        setSubmitResult(null);

        try {
            // 사용자 정보 (prop 전용)
            if (!currentUser) {
                toast.error("사용자 정보를 불러올 수 없습니다.");
                return;
            }

            const effectiveEmail = currentUser.email;
            const effectiveEpId = currentUser.epId ?? undefined;
            const effectiveUserId = String(currentUser.id ?? "");

            debugLog("Current User", { email: effectiveEmail, epId: effectiveEpId, userId: effectiveUserId });

            if (!effectiveEpId) {
                toast.error("사용자 정보가 올바르지 않습니다.");
                return;
            }

            // 결재 경로 생성 (ID 제거하고 API 호출)
            const approvalLines: ApprovalLine[] = await Promise.all(
                data.aplns.map((apln) =>
                    createApprovalLine(
                        { epId: apln.epId },
                        apln.role,
                        apln.seq,
                        { opinion: apln.opinion },
                    ),
                ),
            );

            debugLog("Approval Lines", approvalLines);

            // 상신 요청 생성
            const attachmentsArray = data.attachments
                ? Array.from(data.attachments as FileList)
                : undefined;

            const submitRequest: SubmitApprovalRequest =
                await createSubmitApprovalRequest(
                    data.contents,
                    data.subject,
                    approvalLines,
                    {
                        contentsType: data.contentsType,
                        docSecuType: data.docSecuType,
                        urgYn: data.urgYn ? "Y" : "N",
                        importantYn: data.importantYn ? "Y" : "N",
                        notifyOption: data.notifyOption,
                        docMngSaveCode: data.docMngSaveCode,
                        sbmLang: data.sbmLang,
                        timeZone: data.timeZone,
                        attachments: attachmentsArray,
                    },
                );

            // API 호출 (보안 등급에 따라 분기)
            const isSecure =
                data.docSecuType === "CONFIDENTIAL" ||
                data.docSecuType === "CONFIDENTIAL_STRICT";

            debugLog("Submit Request", submitRequest);

            const response = isSecure
                ? await submitSecurityApproval(submitRequest, {
                      userId: effectiveUserId,
                      epId: effectiveEpId,
                      emailAddress: effectiveEmail,
                  })
                : await submitApproval(submitRequest, {
                      userId: effectiveUserId,
                      epId: effectiveEpId,
                      emailAddress: effectiveEmail,
                  });

            debugLog("Submit Response", response);

            if (response.result === "success") {
                setSubmitResult({ apInfId: response.data.apInfId });
                toast.success("결재가 성공적으로 상신되었습니다.");
                onSubmitSuccess?.(response.data.apInfId);
                form.reset();
            } else {
                toast.error(`결재 상신에 실패했습니다: ${response.result}`);
            }
        } catch (error) {
            debugError("결재 상신 오류", error);
            toast.error("결재 상신 중 오류가 발생했습니다.");
        } finally {
            setIsSubmitting(false);
        }
    };

    return (
        <Card className="w-full max-w-5xl">
            <CardHeader>
                <CardTitle className="flex items-center gap-2">
                    <FileText className="w-5 h-5" />
                    결재 상신
                </CardTitle>
                <CardDescription>새로운 결재를 상신합니다.</CardDescription>
            </CardHeader>

            <CardContent className="space-y-6">
                {submitResult && (
                    <div className="p-4 bg-green-50 border border-green-200 rounded-lg">
                        <div className="flex items-center gap-2 text-green-700">
                            <AlertCircle className="w-4 h-4" />
                            <span className="font-medium">상신 완료</span>
                        </div>
                        <p className="text-sm text-green-600 mt-1">
                            결재 ID: {submitResult.apInfId}
                        </p>
                    </div>
                )}

                <Form {...form}>
                    <form
                        onSubmit={form.handleSubmit(onSubmit)}
                        className="space-y-6"
                    >
                        {/* 기본 정보 */}
                        <div className="space-y-4">
                            <Separator />

                            {/* 결재 경로 */}
                            <div className="space-y-4">
                                <h3 className="text-lg font-semibold">
                                    결재 경로
                                </h3>

                                {/* 상단 제어 버튼 */}
                                <div className="flex justify-end gap-2 mb-2">
                                    <Button
                                        type="button"
                                        variant="outline"
                                        size="sm"
                                        onClick={applyParallel}
                                    >
                                        병렬
                                    </Button>
                                    <Button
                                        type="button"
                                        variant="outline"
                                        size="sm"
                                        onClick={applyAfter}
                                    >
                                        후결
                                    </Button>
                                    <Button
                                        type="button"
                                        variant="outline"
                                        size="sm"
                                        onClick={ungroupParallel}
                                    >
                                        해제
                                    </Button>
                                </div>

                                {/* 결재자 추가 섹션 */}
                                <div className="p-4 border border-dashed border-gray-300 rounded-lg">
                                    <div className="mb-2">
                                        <label className="text-sm font-medium text-gray-700">
                                            결재자 추가
                                        </label>
                                        <p className="text-xs text-gray-500">
                                            사용자를 검색하여 결재 라인에
                                            추가하세요
                                        </p>
                                    </div>
                                    <UserSelector
                                        selectedUsers={[]}
                                        onUsersChange={addApprovalUsers}
                                        placeholder="결재자를 검색하세요..."
                                        domainFilter={{
                                            type: "exclude",
                                            domains: ["partners"],
                                        }}
                                        maxSelections={10} // 최대 10명까지 추가 가능
                                    />
                                </div>

                                {/* 그룹 기반 렌더링 */}
                                {aplns.length > 0 &&
                                    (() => {
                                        const groups = Object.values(
                                            aplns.reduce<
                                                Record<
                                                    string,
                                                    ApprovalLineItem[]
                                                >
                                            >((acc, apln) => {
                                                acc[apln.seq] = acc[apln.seq]
                                                    ? [...acc[apln.seq], apln]
                                                    : [apln];
                                                return acc;
                                            }, {}),
                                        ).sort(
                                            (a, b) =>
                                                parseInt(a[0].seq) -
                                                parseInt(b[0].seq),
                                        );

                                        return (
                                            <DndContext
                                                sensors={sensors}
                                                collisionDetection={
                                                    closestCenter
                                                }
                                                modifiers={[
                                                    restrictToVerticalAxis,
                                                    restrictToParentElement,
                                                ]}
                                                onDragEnd={handleDragEnd}
                                            >
                                                <SortableContext
                                                    items={groups.map(
                                                        (g) => g[0].id,
                                                    )}
                                                    strategy={
                                                        verticalListSortingStrategy
                                                    }
                                                >
                                                    <div className="space-y-3">
                                                        {groups.map(
                                                            (group, idx) => (
                                                                <SortableApprovalGroup
                                                                    key={
                                                                        group[0]
                                                                            .id
                                                                    }
                                                                    group={
                                                                        group
                                                                    }
                                                                    index={idx}
                                                                    form={form}
                                                                    onRemoveGroup={() =>
                                                                        removeApprovalGroup(
                                                                            group[0]
                                                                                .seq,
                                                                        )
                                                                    }
                                                                    canRemove={
                                                                        idx !==
                                                                            0 &&
                                                                        aplns.length >
                                                                            1
                                                                    }
                                                                    selected={selectedSeqs.includes(
                                                                        group[0]
                                                                            .seq,
                                                                    )}
                                                                    onSelect={() =>
                                                                        toggleSelectGroup(
                                                                            group[0]
                                                                                .seq,
                                                                        )
                                                                    }
                                                                />
                                                            ),
                                                        )}
                                                    </div>
                                                </SortableContext>
                                            </DndContext>
                                        );
                                    })()}

                                {aplns.length === 0 && (
                                    <div className="text-center py-8 text-gray-500">
                                        <FileText className="w-12 h-12 mx-auto mb-2 opacity-50" />
                                        <p>결재자를 추가해주세요</p>
                                    </div>
                                )}
                            </div>

                            <FormField
                                control={form.control}
                                name="subject"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>제목 *</FormLabel>
                                        <FormControl>
                                            <Input
                                                placeholder="결재 제목을 입력하세요"
                                                {...field}
                                            />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            <FormField
                                control={form.control}
                                name="contents"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>내용 *</FormLabel>
                                        <FormControl>
                                            <RichTextEditor
                                                value={field.value}
                                                onChange={field.onChange}
                                                height="400px"
                                            />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            {/*  1 x 3 옵션 그리드 (보안 / 긴급 / 중요) */}
                            <div className="grid grid-cols-3 gap-4">
                                {/* 보안 등급 */}
                                <FormField
                                    control={form.control}
                                    name="docSecuType"
                                    render={({ field }) => (
                                        <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
                                            <FormLabel>보안</FormLabel>
                                            <FormControl>
                                                <Select
                                                    onValueChange={
                                                        field.onChange
                                                    }
                                                    defaultValue={field.value}
                                                >
                                                    <SelectTrigger className="w-24">
                                                        <SelectValue placeholder="등급" />
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        <SelectItem value="PERSONAL">
                                                            개인
                                                        </SelectItem>
                                                        <SelectItem value="CONFIDENTIAL">
                                                            기밀
                                                        </SelectItem>
                                                        <SelectItem value="CONFIDENTIAL_STRICT">
                                                            극기밀
                                                        </SelectItem>
                                                    </SelectContent>
                                                </Select>
                                            </FormControl>
                                        </FormItem>
                                    )}
                                />

                                {/* 긴급 여부 */}
                                <FormField
                                    control={form.control}
                                    name="urgYn"
                                    render={({ field }) => (
                                        <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
                                            <FormLabel>긴급</FormLabel>
                                            <FormControl>
                                                <Switch
                                                    checked={field.value}
                                                    onCheckedChange={
                                                        field.onChange
                                                    }
                                                />
                                            </FormControl>
                                        </FormItem>
                                    )}
                                />

                                {/* 중요 여부 */}
                                <FormField
                                    control={form.control}
                                    name="importantYn"
                                    render={({ field }) => (
                                        <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
                                            <FormLabel>중요</FormLabel>
                                            <FormControl>
                                                <Switch
                                                    checked={field.value}
                                                    onCheckedChange={
                                                        field.onChange
                                                    }
                                                />
                                            </FormControl>
                                        </FormItem>
                                    )}
                                />
                            </div>

                            {/* 첨부 파일 */}
                            <FormField
                                control={form.control}
                                name="attachments"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>첨부 파일</FormLabel>
                                        <FormControl>
                                            <Input
                                                type="file"
                                                multiple
                                                onChange={(e) =>
                                                    field.onChange(
                                                        e.target.files,
                                                    )
                                                }
                                            />
                                        </FormControl>
                                        <FormDescription>
                                            필요 시 파일을 선택하세요. (다중
                                            선택 가능)
                                        </FormDescription>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                        </div>

                        <Separator />

                        {/* 제출 버튼 */}
                        <div className="flex justify-end space-x-3">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => form.reset()}
                                disabled={isSubmitting}
                            >
                                초기화
                            </Button>
                            <Button type="submit" disabled={isSubmitting}>
                                {isSubmitting ? (
                                    <>
                                        <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                                        상신 중...
                                    </>
                                ) : (
                                    "결재 상신"
                                )}
                            </Button>
                        </div>
                    </form>
                </Form>
            </CardContent>
        </Card>
    );
}
