"use client";

import React, { useState, useEffect } from "react";
import { useParams, useRouter } from "next/navigation";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { RefreshCw, Save, ArrowLeft, Plus, Trash2 } from "lucide-react";
import { toast } from "sonner";
import {
  BatchAPI,
  BatchConfig,
  BatchMapping,
  ConnectionInfo,
} from "@/lib/api/batch";
import { BatchManagementAPI } from "@/lib/api/batchManagement";

interface BatchColumnInfo {
  column_name: string;
  data_type: string;
  is_nullable: string;
}

// 배치 타입 감지 함수
const detectBatchType = (mapping: BatchMapping): 'db-to-db' | 'restapi-to-db' | 'db-to-restapi' => {
  const fromType = mapping.from_connection_type;
  const toType = mapping.to_connection_type;
  
  if (fromType === 'restapi' && (toType === 'internal' || toType === 'external')) {
    return 'restapi-to-db';
  } else if ((fromType === 'internal' || fromType === 'external') && toType === 'restapi') {
    return 'db-to-restapi';
  } else {
    return 'db-to-db';
  }
};

export default function BatchEditPage() {
  const params = useParams();
  const router = useRouter();
  const batchId = parseInt(params.id as string);

  // 기본 상태
  const [loading, setLoading] = useState(false);
  const [batchConfig, setBatchConfig] = useState<BatchConfig | null>(null);
  const [batchName, setBatchName] = useState("");
  const [cronSchedule, setCronSchedule] = useState("0 12 * * *");
  const [description, setDescription] = useState("");
  const [isActive, setIsActive] = useState("Y");
  const [saveMode, setSaveMode] = useState<"INSERT" | "UPSERT">("INSERT");
  const [conflictKey, setConflictKey] = useState("");
  const [authServiceName, setAuthServiceName] = useState("");
  const [authServiceNames, setAuthServiceNames] = useState<string[]>([]);
  const [dataArrayPath, setDataArrayPath] = useState("");

  // 연결 정보
  const [connections, setConnections] = useState<ConnectionInfo[]>([]);
  const [fromConnection, setFromConnection] = useState<ConnectionInfo | null>(null);
  const [toConnection, setToConnection] = useState<ConnectionInfo | null>(null);
  
  // 테이블 및 컬럼 정보
  const [fromTables, setFromTables] = useState<string[]>([]);
  const [toTables, setToTables] = useState<string[]>([]);
  const [fromTable, setFromTable] = useState("");
  const [toTable, setToTable] = useState("");
  const [fromColumns, setFromColumns] = useState<BatchColumnInfo[]>([]);
  const [toColumns, setToColumns] = useState<BatchColumnInfo[]>([]);
  
  // 매핑 정보
  const [mappings, setMappings] = useState<BatchMapping[]>([]);
  
  // 배치 타입 감지
  const [batchType, setBatchType] = useState<'db-to-db' | 'restapi-to-db' | 'db-to-restapi' | null>(null);

  // REST API 미리보기 상태
  const [apiPreviewData, setApiPreviewData] = useState<any[]>([]);
  const [fromApiFields, setFromApiFields] = useState<string[]>([]);

  // 인증 토큰 모드 (직접 입력 / DB에서 선택)
  const [authTokenMode, setAuthTokenMode] = useState<"direct" | "db">("direct");
  const [fromApiKey, setFromApiKey] = useState("");

  // API 파라미터 설정
  const [apiParamType, setApiParamType] = useState<"none" | "url" | "query">("none");
  const [apiParamName, setApiParamName] = useState("");
  const [apiParamValue, setApiParamValue] = useState("");
  const [apiParamSource, setApiParamSource] = useState<"static" | "dynamic">("static");

  // 매핑 리스트 (새로운 UI용)
  interface MappingItem {
    id: string;
    dbColumn: string;
    sourceType: "api" | "fixed";
    apiField: string;
    fixedValue: string;
  }
  const [mappingList, setMappingList] = useState<MappingItem[]>([]);

  // 페이지 로드 시 배치 정보 조회
  useEffect(() => {
    if (batchId) {
      loadBatchConfig();
      loadConnections();
      loadAuthServiceNames();
    }
  }, [batchId]);

  // 인증 서비스명 목록 로드
  const loadAuthServiceNames = async () => {
    try {
      const names = await BatchAPI.getAuthServiceNames();
      setAuthServiceNames(names);
    } catch (error) {
      console.error("인증 서비스 목록 로드 실패:", error);
    }
  };

  // 연결 정보가 로드된 후 배치 설정의 연결 정보 설정
  useEffect(() => {
    if (batchConfig && connections.length > 0 && batchConfig.batch_mappings && batchConfig.batch_mappings.length > 0) {
      const firstMapping = batchConfig.batch_mappings[0];
      console.log("🔗 연결 정보 설정 시작:", firstMapping);
      
      // FROM 연결 정보 설정
      if (firstMapping.from_connection_type === 'internal') {
        setFromConnection({ type: 'internal', name: '내부 DB' });
        // 내부 DB 테이블 목록 로드
        BatchAPI.getTablesFromConnection({ type: 'internal', name: '내부 DB' }).then(tables => {
          console.log("📋 FROM 테이블 목록:", tables);
          setFromTables(tables);
          
          // 컬럼 정보도 로드
          if (firstMapping.from_table_name) {
            BatchAPI.getTableColumns({ type: 'internal', name: '내부 DB' }, firstMapping.from_table_name).then(columns => {
              console.log("📊 FROM 컬럼 목록:", columns);
              setFromColumns(columns);
            });
          }
        });
      } else if (firstMapping.from_connection_id) {
        const fromConn = connections.find(c => c.id === firstMapping.from_connection_id);
        if (fromConn) {
          setFromConnection(fromConn);
          // 외부 DB 테이블 목록 로드
          BatchAPI.getTablesFromConnection(fromConn).then(tables => {
            console.log("📋 FROM 테이블 목록:", tables);
            setFromTables(tables);
            
            // 컬럼 정보도 로드
            if (firstMapping.from_table_name) {
              BatchAPI.getTableColumns(fromConn, firstMapping.from_table_name).then(columns => {
                console.log("📊 FROM 컬럼 목록:", columns);
                setFromColumns(columns);
              });
            }
          });
        }
      }
      
      // TO 연결 정보 설정
      if (firstMapping.to_connection_type === 'internal') {
        setToConnection({ type: 'internal', name: '내부 DB' });
        // 내부 DB 테이블 목록 로드
        BatchAPI.getTablesFromConnection({ type: 'internal', name: '내부 DB' }).then(tables => {
          console.log("📋 TO 테이블 목록:", tables);
          setToTables(tables);
          
          // 컬럼 정보도 로드
          if (firstMapping.to_table_name) {
            BatchAPI.getTableColumns({ type: 'internal', name: '내부 DB' }, firstMapping.to_table_name).then(columns => {
              console.log("📊 TO 컬럼 목록:", columns);
              setToColumns(columns);
            });
          }
        });
      } else if (firstMapping.to_connection_id) {
        const toConn = connections.find(c => c.id === firstMapping.to_connection_id);
        if (toConn) {
          setToConnection(toConn);
          // 외부 DB 테이블 목록 로드
          BatchAPI.getTablesFromConnection(toConn).then(tables => {
            console.log("📋 TO 테이블 목록:", tables);
            setToTables(tables);
            
            // 컬럼 정보도 로드
            if (firstMapping.to_table_name) {
              BatchAPI.getTableColumns(toConn, firstMapping.to_table_name).then(columns => {
                console.log("📊 TO 컬럼 목록:", columns);
                setToColumns(columns);
              });
            }
          });
        }
      }
    }
  }, [batchConfig, connections]);

  // 배치 설정 조회
  const loadBatchConfig = async () => {
    try {
      setLoading(true);
      console.log("🔍 배치 설정 조회 시작:", batchId);
      
      const config = await BatchAPI.getBatchConfig(batchId);
      console.log("📋 조회된 배치 설정:", config);
      
      setBatchConfig(config);
      setBatchName(config.batch_name);
      setCronSchedule(config.cron_schedule);
      setDescription(config.description || "");
      setIsActive(config.is_active || "Y");
      setSaveMode((config as any).save_mode || "INSERT");
      setConflictKey((config as any).conflict_key || "");
      setAuthServiceName((config as any).auth_service_name || "");
      setDataArrayPath((config as any).data_array_path || "");
      
      // 인증 토큰 모드 설정
      if ((config as any).auth_service_name) {
        setAuthTokenMode("db");
      } else {
        setAuthTokenMode("direct");
      }
      
      if (config.batch_mappings && config.batch_mappings.length > 0) {
        // API 키 설정 (첫 번째 매핑에서)
        const firstMappingForApiKey = config.batch_mappings[0];
        if (firstMappingForApiKey.from_api_key) {
          setFromApiKey(firstMappingForApiKey.from_api_key);
        }
        console.log("📊 매핑 정보:", config.batch_mappings);
        console.log("📊 매핑 개수:", config.batch_mappings.length);
        config.batch_mappings.forEach((mapping, idx) => {
          console.log(`📊 매핑 #${idx + 1}:`, {
            from: `${mapping.from_column_name} (${mapping.from_column_type})`,
            to: `${mapping.to_column_name} (${mapping.to_column_type})`,
            type: mapping.mapping_type
          });
        });
        setMappings(config.batch_mappings);
        
        // 첫 번째 매핑에서 연결 및 테이블 정보 추출
        const firstMapping = config.batch_mappings[0];
        setFromTable(firstMapping.from_table_name);
        setToTable(firstMapping.to_table_name);
        
        // 배치 타입 감지
        const detectedBatchType = detectBatchType(firstMapping);
        setBatchType(detectedBatchType);
        console.log("🎯 감지된 배치 타입:", detectedBatchType);
        
        // FROM 연결 정보 설정
        if (firstMapping.from_connection_type === 'internal') {
          setFromConnection({ type: 'internal', name: '내부 DB' });
        } else if (firstMapping.from_connection_id) {
          // 외부 연결은 connections 로드 후 설정
          setTimeout(() => {
            const fromConn = connections.find(c => c.id === firstMapping.from_connection_id);
            if (fromConn) {
              setFromConnection(fromConn);
            }
          }, 100);
        }
        
        // TO 연결 정보 설정
        if (firstMapping.to_connection_type === 'internal') {
          setToConnection({ type: 'internal', name: '내부 DB' });
        } else if (firstMapping.to_connection_id) {
          // 외부 연결은 connections 로드 후 설정
          setTimeout(() => {
            const toConn = connections.find(c => c.id === firstMapping.to_connection_id);
            if (toConn) {
              setToConnection(toConn);
            }
          }, 100);
        }
        
        console.log("🔗 테이블 정보 설정:", {
          fromTable: firstMapping.from_table_name,
          toTable: firstMapping.to_table_name,
          fromConnectionType: firstMapping.from_connection_type,
          toConnectionType: firstMapping.to_connection_type
        });
        
        // 기존 매핑을 mappingList로 변환
        const convertedMappingList: MappingItem[] = config.batch_mappings.map((mapping, index) => ({
          id: `mapping-${index}-${Date.now()}`,
          dbColumn: mapping.to_column_name || "",
          sourceType: (mapping as any).mapping_type === "fixed" ? "fixed" as const : "api" as const,
          apiField: (mapping as any).mapping_type === "fixed" ? "" : mapping.from_column_name || "",
          fixedValue: (mapping as any).mapping_type === "fixed" ? mapping.from_column_name || "" : "",
        }));
        setMappingList(convertedMappingList);
        console.log("🔄 변환된 mappingList:", convertedMappingList);
      }
      
    } catch (error) {
      console.error("❌ 배치 설정 조회 오류:", error);
      toast.error("배치 설정을 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  // 연결 정보 조회
  const loadConnections = async () => {
    try {
      const connectionList = await BatchAPI.getConnections();
      setConnections(connectionList);
    } catch (error) {
      console.error("연결 정보 조회 오류:", error);
      toast.error("연결 정보를 불러오는데 실패했습니다.");
    }
  };

  // FROM 연결 변경 시
  const handleFromConnectionChange = async (connectionId: string) => {
    const connection = connections.find(c => c.id?.toString() === connectionId) || 
                     (connectionId === 'internal' ? { type: 'internal' as const, name: '내부 DB' } : null);
    
    if (connection) {
      setFromConnection(connection);
      
      try {
        const tables = await BatchAPI.getTablesFromConnection(connection);
        setFromTables(tables);
        setFromTable("");
        setFromColumns([]);
      } catch (error) {
        console.error("테이블 목록 조회 오류:", error);
        toast.error("테이블 목록을 불러오는데 실패했습니다.");
      }
    }
  };

  // TO 연결 변경 시
  const handleToConnectionChange = async (connectionId: string) => {
    const connection = connections.find(c => c.id?.toString() === connectionId) || 
                     (connectionId === 'internal' ? { type: 'internal' as const, name: '내부 DB' } : null);
    
    if (connection) {
      setToConnection(connection);
      
      try {
        const tables = await BatchAPI.getTablesFromConnection(connection);
        setToTables(tables);
        setToTable("");
        setToColumns([]);
      } catch (error) {
        console.error("테이블 목록 조회 오류:", error);
        toast.error("테이블 목록을 불러오는데 실패했습니다.");
      }
    }
  };

  // FROM 테이블 변경 시
  const handleFromTableChange = async (tableName: string) => {
    setFromTable(tableName);
    
    if (fromConnection && tableName) {
      try {
        const columns = await BatchAPI.getTableColumns(fromConnection, tableName);
        setFromColumns(columns);
      } catch (error) {
        console.error("컬럼 정보 조회 오류:", error);
        toast.error("컬럼 정보를 불러오는데 실패했습니다.");
      }
    }
  };

  // TO 테이블 변경 시
  const handleToTableChange = async (tableName: string) => {
    setToTable(tableName);
    
    if (toConnection && tableName) {
      try {
        const columns = await BatchAPI.getTableColumns(toConnection, tableName);
        setToColumns(columns);
      } catch (error) {
        console.error("컬럼 정보 조회 오류:", error);
        toast.error("컬럼 정보를 불러오는데 실패했습니다.");
      }
    }
  };

  // 매핑 추가
  const addMapping = () => {
    const newMapping: BatchMapping = {
      from_connection_type: fromConnection?.type === 'internal' ? 'internal' : 'external',
      from_connection_id: fromConnection?.type === 'internal' ? undefined : fromConnection?.id,
      from_table_name: fromTable,
      from_column_name: '',
      from_column_type: '',
      to_connection_type: toConnection?.type === 'internal' ? 'internal' : 'external',
      to_connection_id: toConnection?.type === 'internal' ? undefined : toConnection?.id,
      to_table_name: toTable,
      to_column_name: '',
      to_column_type: '',
      mapping_type: 'direct',
      mapping_order: mappings.length + 1
    };
    
    setMappings([...mappings, newMapping]);
  };

  // REST API → DB 매핑 추가
  const addRestapiToDbMapping = () => {
    if (!batchConfig || !batchConfig.batch_mappings || batchConfig.batch_mappings.length === 0) {
      return;
    }

    const first = batchConfig.batch_mappings[0] as any;

    const newMapping: BatchMapping = {
      // FROM: REST API (기존 설정 그대로 복사)
      from_connection_type: "restapi" as any,
      from_connection_id: first.from_connection_id,
      from_table_name: first.from_table_name,
      from_column_name: "",
      from_column_type: "",
      // TO: DB (기존 설정 그대로 복사)
      to_connection_type: first.to_connection_type as any,
      to_connection_id: first.to_connection_id,
      to_table_name: first.to_table_name,
      to_column_name: "",
      to_column_type: "",
      mapping_type: (first.mapping_type as any) || "direct",
      mapping_order: mappings.length + 1,
    };

    setMappings((prev) => [...prev, newMapping]);
  };

  // mappingList 관련 함수들 (새로운 UI용)
  const addMappingListItem = () => {
    const newId = `mapping-${Date.now()}`;
    setMappingList((prev) => [
      ...prev,
      {
        id: newId,
        dbColumn: "",
        sourceType: "api",
        apiField: "",
        fixedValue: "",
      },
    ]);
  };

  const removeMappingListItem = (id: string) => {
    setMappingList((prev) => prev.filter((m) => m.id !== id));
  };

  const updateMappingListItem = (id: string, updates: Partial<MappingItem>) => {
    setMappingList((prev) => prev.map((m) => (m.id === id ? { ...m, ...updates } : m)));
  };

  // REST API 데이터 미리보기 (수정 화면용)
  const previewRestApiData = async () => {
    if (!mappings || mappings.length === 0) {
      toast.error("미리보기할 REST API 매핑이 없습니다.");
      return;
    }

    const first: any = mappings[0];

    if (!first.from_api_url || !first.from_table_name) {
      toast.error("API URL과 엔드포인트 정보가 없습니다.");
      return;
    }

    try {
      const method =
        (first.from_api_method as "GET" | "POST" | "PUT" | "DELETE") || "GET";

      const paramInfo =
        first.from_api_param_type &&
        first.from_api_param_name &&
        first.from_api_param_value
          ? {
              paramType: first.from_api_param_type as "url" | "query",
              paramName: first.from_api_param_name as string,
              paramValue: first.from_api_param_value as string,
              paramSource:
                (first.from_api_param_source as "static" | "dynamic") ||
                "static",
            }
          : undefined;

      // authServiceName과 dataArrayPath 전달
      const result = await BatchManagementAPI.previewRestApiData(
        first.from_api_url,
        first.from_api_key || "",
        first.from_table_name,
        method,
        paramInfo,
        first.from_api_body || undefined,
        authServiceName || undefined,
        dataArrayPath || undefined
      );

      setApiPreviewData(result.samples || []);
      setFromApiFields(result.fields || []);

      toast.success(
        `API 데이터 미리보기 완료! ${result.fields.length}개 필드, ${result.samples.length}개 레코드`
      );
    } catch (error: any) {
      console.error("REST API 미리보기 오류:", error);
      toast.error(error?.message || "API 데이터 미리보기에 실패했습니다.");
    }
  };

  // 매핑 삭제
  const removeMapping = (index: number) => {
    const updatedMappings = mappings.filter((_, i) => i !== index);
    setMappings(updatedMappings);
  };

  // 매핑 업데이트
  const updateMapping = (index: number, field: keyof BatchMapping, value: any) => {
    setMappings(prevMappings => {
      const updatedMappings = [...prevMappings];
      updatedMappings[index] = { ...updatedMappings[index], [field]: value };
      return updatedMappings;
    });
  };

  // 배치 설정 저장
  const saveBatchConfig = async () => {
    // restapi-to-db인 경우 mappingList 사용, 아닌 경우 mappings 사용
    const effectiveMappings = batchType === "restapi-to-db" ? mappingList : mappings;
    
    if (!batchName || !cronSchedule || effectiveMappings.length === 0) {
      toast.error("필수 항목을 모두 입력해주세요.");
      return;
    }

    try {
      setLoading(true);
      
      // restapi-to-db인 경우 mappingList를 mappings 형식으로 변환
      let finalMappings: BatchMapping[] = mappings;
      
      if (batchType === "restapi-to-db" && batchConfig?.batch_mappings?.[0]) {
        const first = batchConfig.batch_mappings[0] as any;
        finalMappings = mappingList
          .filter((m) => m.dbColumn) // DB 컬럼이 선택된 것만
          .map((m, index) => ({
            // FROM: REST API (기존 설정 복사)
            from_connection_type: "restapi" as any,
            from_connection_id: first.from_connection_id,
            from_table_name: first.from_table_name,
            from_column_name: m.sourceType === "fixed" ? m.fixedValue : m.apiField,
            from_column_type: m.sourceType === "fixed" ? "text" : "text",
            from_api_url: mappings[0]?.from_api_url || first.from_api_url,
            from_api_key: authTokenMode === "direct" ? fromApiKey : first.from_api_key,
            from_api_method: mappings[0]?.from_api_method || first.from_api_method,
            from_api_body: mappings[0]?.from_api_body || first.from_api_body,
            // TO: DB (기존 설정 복사)
            to_connection_type: first.to_connection_type as any,
            to_connection_id: first.to_connection_id,
            to_table_name: toTable || first.to_table_name,
            to_column_name: m.dbColumn,
            to_column_type: toColumns.find((c) => c.column_name === m.dbColumn)?.data_type || "text",
            mapping_type: m.sourceType === "fixed" ? "fixed" : "direct",
            mapping_order: index + 1,
          })) as BatchMapping[];
      }
      
      await BatchAPI.updateBatchConfig(batchId, {
        batchName,
        description,
        cronSchedule,
        isActive,
        mappings: finalMappings,
        saveMode,
        conflictKey: saveMode === "UPSERT" ? conflictKey : undefined,
        authServiceName: authTokenMode === "db" ? authServiceName : undefined,
        dataArrayPath: dataArrayPath || undefined
      });
      
      toast.success("배치 설정이 성공적으로 수정되었습니다.");
      router.push("/admin/batchmng");
      
    } catch (error) {
      console.error("배치 설정 수정 실패:", error);
      toast.error("배치 설정 수정에 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  if (loading && !batchConfig) {
    return (
      <div className="container mx-auto p-6">
        <div className="flex items-center justify-center h-64">
          <RefreshCw className="w-8 h-8 animate-spin" />
          <span className="ml-2">배치 설정을 불러오는 중...</span>
        </div>
      </div>
    );
  }

  return (
    <div className="container mx-auto space-y-6 p-6">
      {/* 페이지 헤더 */}
      <div className="flex items-center gap-4 border-b pb-4">
        <Button
          variant="outline"
          onClick={() => router.push("/admin/batchmng")}
          className="gap-2"
        >
          <ArrowLeft className="h-4 w-4" />
          목록으로
        </Button>
        <h1 className="text-3xl font-bold">배치 설정 수정</h1>
      </div>

      {/* 기본 정보 */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            기본 정보
            {batchType && (
              <Badge variant="outline">
                {batchType === "db-to-db" && "DB -> DB"}
                {batchType === "restapi-to-db" && "REST API -> DB"}
                {batchType === "db-to-restapi" && "DB -> REST API"}
              </Badge>
            )}
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div>
              <Label htmlFor="batchName">배치명 *</Label>
              <Input
                id="batchName"
                value={batchName}
                onChange={(e) => setBatchName(e.target.value)}
                placeholder="배치명을 입력하세요"
              />
            </div>
            <div>
              <Label htmlFor="cronSchedule">실행 스케줄 (Cron) *</Label>
              <Input
                id="cronSchedule"
                value={cronSchedule}
                onChange={(e) => setCronSchedule(e.target.value)}
                placeholder="0 12 * * *"
              />
            </div>
          </div>

          <div>
            <Label htmlFor="description">설명</Label>
            <Textarea
              id="description"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="배치에 대한 설명을 입력하세요"
              rows={3}
            />
          </div>

          <div className="flex items-center space-x-2">
            <Checkbox
              id="isActive"
              checked={isActive === "Y"}
              onCheckedChange={(checked) => setIsActive(checked ? "Y" : "N")}
            />
            <Label htmlFor="isActive">활성화</Label>
          </div>
        </CardContent>
      </Card>

      {/* FROM/TO 섹션 가로 배치 */}
      <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
        {/* FROM 설정 */}
        <Card>
          <CardHeader>
            <CardTitle>FROM (소스)</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {batchType === "db-to-db" && (
              <>
                <div>
                  <Label>연결</Label>
                  <Select
                    value={
                      fromConnection?.type === "internal"
                        ? "internal"
                        : fromConnection?.id?.toString() || ""
                    }
                    onValueChange={handleFromConnectionChange}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="소스 연결을 선택하세요" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="internal">내부 DB</SelectItem>
                      {connections
                        .filter((conn) => conn.id)
                        .map((conn) => (
                          <SelectItem key={conn.id} value={conn.id!.toString()}>
                            {conn.name}
                          </SelectItem>
                        ))}
                    </SelectContent>
                  </Select>
                </div>

                <div>
                  <Label>테이블</Label>
                  <Select value={fromTable} onValueChange={handleFromTableChange}>
                    <SelectTrigger>
                      <SelectValue placeholder="소스 테이블을 선택하세요" />
                    </SelectTrigger>
                    <SelectContent>
                      {fromTables.map((table) => (
                        <SelectItem key={table} value={table}>
                          {table}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </>
            )}

            {batchType === "restapi-to-db" && mappings.length > 0 && (
              <>
                {/* API 서버 URL */}
                <div>
                  <Label>API 서버 URL *</Label>
                  <Input
                    value={mappings[0]?.from_api_url || ""}
                    onChange={(e) => {
                      const value = e.target.value;
                      setMappings((prev) => {
                        if (prev.length === 0) return prev;
                        const updated = [...prev];
                        updated[0] = { ...updated[0], from_api_url: value } as any;
                        return updated;
                      });
                    }}
                    placeholder="https://api.example.com"
                  />
                </div>

                {/* 인증 토큰 (Authorization) */}
                <div>
                  <Label>인증 토큰 (Authorization)</Label>
                  <div className="mt-2 flex items-center gap-4">
                    <label className="flex cursor-pointer items-center gap-1.5">
                      <input
                        type="radio"
                        name="authTokenMode"
                        value="direct"
                        checked={authTokenMode === "direct"}
                        onChange={() => setAuthTokenMode("direct")}
                        className="h-3.5 w-3.5"
                      />
                      <span className="text-xs">직접 입력</span>
                    </label>
                    <label className="flex cursor-pointer items-center gap-1.5">
                      <input
                        type="radio"
                        name="authTokenMode"
                        value="db"
                        checked={authTokenMode === "db"}
                        onChange={() => setAuthTokenMode("db")}
                        className="h-3.5 w-3.5"
                      />
                      <span className="text-xs">DB에서 선택</span>
                    </label>
                  </div>
                  {/* 직접 입력 모드 */}
                  {authTokenMode === "direct" && (
                    <Input
                      value={fromApiKey}
                      onChange={(e) => setFromApiKey(e.target.value)}
                      placeholder="Bearer eyJhbGciOiJIUzI1NiIs..."
                      className="mt-2"
                    />
                  )}
                  {/* DB 선택 모드 */}
                  {authTokenMode === "db" && (
                    <Select
                      value={authServiceName || "none"}
                      onValueChange={(value) => setAuthServiceName(value === "none" ? "" : value)}
                    >
                      <SelectTrigger className="mt-2">
                        <SelectValue placeholder="서비스명 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="none">선택 안 함</SelectItem>
                        {authServiceNames.map((name) => (
                          <SelectItem key={name} value={name}>
                            {name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  )}
                  <p className="mt-1 text-xs text-gray-500">
                    {authTokenMode === "direct"
                      ? "API 호출 시 Authorization 헤더에 사용할 토큰을 입력하세요."
                      : "auth_tokens 테이블에서 선택한 서비스의 최신 토큰을 사용합니다."}
                  </p>
                </div>

                {/* 엔드포인트 */}
                <div>
                  <Label>엔드포인트 *</Label>
                  <Input
                    value={mappings[0]?.from_table_name || ""}
                    onChange={(e) => {
                      const value = e.target.value;
                      setMappings((prev) => {
                        if (prev.length === 0) return prev;
                        const updated = [...prev];
                        updated[0] = { ...updated[0], from_table_name: value } as any;
                        return updated;
                      });
                    }}
                    placeholder="/api/users"
                  />
                </div>

                {/* HTTP 메서드 */}
                <div>
                  <Label>HTTP 메서드</Label>
                  <Select
                    value={mappings[0]?.from_api_method || "GET"}
                    onValueChange={(value) => {
                      setMappings((prev) => {
                        if (prev.length === 0) return prev;
                        const updated = [...prev];
                        updated[0] = { ...updated[0], from_api_method: value } as any;
                        return updated;
                      });
                    }}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="HTTP 메서드 선택" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="GET">GET (데이터 조회)</SelectItem>
                      <SelectItem value="POST">POST (데이터 조회/전송)</SelectItem>
                      <SelectItem value="PUT">PUT</SelectItem>
                      <SelectItem value="DELETE">DELETE</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                {/* 데이터 배열 경로 */}
                <div>
                  <Label>데이터 배열 경로</Label>
                  <Input
                    value={dataArrayPath}
                    onChange={(e) => setDataArrayPath(e.target.value)}
                    placeholder="response (예: data.items, results)"
                  />
                  <p className="mt-1 text-xs text-gray-500">
                    API 응답에서 배열 데이터가 있는 경로를 입력하세요. 비워두면 응답 전체를 사용합니다.
                    <br />
                    예시: response, data.items, result.list
                  </p>
                </div>

                {/* Request Body (POST/PUT/DELETE용) */}
                {(mappings[0]?.from_api_method === "POST" || 
                  mappings[0]?.from_api_method === "PUT" || 
                  mappings[0]?.from_api_method === "DELETE") && (
                  <div>
                    <Label>Request Body (JSON)</Label>
                    <Textarea
                      value={mappings[0]?.from_api_body || ""}
                      onChange={(e) => {
                        const value = e.target.value;
                        setMappings((prev) => {
                          if (prev.length === 0) return prev;
                          const updated = [...prev];
                          updated[0] = { ...updated[0], from_api_body: value } as any;
                          return updated;
                        });
                      }}
                      placeholder='{"username": "myuser", "token": "abc"}'
                      className="min-h-[100px]"
                      rows={5}
                    />
                    <p className="mt-1 text-xs text-gray-500">API 호출 시 함께 전송할 JSON 데이터를 입력하세요.</p>
                  </div>
                )}

                {/* API 파라미터 설정 */}
                <div className="space-y-4">
                  <div className="border-t pt-4">
                    <Label className="text-base font-medium">API 파라미터 설정</Label>
                    <p className="mt-1 text-sm text-gray-600">특정 사용자나 조건으로 데이터를 조회할 때 사용합니다.</p>
                  </div>

                  <div>
                    <Label>파라미터 타입</Label>
                    <Select value={apiParamType} onValueChange={(value: any) => setApiParamType(value)}>
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="none">파라미터 없음</SelectItem>
                        <SelectItem value="url">URL 파라미터 (/api/users/{"{userId}"})</SelectItem>
                        <SelectItem value="query">쿼리 파라미터 (/api/users?userId=123)</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>

                  {apiParamType !== "none" && (
                    <>
                      {/* 파라미터명 */}
                      <div>
                        <Label>파라미터명 *</Label>
                        <Input
                          value={apiParamName}
                          onChange={(e) => setApiParamName(e.target.value)}
                          placeholder="userId, id, email 등"
                        />
                      </div>

                      {/* 파라미터 소스 */}
                      <div>
                        <Label>파라미터 소스</Label>
                        <Select value={apiParamSource} onValueChange={(value: any) => setApiParamSource(value)}>
                          <SelectTrigger>
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="static">고정값</SelectItem>
                            <SelectItem value="dynamic">동적값 (실행 시 결정)</SelectItem>
                          </SelectContent>
                        </Select>
                      </div>

                      <div>
                        <Label>
                          {apiParamSource === "static" ? "파라미터 값" : "파라미터 템플릿"} *
                        </Label>
                        <Input
                          value={apiParamValue}
                          onChange={(e) => setApiParamValue(e.target.value)}
                          placeholder={
                            apiParamSource === "static"
                              ? "123, john@example.com 등"
                              : "{{user_id}}, {{email}} 등 (실행 시 치환됨)"
                          }
                        />
                        {apiParamSource === "dynamic" && (
                          <p className="mt-1 text-xs text-gray-500">
                            동적값은 배치 실행 시 설정된 값으로 치환됩니다. 예: {"{{user_id}}"} → 실제 사용자 ID
                          </p>
                        )}
                      </div>

                      {apiParamType === "url" && (
                        <div className="rounded-lg bg-blue-50 p-3">
                          <div className="text-sm font-medium text-blue-800">URL 파라미터 예시</div>
                          <div className="mt-1 text-sm text-blue-700">
                            엔드포인트: /api/users/{`{${apiParamName || "userId"}}`}
                          </div>
                          <div className="text-sm text-blue-700">실제 호출: /api/users/{apiParamValue || "123"}</div>
                        </div>
                      )}

                      {apiParamType === "query" && (
                        <div className="rounded-lg bg-green-50 p-3">
                          <div className="text-sm font-medium text-green-800">쿼리 파라미터 예시</div>
                          <div className="mt-1 text-sm text-green-700">
                            실제 호출: {mappings[0]?.from_table_name || "/api/users"}?{apiParamName || "userId"}=
                            {apiParamValue || "123"}
                          </div>
                        </div>
                      )}
                    </>
                  )}
                </div>
              </>
            )}

            {batchType === "db-to-restapi" && mappings.length > 0 && (
              <>
                <div>
                  <Label>소스 테이블</Label>
                  <Input value={mappings[0]?.from_table_name || ""} readOnly />
                </div>
              </>
            )}
          </CardContent>
        </Card>

        {/* TO 설정 */}
        <Card>
          <CardHeader>
            <CardTitle>TO (대상)</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {batchType === "db-to-db" && (
              <>
                <div>
                  <Label>연결</Label>
                  <Select
                    value={
                      toConnection?.type === "internal"
                        ? "internal"
                        : toConnection?.id?.toString() || ""
                    }
                    onValueChange={handleToConnectionChange}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="대상 연결을 선택하세요" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="internal">내부 DB</SelectItem>
                      {connections
                        .filter((conn) => conn.id)
                        .map((conn) => (
                          <SelectItem key={conn.id} value={conn.id!.toString()}>
                            {conn.name}
                          </SelectItem>
                        ))}
                    </SelectContent>
                  </Select>
                </div>

                <div>
                  <Label>테이블</Label>
                  <Select
                    value={toTable}
                    onValueChange={handleToTableChange}
                    disabled={!toConnection}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="대상 테이블을 선택하세요" />
                    </SelectTrigger>
                    <SelectContent>
                      {toTables.map((table) => (
                        <SelectItem key={table} value={table}>
                          {table}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </>
            )}

            {batchType === "restapi-to-db" && (
              <>
                <div>
                  <Label>데이터베이스 연결 *</Label>
                  <Select
                    value={
                      toConnection?.type === "internal"
                        ? "internal"
                        : toConnection?.id?.toString() || ""
                    }
                    onValueChange={handleToConnectionChange}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="대상 연결을 선택하세요" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="internal">내부 DB</SelectItem>
                      {connections
                        .filter((conn) => conn.id)
                        .map((conn) => (
                          <SelectItem key={conn.id} value={conn.id!.toString()}>
                            {conn.name}
                          </SelectItem>
                        ))}
                    </SelectContent>
                  </Select>
                </div>

                <div>
                  <Label>대상 테이블 *</Label>
                  <Select
                    value={toTable}
                    onValueChange={handleToTableChange}
                    disabled={!toConnection}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={toConnection ? "테이블을 선택하세요" : "먼저 연결을 선택하세요"} />
                    </SelectTrigger>
                    <SelectContent>
                      {toTables.map((table) => (
                        <SelectItem key={table} value={table}>
                          {table}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </>
            )}

            {batchType === "db-to-restapi" && mappings.length > 0 && (
              <>
                <div>
                  <Label>API URL</Label>
                  <Input value={mappings[0]?.to_api_url || ""} readOnly />
                </div>
                <div>
                  <Label>API 엔드포인트</Label>
                  <Input value={mappings[0]?.to_table_name || ""} readOnly />
                </div>
                <div>
                  <Label>HTTP 메서드</Label>
                  <Input value={mappings[0]?.to_api_method || "POST"} readOnly />
                </div>
              </>
            )}

            {/* 저장 모드 설정 - 항상 표시 (단계적 활성화) */}
            <div className="border-t pt-4">
              <Label>저장 모드</Label>
              <Select
                value={saveMode}
                onValueChange={(value: "INSERT" | "UPSERT") => {
                  setSaveMode(value);
                  // INSERT로 변경 시 충돌 기준 컬럼 초기화
                  if (value === "INSERT") {
                    setConflictKey("");
                  }
                }}
                disabled={!toTable}
              >
                <SelectTrigger>
                  <SelectValue placeholder="저장 모드 선택" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="INSERT">INSERT (항상 새로 추가)</SelectItem>
                  <SelectItem value="UPSERT">
                    UPSERT (있으면 업데이트, 없으면 추가)
                  </SelectItem>
                </SelectContent>
              </Select>
              <p className="text-muted-foreground mt-1.5 text-xs">
                UPSERT: 동일한 키가 있으면 업데이트, 없으면 새로 추가합니다.
              </p>
            </div>

            {/* 충돌 기준 컬럼 - UPSERT일 때만 활성화 */}
            <div>
              <Label>충돌 기준 컬럼</Label>
              <Select
                value={conflictKey || "none"}
                onValueChange={(value) => setConflictKey(value === "none" ? "" : value)}
                disabled={saveMode !== "UPSERT" || toColumns.length === 0}
              >
                <SelectTrigger>
                  <SelectValue placeholder={saveMode !== "UPSERT" ? "UPSERT 모드를 선택하세요" : "컬럼을 선택하세요"} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">선택 안함</SelectItem>
                  {toColumns.map((col) => (
                    <SelectItem key={col.column_name} value={col.column_name}>
                      <div className="flex items-center gap-2">
                        <span>{col.column_name}</span>
                        <span className="text-muted-foreground text-xs">({col.data_type})</span>
                      </div>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <p className="text-muted-foreground mt-1.5 text-xs">
                UPSERT 시 중복 여부를 판단할 컬럼을 선택하세요.
              </p>
            </div>
          </CardContent>
        </Card>
      </div>

      {/* API 데이터 미리보기 버튼 */}
      {batchType === "restapi-to-db" && (
        <div className="flex justify-center">
          <Button
            variant="outline"
            onClick={previewRestApiData}
            disabled={mappings.length === 0}
          >
            <RefreshCw className="mr-2 h-4 w-4" />
            API 데이터 미리보기
          </Button>
        </div>
      )}

      {/* 컬럼 매핑 섹션 - 좌우 분리 */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center justify-between">
            {batchType === "db-to-db" && "컬럼 매핑"}
            {batchType === "restapi-to-db" && "컬럼 매핑 설정"}
            {batchType === "db-to-restapi" && "DB 컬럼 -> API 필드 매핑"}
          </CardTitle>
          {batchType === "restapi-to-db" && (
            <p className="text-muted-foreground text-sm">DB 컬럼에 API 필드 또는 고정값을 매핑합니다.</p>
          )}
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
            {/* 왼쪽: 샘플 데이터 */}
            <div className="flex flex-col">
              <div className="mb-3 flex h-8 items-center">
                <h4 className="text-sm font-semibold">샘플 데이터 (최대 3개)</h4>
              </div>
              {apiPreviewData.length > 0 ? (
                <div className="bg-muted/30 h-[360px] overflow-y-auto rounded-lg border p-3">
                  <div className="space-y-2">
                    {apiPreviewData.slice(0, 3).map((item, index) => (
                      <div key={index} className="bg-background rounded border p-2">
                        <pre className="whitespace-pre-wrap font-mono text-xs">
                          {JSON.stringify(item, null, 2)}
                        </pre>
                      </div>
                    ))}
                  </div>
                </div>
              ) : (
                <div className="flex h-[360px] items-center justify-center rounded-lg border border-dashed">
                  <p className="text-muted-foreground text-sm">
                    API 데이터 미리보기를 실행하면 샘플 데이터가 표시됩니다.
                  </p>
                </div>
              )}
            </div>

            {/* 오른쪽: 매핑 설정 */}
            <div className="flex flex-col">
              <div className="mb-3 flex h-8 items-center justify-between">
                <h4 className="text-sm font-semibold">매핑 설정</h4>
                {(batchType === "db-to-db" || batchType === "restapi-to-db") && (
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={batchType === "db-to-db" ? addMapping : addMappingListItem}
                    className="h-8 gap-1"
                  >
                    <Plus className="h-4 w-4" />
                    매핑 추가
                  </Button>
                )}
              </div>

              {/* restapi-to-db 새로운 매핑 UI */}
              {batchType === "restapi-to-db" && (
                <>
                  {mappingList.length === 0 ? (
                    <div className="flex h-[360px] flex-col items-center justify-center rounded-lg border border-dashed text-center">
                      <p className="text-muted-foreground text-sm">매핑이 없습니다.</p>
                      <Button variant="link" onClick={addMappingListItem} className="mt-2">
                        매핑 추가하기
                      </Button>
                    </div>
                  ) : (
                    <div className="bg-muted/30 h-[360px] space-y-3 overflow-y-auto rounded-lg border p-3">
                      {mappingList.map((mapping, index) => (
                        <div key={mapping.id} className="bg-background flex items-center gap-2 rounded-lg border p-3">
                          {/* 순서 표시 */}
                          <div className="bg-primary/10 text-primary flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-medium">
                            {index + 1}
                          </div>

                          {/* DB 컬럼 선택 (좌측 - TO) */}
                          <div className="w-36 shrink-0">
                            <Select
                              value={mapping.dbColumn || "none"}
                              onValueChange={(value) =>
                                updateMappingListItem(mapping.id, { dbColumn: value === "none" ? "" : value })
                              }
                            >
                              <SelectTrigger className="h-9">
                                <SelectValue placeholder="선택 안함" />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="none">선택 안함</SelectItem>
                                {toColumns.map((col) => {
                                  const isUsed =
                                    mappingList.some((m) => m.dbColumn === col.column_name) &&
                                    mapping.dbColumn !== col.column_name;
                                  return (
                                    <SelectItem key={col.column_name} value={col.column_name} disabled={isUsed}>
                                      <div className="flex items-center gap-2">
                                        <span className={isUsed ? "text-muted-foreground" : ""}>{col.column_name}</span>
                                        <span className="text-muted-foreground text-xs">({col.data_type})</span>
                                      </div>
                                    </SelectItem>
                                  );
                                })}
                              </SelectContent>
                            </Select>
                          </div>

                          {/* 화살표 */}
                          <ArrowLeft className="text-muted-foreground h-4 w-4 shrink-0" />

                          {/* 소스 타입 선택 */}
                          <div className="w-24 shrink-0">
                            <Select
                              value={mapping.sourceType}
                              onValueChange={(value: "api" | "fixed") =>
                                updateMappingListItem(mapping.id, {
                                  sourceType: value,
                                  apiField: value === "fixed" ? "" : mapping.apiField,
                                  fixedValue: value === "api" ? "" : mapping.fixedValue,
                                })
                              }
                            >
                              <SelectTrigger className="h-9">
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="api">API 필드</SelectItem>
                                <SelectItem value="fixed">고정값</SelectItem>
                              </SelectContent>
                            </Select>
                          </div>

                          {/* API 필드 선택 또는 고정값 입력 (우측 - FROM) */}
                          <div className="min-w-0 flex-1">
                            {mapping.sourceType === "api" ? (
                              <Select
                                value={mapping.apiField || "none"}
                                onValueChange={(value) =>
                                  updateMappingListItem(mapping.id, { apiField: value === "none" ? "" : value })
                                }
                              >
                                <SelectTrigger className="h-9">
                                  <SelectValue placeholder="선택 안함" />
                                </SelectTrigger>
                                <SelectContent>
                                  <SelectItem value="none">선택 안함</SelectItem>
                                  {fromApiFields.map((field) => (
                                    <SelectItem key={field} value={field}>
                                      <div className="flex items-center gap-2">
                                        <span>{field}</span>
                                        {apiPreviewData[0] && apiPreviewData[0][field] !== undefined && (
                                          <span className="text-muted-foreground text-xs">
                                            (예: {String(apiPreviewData[0][field]).substring(0, 15)}
                                            {String(apiPreviewData[0][field]).length > 15 ? "..." : ""})
                                          </span>
                                        )}
                                      </div>
                                    </SelectItem>
                                  ))}
                                </SelectContent>
                              </Select>
                            ) : (
                              <Input
                                value={mapping.fixedValue}
                                onChange={(e) => updateMappingListItem(mapping.id, { fixedValue: e.target.value })}
                                placeholder="고정값 입력"
                                className="h-9"
                              />
                            )}
                          </div>

                          {/* 삭제 버튼 */}
                          <Button
                            variant="ghost"
                            size="icon"
                            onClick={() => removeMappingListItem(mapping.id)}
                            className="text-muted-foreground hover:text-destructive h-8 w-8 shrink-0"
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                </>
              )}

              {/* db-to-db 기존 매핑 UI */}
              {batchType === "db-to-db" && (
                <>
                  {mappings.length === 0 ? (
                    <div className="flex h-[360px] flex-col items-center justify-center rounded-lg border border-dashed text-center">
                      <p className="text-muted-foreground text-sm">매핑이 없습니다.</p>
                      <Button variant="link" onClick={addMapping} className="mt-2">
                        매핑 추가하기
                      </Button>
                    </div>
                  ) : (
                    <div className="bg-muted/30 h-[360px] space-y-3 overflow-y-auto rounded-lg border p-3">
                      {mappings.map((mapping, index) => (
                        <div
                          key={index}
                          className="bg-background flex items-center gap-2 rounded-lg border p-3"
                        >
                          <div className="flex-1">
                            <Select
                              value={mapping.from_column_name || ""}
                              onValueChange={(value) => {
                                updateMapping(index, "from_column_name", value);
                                const selectedColumn = fromColumns.find(
                                  (col) => col.column_name === value
                                );
                                if (selectedColumn) {
                                  updateMapping(
                                    index,
                                    "from_column_type",
                                    selectedColumn.data_type
                                  );
                                }
                              }}
                            >
                              <SelectTrigger className="h-9 text-xs">
                                <SelectValue placeholder="FROM 컬럼" />
                              </SelectTrigger>
                              <SelectContent>
                                {fromColumns.map((column) => (
                                  <SelectItem
                                    key={column.column_name}
                                    value={column.column_name}
                                  >
                                    {column.column_name}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                          </div>
                          <span className="text-muted-foreground text-xs">-&gt;</span>
                          <div className="flex-1">
                            <Select
                              value={mapping.to_column_name || ""}
                              onValueChange={(value) => {
                                updateMapping(index, "to_column_name", value);
                                const selectedColumn = toColumns.find(
                                  (col) => col.column_name === value
                                );
                                if (selectedColumn) {
                                  updateMapping(
                                    index,
                                    "to_column_type",
                                    selectedColumn.data_type
                                  );
                                }
                              }}
                            >
                              <SelectTrigger className="h-9 text-xs">
                                <SelectValue placeholder="TO 컬럼" />
                              </SelectTrigger>
                              <SelectContent>
                                {toColumns.map((column) => (
                                  <SelectItem
                                    key={column.column_name}
                                    value={column.column_name}
                                  >
                                    {column.column_name}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                          </div>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-8 w-8"
                            onClick={() => removeMapping(index)}
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                </>
              )}

              {/* db-to-restapi 기존 매핑 UI */}
              {batchType === "db-to-restapi" && (
                <>
                  {mappings.length === 0 ? (
                    <div className="flex h-[360px] flex-col items-center justify-center rounded-lg border border-dashed text-center">
                      <p className="text-muted-foreground text-sm">매핑이 없습니다.</p>
                    </div>
                  ) : (
                    <div className="bg-muted/30 h-[360px] space-y-3 overflow-y-auto rounded-lg border p-3">
                      {mappings.map((mapping, index) => (
                        <div
                          key={index}
                          className="bg-background flex items-center gap-2 rounded-lg border p-3"
                        >
                          <div className="flex-1">
                            <Input
                              value={mapping.from_column_name || ""}
                              readOnly
                              className="h-9 text-xs"
                            />
                          </div>
                          <span className="text-muted-foreground text-xs">-&gt;</span>
                          <div className="flex-1">
                            <Input
                              value={mapping.to_column_name || ""}
                              readOnly
                              className="h-9 text-xs"
                            />
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </>
              )}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* 하단 버튼 */}
      <div className="flex justify-end space-x-2 border-t pt-6">
        <Button variant="outline" onClick={() => router.push("/admin/batchmng")}>
          취소
        </Button>
        <Button
          onClick={saveBatchConfig}
          disabled={loading || (batchType === "restapi-to-db" ? mappingList.length === 0 : mappings.length === 0)}
        >
          {loading ? (
            <RefreshCw className="mr-2 h-4 w-4 animate-spin" />
          ) : (
            <Save className="mr-2 h-4 w-4" />
          )}
          {loading ? "저장 중..." : "배치 설정 저장"}
        </Button>
      </div>
    </div>
  );
}
