"use client";

import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Textarea } from "@/components/ui/textarea";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { toast } from "sonner";
import {
  Plus,
  Edit,
  Trash2,
  Search,
  Loader2,
  UserPlus,
  GripVertical,
} from "lucide-react";
import { ScrollToTop } from "@/components/common/ScrollToTop";
import {
  type ApprovalDefinition,
  type ApprovalLineTemplate,
  type ApprovalLineTemplateStep,
  getApprovalDefinitions,
  getApprovalTemplates,
  getApprovalTemplate,
  createApprovalTemplate,
  updateApprovalTemplate,
  deleteApprovalTemplate,
} from "@/lib/api/approval";
import { getUserList } from "@/lib/api/user";
import { ResponsiveDataView, RDVColumn, RDVCardField } from "@/components/common/ResponsiveDataView";

// ============================================================
// 타입 정의
// ============================================================

type StepType = "approval" | "consensus" | "notification";

interface StepApprover {
  approver_type: "user" | "position" | "dept";
  approver_user_id?: string;
  approver_position?: string;
  approver_dept_code?: string;
  approver_label?: string;
}

interface StepFormData {
  step_order: number;
  step_type: StepType;
  approvers: StepApprover[];
}

interface TemplateFormData {
  template_name: string;
  description: string;
  definition_id: number | null;
  steps: StepFormData[];
}

const STEP_TYPE_OPTIONS: { value: StepType; label: string }[] = [
  { value: "approval", label: "결재" },
  { value: "consensus", label: "합의" },
  { value: "notification", label: "통보" },
];

const STEP_TYPE_BADGE: Record<StepType, { label: string; variant: "default" | "secondary" | "outline" }> = {
  approval: { label: "결재", variant: "default" },
  consensus: { label: "합의", variant: "secondary" },
  notification: { label: "통보", variant: "outline" },
};

const INITIAL_FORM: TemplateFormData = {
  template_name: "",
  description: "",
  definition_id: null,
  steps: [
    {
      step_order: 1,
      step_type: "approval",
      approvers: [{ approver_type: "user", approver_user_id: "", approver_label: "1차 결재자" }],
    },
  ],
};

// ============================================================
// 사용자 검색 컴포넌트
// ============================================================

function UserSearchInput({
  value,
  label,
  onSelect,
  onLabelChange,
}: {
  value: string;
  label: string;
  onSelect: (userId: string, userName: string) => void;
  onLabelChange: (label: string) => void;
}) {
  const [searchText, setSearchText] = useState("");
  const [results, setResults] = useState<any[]>([]);
  const [showResults, setShowResults] = useState(false);
  const [searching, setSearching] = useState(false);
  const containerRef = React.useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setShowResults(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  const handleSearch = useCallback(
    async (text: string) => {
      setSearchText(text);
      if (text.length < 1) {
        setResults([]);
        setShowResults(false);
        return;
      }
      setSearching(true);
      try {
        const res = await getUserList({ search: text, limit: 10 });
        const users = res?.success !== false ? (res?.data || res || []) : [];
        setResults(Array.isArray(users) ? users : []);
        setShowResults(true);
      } catch {
        setResults([]);
      } finally {
        setSearching(false);
      }
    },
    [],
  );

  const selectUser = (user: any) => {
    const userId = user.user_id || user.userId || "";
    const userName = user.user_name || user.userName || userId;
    onSelect(userId, userName);
    setSearchText("");
    setShowResults(false);
  };

  return (
    <div className="space-y-1.5">
      <div className="grid grid-cols-2 gap-2">
        <div>
          <Label className="text-[10px]">결재자 ID</Label>
          <div ref={containerRef} className="relative">
            <Input
              value={value || searchText}
              onChange={(e) => {
                if (value) {
                  onSelect("", "");
                }
                handleSearch(e.target.value);
              }}
              placeholder="ID 또는 이름 검색"
              className="h-7 text-xs"
            />
            {showResults && results.length > 0 && (
              <div className="absolute z-50 mt-1 max-h-40 w-full overflow-y-auto rounded-md border bg-popover shadow-md">
                {results.map((user, i) => (
                  <button
                    key={i}
                    type="button"
                    className="flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent"
                    onClick={() => selectUser(user)}
                  >
                    <span className="font-medium">{user.user_name || user.userName}</span>
                    <span className="text-muted-foreground">({user.user_id || user.userId})</span>
                  </button>
                ))}
              </div>
            )}
            {showResults && results.length === 0 && !searching && searchText.length > 0 && (
              <div className="absolute z-50 mt-1 w-full rounded-md border bg-popover p-2 text-center text-xs text-muted-foreground shadow-md">
                검색 결과 없음
              </div>
            )}
          </div>
        </div>
        <div>
          <Label className="text-[10px]">표시 라벨</Label>
          <Input
            value={label}
            onChange={(e) => onLabelChange(e.target.value)}
            placeholder="예: 팀장"
            className="h-7 text-xs"
          />
        </div>
      </div>
    </div>
  );
}

// ============================================================
// 단계 편집 행 컴포넌트
// ============================================================

function StepEditor({
  step,
  stepIndex,
  onUpdate,
  onRemove,
}: {
  step: StepFormData;
  stepIndex: number;
  onUpdate: (stepIndex: number, updated: StepFormData) => void;
  onRemove: (stepIndex: number) => void;
}) {
  const updateStepType = (newType: StepType) => {
    const updated = { ...step, step_type: newType };
    if (newType === "notification" && updated.approvers.length > 1) {
      updated.approvers = [updated.approvers[0]];
    }
    onUpdate(stepIndex, updated);
  };

  const addApprover = () => {
    onUpdate(stepIndex, {
      ...step,
      approvers: [
        ...step.approvers,
        { approver_type: "user", approver_user_id: "", approver_label: "" },
      ],
    });
  };

  const removeApprover = (approverIdx: number) => {
    if (step.approvers.length <= 1) return;
    onUpdate(stepIndex, {
      ...step,
      approvers: step.approvers.filter((_, i) => i !== approverIdx),
    });
  };

  const updateApprover = (approverIdx: number, field: string, value: string) => {
    onUpdate(stepIndex, {
      ...step,
      approvers: step.approvers.map((a, i) =>
        i === approverIdx ? { ...a, [field]: value } : a,
      ),
    });
  };

  const handleUserSelect = (approverIdx: number, userId: string, userName: string) => {
    onUpdate(stepIndex, {
      ...step,
      approvers: step.approvers.map((a, i) =>
        i === approverIdx
          ? { ...a, approver_user_id: userId, approver_label: a.approver_label || userName }
          : a,
      ),
    });
  };

  const badgeInfo = STEP_TYPE_BADGE[step.step_type];

  return (
    <div className="rounded-md border bg-muted/30 p-3 space-y-2">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <GripVertical className="h-4 w-4 text-muted-foreground" />
          <span className="text-xs font-semibold">{step.step_order}단계</span>
          <Badge variant={badgeInfo.variant} className="text-[10px]">
            {badgeInfo.label}
          </Badge>
        </div>
        <Button
          variant="ghost"
          size="icon"
          className="h-6 w-6 text-destructive"
          onClick={() => onRemove(stepIndex)}
        >
          <Trash2 className="h-3 w-3" />
        </Button>
      </div>

      <div>
        <Label className="text-[10px]">결재 유형</Label>
        <Select value={step.step_type} onValueChange={(v) => updateStepType(v as StepType)}>
          <SelectTrigger className="h-7 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {STEP_TYPE_OPTIONS.map((opt) => (
              <SelectItem key={opt.value} value={opt.value} className="text-xs">
                {opt.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {step.step_type === "notification" && (
        <p className="text-[10px] text-muted-foreground italic">
          (자동 처리됩니다 - 통보 대상자에게 알림만 발송)
        </p>
      )}

      <div className="space-y-2">
        {step.approvers.map((approver, aIdx) => (
          <div key={aIdx} className="rounded border bg-background p-2 space-y-1.5">
            <div className="flex items-center justify-between">
              <span className="text-[10px] font-medium text-muted-foreground">
                {step.step_type === "consensus"
                  ? `합의자 ${aIdx + 1}`
                  : step.step_type === "notification"
                    ? "통보 대상"
                    : "결재자"}
              </span>
              {step.approvers.length > 1 && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-5 w-5 text-destructive"
                  onClick={() => removeApprover(aIdx)}
                >
                  <Trash2 className="h-3 w-3" />
                </Button>
              )}
            </div>
            <div>
              <Label className="text-[10px]">결재자 유형</Label>
              <Select
                value={approver.approver_type}
                onValueChange={(v) => updateApprover(aIdx, "approver_type", v)}
              >
                <SelectTrigger className="h-7 text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="user" className="text-xs">사용자 지정</SelectItem>
                  <SelectItem value="position" className="text-xs">직급 지정</SelectItem>
                  <SelectItem value="dept" className="text-xs">부서 지정</SelectItem>
                </SelectContent>
              </Select>
            </div>
            {approver.approver_type === "user" && (
              <UserSearchInput
                value={approver.approver_user_id || ""}
                label={approver.approver_label || ""}
                onSelect={(userId, userName) => handleUserSelect(aIdx, userId, userName)}
                onLabelChange={(label) => updateApprover(aIdx, "approver_label", label)}
              />
            )}
            {approver.approver_type === "position" && (
              <div className="grid grid-cols-2 gap-2">
                <div>
                  <Label className="text-[10px]">직급</Label>
                  <Input
                    value={approver.approver_position || ""}
                    onChange={(e) => updateApprover(aIdx, "approver_position", e.target.value)}
                    placeholder="예: 부장, 이사"
                    className="h-7 text-xs"
                  />
                </div>
                <div>
                  <Label className="text-[10px]">표시 라벨</Label>
                  <Input
                    value={approver.approver_label || ""}
                    onChange={(e) => updateApprover(aIdx, "approver_label", e.target.value)}
                    placeholder="예: 팀장"
                    className="h-7 text-xs"
                  />
                </div>
              </div>
            )}
            {approver.approver_type === "dept" && (
              <div className="grid grid-cols-2 gap-2">
                <div>
                  <Label className="text-[10px]">부서 코드</Label>
                  <Input
                    value={approver.approver_dept_code || ""}
                    onChange={(e) => updateApprover(aIdx, "approver_dept_code", e.target.value)}
                    placeholder="예: DEPT001"
                    className="h-7 text-xs"
                  />
                </div>
                <div>
                  <Label className="text-[10px]">표시 라벨</Label>
                  <Input
                    value={approver.approver_label || ""}
                    onChange={(e) => updateApprover(aIdx, "approver_label", e.target.value)}
                    placeholder="예: 경영지원팀"
                    className="h-7 text-xs"
                  />
                </div>
              </div>
            )}
          </div>
        ))}
      </div>

      {step.step_type === "consensus" && (
        <Button
          variant="outline"
          size="sm"
          onClick={addApprover}
          className="h-6 w-full gap-1 text-[10px]"
        >
          <UserPlus className="h-3 w-3" />
          합의자 추가
        </Button>
      )}
    </div>
  );
}

// ============================================================
// 메인 페이지
// ============================================================

export default function ApprovalTemplatePage() {
  const [templates, setTemplates] = useState<ApprovalLineTemplate[]>([]);
  const [definitions, setDefinitions] = useState<ApprovalDefinition[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchTerm, setSearchTerm] = useState("");

  const [editOpen, setEditOpen] = useState(false);
  const [editingTpl, setEditingTpl] = useState<ApprovalLineTemplate | null>(null);
  const [saving, setSaving] = useState(false);
  const [formData, setFormData] = useState<TemplateFormData>({ ...INITIAL_FORM });

  const [deleteTarget, setDeleteTarget] = useState<ApprovalLineTemplate | null>(null);

  const fetchData = useCallback(async () => {
    setLoading(true);
    const [tplRes, defRes] = await Promise.all([
      getApprovalTemplates(),
      getApprovalDefinitions({ is_active: "Y" }),
    ]);
    if (tplRes.success && tplRes.data) setTemplates(tplRes.data);
    if (defRes.success && defRes.data) setDefinitions(defRes.data);
    setLoading(false);
  }, []);

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

  const stepsToFormData = (steps: ApprovalLineTemplateStep[]): StepFormData[] => {
    const stepMap = new Map<number, StepFormData>();

    const sorted = [...steps].sort((a, b) => a.step_order - b.step_order);
    for (const s of sorted) {
      const existing = stepMap.get(s.step_order);
      const approver: StepApprover = {
        approver_type: s.approver_type,
        approver_user_id: s.approver_user_id,
        approver_position: s.approver_position,
        approver_dept_code: s.approver_dept_code,
        approver_label: s.approver_label,
      };

      if (existing) {
        existing.approvers.push(approver);
        if (s.step_type) existing.step_type = s.step_type;
      } else {
        stepMap.set(s.step_order, {
          step_order: s.step_order,
          step_type: s.step_type || "approval",
          approvers: [approver],
        });
      }
    }

    return Array.from(stepMap.values()).sort((a, b) => a.step_order - b.step_order);
  };

  const formDataToSteps = (
    steps: StepFormData[],
  ): Omit<ApprovalLineTemplateStep, "step_id" | "template_id" | "company_code">[] => {
    const result: Omit<ApprovalLineTemplateStep, "step_id" | "template_id" | "company_code">[] = [];
    for (const step of steps) {
      for (const approver of step.approvers) {
        result.push({
          step_order: step.step_order,
          step_type: step.step_type,
          approver_type: approver.approver_type,
          approver_user_id: approver.approver_user_id || undefined,
          approver_position: approver.approver_position || undefined,
          approver_dept_code: approver.approver_dept_code || undefined,
          approver_label: approver.approver_label || undefined,
        });
      }
    }
    return result;
  };

  const openCreate = () => {
    setEditingTpl(null);
    setFormData({
      template_name: "",
      description: "",
      definition_id: null,
      steps: [
        {
          step_order: 1,
          step_type: "approval",
          approvers: [{ approver_type: "user", approver_user_id: "", approver_label: "1차 결재자" }],
        },
      ],
    });
    setEditOpen(true);
  };

  const openEdit = async (tpl: ApprovalLineTemplate) => {
    const res = await getApprovalTemplate(tpl.template_id);
    if (!res.success || !res.data) {
      toast.error("템플릿 정보를 불러올 수 없습니다.");
      return;
    }
    const detail = res.data;
    setEditingTpl(detail);
    setFormData({
      template_name: detail.template_name,
      description: detail.description || "",
      definition_id: detail.definition_id || null,
      steps:
        detail.steps && detail.steps.length > 0
          ? stepsToFormData(detail.steps)
          : [
              {
                step_order: 1,
                step_type: "approval",
                approvers: [{ approver_type: "user", approver_user_id: "", approver_label: "1차 결재자" }],
              },
            ],
    });
    setEditOpen(true);
  };

  const addStep = () => {
    setFormData((p) => ({
      ...p,
      steps: [
        ...p.steps,
        {
          step_order: p.steps.length + 1,
          step_type: "approval",
          approvers: [
            {
              approver_type: "user",
              approver_user_id: "",
              approver_label: `${p.steps.length + 1}차 결재자`,
            },
          ],
        },
      ],
    }));
  };

  const removeStep = (idx: number) => {
    setFormData((p) => ({
      ...p,
      steps: p.steps
        .filter((_, i) => i !== idx)
        .map((s, i) => ({ ...s, step_order: i + 1 })),
    }));
  };

  const updateStep = (idx: number, updated: StepFormData) => {
    setFormData((p) => ({
      ...p,
      steps: p.steps.map((s, i) => (i === idx ? updated : s)),
    }));
  };

  const handleSave = async () => {
    if (!formData.template_name.trim()) {
      toast.warning("템플릿명을 입력해주세요.");
      return;
    }
    if (formData.steps.length === 0) {
      toast.warning("결재 단계를 최소 1개 추가해주세요.");
      return;
    }

    const hasEmptyApprover = formData.steps.some((step) =>
      step.approvers.some((a) => {
        if (a.approver_type === "user" && !a.approver_user_id) return true;
        if (a.approver_type === "position" && !a.approver_position) return true;
        if (a.approver_type === "dept" && !a.approver_dept_code) return true;
        return false;
      }),
    );

    if (hasEmptyApprover) {
      toast.warning("모든 결재자 정보를 입력해주세요.");
      return;
    }

    setSaving(true);
    const payload = {
      template_name: formData.template_name,
      description: formData.description || undefined,
      definition_id: formData.definition_id || undefined,
      steps: formDataToSteps(formData.steps),
    };

    let res;
    if (editingTpl) {
      res = await updateApprovalTemplate(editingTpl.template_id, payload);
    } else {
      res = await createApprovalTemplate(payload);
    }

    setSaving(false);
    if (res.success) {
      toast.success(editingTpl ? "수정되었습니다." : "등록되었습니다.");
      setEditOpen(false);
      fetchData();
    } else {
      toast.error(res.error || "저장 실패");
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    const res = await deleteApprovalTemplate(deleteTarget.template_id);
    if (res.success) {
      toast.success("삭제되었습니다.");
      setDeleteTarget(null);
      fetchData();
    } else {
      toast.error(res.error || "삭제 실패");
    }
  };

  const filtered = templates.filter(
    (t) =>
      t.template_name.toLowerCase().includes(searchTerm.toLowerCase()) ||
      (t.description || "").toLowerCase().includes(searchTerm.toLowerCase()),
  );

  const renderStepSummary = (tpl: ApprovalLineTemplate) => {
    if (!tpl.steps || tpl.steps.length === 0) return <span className="text-muted-foreground">-</span>;

    const stepMap = new Map<number, { type: StepType; count: number }>();
    for (const s of tpl.steps) {
      const existing = stepMap.get(s.step_order);
      if (existing) {
        existing.count++;
      } else {
        stepMap.set(s.step_order, { type: s.step_type || "approval", count: 1 });
      }
    }

    return (
      <div className="flex flex-wrap gap-1">
        {Array.from(stepMap.entries())
          .sort(([a], [b]) => a - b)
          .map(([order, info]) => {
            const badge = STEP_TYPE_BADGE[info.type];
            return (
              <Badge key={order} variant={badge.variant} className="text-[10px]">
                {order}단계 {badge.label}
                {info.count > 1 && ` (${info.count}명)`}
              </Badge>
            );
          })}
      </div>
    );
  };

  const formatDate = (dateStr: string) => {
    if (!dateStr) return "-";
    const d = new Date(dateStr);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  };

  const columns: RDVColumn<ApprovalLineTemplate>[] = [
    {
      key: "template_name",
      label: "템플릿명",
      render: (_val, tpl) => (
        <span className="font-medium">{tpl.template_name}</span>
      ),
    },
    {
      key: "description",
      label: "설명",
      hideOnMobile: true,
      render: (_val, tpl) => (
        <span className="text-muted-foreground">{tpl.description || "-"}</span>
      ),
    },
    {
      key: "steps",
      label: "단계 구성",
      render: (_val, tpl) => renderStepSummary(tpl),
    },
    {
      key: "definition_name",
      label: "연결된 유형",
      width: "120px",
      hideOnMobile: true,
      render: (_val, tpl) => (
        <span>{tpl.definition_name || "-"}</span>
      ),
    },
    {
      key: "created_at",
      label: "생성일",
      width: "100px",
      hideOnMobile: true,
      className: "text-center",
      render: (_val, tpl) => (
        <span className="text-center">{formatDate(tpl.created_at)}</span>
      ),
    },
  ];

  const cardFields: RDVCardField<ApprovalLineTemplate>[] = [
    {
      label: "단계 구성",
      render: (tpl) => renderStepSummary(tpl),
    },
    {
      label: "생성일",
      render: (tpl) => formatDate(tpl.created_at),
    },
  ];

  return (
    <div className="bg-background flex min-h-screen flex-col">
      <div className="space-y-6 p-6">
        {/* 페이지 헤더 */}
        <div className="space-y-2 border-b pb-4">
          <h1 className="text-3xl font-bold tracking-tight">결재 템플릿 관리</h1>
          <p className="text-muted-foreground text-sm">
            결재선 템플릿의 단계 구성 및 결재자를 관리합니다.
          </p>
        </div>

        {/* 검색 + 신규 등록 버튼 */}
        <div className="relative flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
          <div className="flex items-center gap-3">
            <div className="relative w-full sm:w-[300px]">
              <Search className="text-muted-foreground absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2" />
              <Input
                placeholder="템플릿명 또는 설명 검색..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className="h-10 pl-10 text-sm"
              />
            </div>
            <span className="text-muted-foreground text-sm">
              총 <span className="text-foreground font-semibold">{filtered.length}</span> 건
            </span>
          </div>
          <Button onClick={openCreate} className="h-10 gap-2 text-sm font-medium">
            <Plus className="h-4 w-4" />
            신규 등록
          </Button>
        </div>

        <ResponsiveDataView<ApprovalLineTemplate>
          data={filtered}
          columns={columns}
          keyExtractor={(tpl) => String(tpl.template_id)}
          isLoading={loading}
          emptyMessage="등록된 결재 템플릿이 없습니다."
          skeletonCount={5}
          cardTitle={(tpl) => tpl.template_name}
          cardSubtitle={(tpl) => tpl.description ? (
            <span className="text-muted-foreground text-sm">{tpl.description}</span>
          ) : undefined}
          cardHeaderRight={(tpl) => tpl.definition_name ? (
            <Badge variant="outline" className="text-xs">{tpl.definition_name}</Badge>
          ) : undefined}
          cardFields={cardFields}
          actionsLabel="관리"
          actionsWidth="100px"
          renderActions={(tpl) => (
            <>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8"
                onClick={() => openEdit(tpl)}
              >
                <Edit className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8 text-destructive"
                onClick={() => setDeleteTarget(tpl)}
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            </>
          )}
        />
      </div>

      {/* 등록/수정 Dialog */}
      <Dialog open={editOpen} onOpenChange={setEditOpen}>
        <DialogContent className="max-w-[95vw] sm:max-w-[600px]">
          <DialogHeader>
            <DialogTitle className="text-base sm:text-lg">
              {editingTpl ? "결재 템플릿 수정" : "결재 템플릿 등록"}
            </DialogTitle>
            <DialogDescription className="text-xs sm:text-sm">
              결재선의 기본 정보와 단계별 결재자를 설정합니다.
            </DialogDescription>
          </DialogHeader>
          <div className="max-h-[60vh] space-y-3 overflow-y-auto sm:space-y-4">
            <div>
              <Label htmlFor="template_name" className="text-xs sm:text-sm">
                템플릿 이름 *
              </Label>
              <Input
                id="template_name"
                value={formData.template_name}
                onChange={(e) => setFormData((p) => ({ ...p, template_name: e.target.value }))}
                placeholder="예: 일반 3단계 결재선"
                className="h-8 text-xs sm:h-10 sm:text-sm"
              />
            </div>
            <div>
              <Label htmlFor="description" className="text-xs sm:text-sm">
                설명
              </Label>
              <Textarea
                id="description"
                value={formData.description}
                onChange={(e) => setFormData((p) => ({ ...p, description: e.target.value }))}
                placeholder="템플릿에 대한 설명을 입력하세요"
                rows={2}
                className="text-xs sm:text-sm"
              />
            </div>
            <div>
              <Label className="text-xs sm:text-sm">결재 유형 연결</Label>
              <Select
                value={formData.definition_id ? String(formData.definition_id) : "none"}
                onValueChange={(v) =>
                  setFormData((p) => ({ ...p, definition_id: v === "none" ? null : Number(v) }))
                }
              >
                <SelectTrigger className="h-8 text-xs sm:h-10 sm:text-sm">
                  <SelectValue placeholder="결재 유형 선택 (선택사항)" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">연결 없음</SelectItem>
                  {definitions.map((d) => (
                    <SelectItem key={d.definition_id} value={String(d.definition_id)}>
                      {d.definition_name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <p className="text-muted-foreground mt-1 text-[10px] sm:text-xs">
                특정 결재 유형에 이 템플릿을 연결할 수 있습니다.
              </p>
            </div>

            <div className="space-y-3">
              <div className="flex items-center justify-between">
                <Label className="text-xs font-semibold sm:text-sm">결재 단계</Label>
                <Button variant="outline" size="sm" onClick={addStep} className="h-7 gap-1 text-xs">
                  <Plus className="h-3 w-3" />
                  단계 추가
                </Button>
              </div>

              {formData.steps.length === 0 && (
                <p className="text-muted-foreground py-4 text-center text-xs">
                  결재 단계를 추가해주세요.
                </p>
              )}

              {formData.steps.map((step, idx) => (
                <StepEditor
                  key={`step-${idx}-${step.step_order}`}
                  step={step}
                  stepIndex={idx}
                  onUpdate={updateStep}
                  onRemove={removeStep}
                />
              ))}
            </div>
          </div>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button
              variant="outline"
              onClick={() => setEditOpen(false)}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              취소
            </Button>
            <Button
              onClick={handleSave}
              disabled={saving}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              {saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              {editingTpl ? "수정" : "등록"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 삭제 확인 Dialog */}
      <AlertDialog open={!!deleteTarget} onOpenChange={() => setDeleteTarget(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>결재 템플릿 삭제</AlertDialogTitle>
            <AlertDialogDescription>
              &quot;{deleteTarget?.template_name}&quot;을(를) 삭제하시겠습니까?
              <br />
              이 작업은 되돌릴 수 없습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDelete}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              삭제
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <ScrollToTop />
    </div>
  );
}
