"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { 
  Database, 
  Link2, 
  GitBranch, 
  Columns3, 
  Save,
  Plus, 
  Pencil, 
  Trash2,
  RefreshCw,
  Loader2,
  Check,
  ChevronsUpDown,
} from "lucide-react";
import {
  getTableRelations,
  createTableRelation,
  updateTableRelation,
  deleteTableRelation,
  getFieldJoins,
  createFieldJoin,
  updateFieldJoin,
  deleteFieldJoin,
  getDataFlows,
  createDataFlow,
  updateDataFlow,
  deleteDataFlow,
  FieldJoin,
  DataFlow,
  TableRelation,
} from "@/lib/api/screenGroup";
import { tableManagementApi, ColumnTypeInfo, TableInfo } from "@/lib/api/tableManagement";

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

// 기존 설정 정보 (화면 디자이너에서 추출)
interface ExistingConfig {
  joinColumnRefs?: Array<{
    column: string;
    refTable: string;
    refTableLabel?: string;
    refColumn: string;
  }>;
  filterColumns?: string[];
  fieldMappings?: Array<{
    targetField: string;
    sourceField: string;
    sourceTable?: string;
    sourceDisplayName?: string;
  }>;
  referencedBy?: Array<{
    fromTable: string;
    fromTableLabel?: string;
    fromColumn: string;
    toColumn: string;
    toColumnLabel?: string;
    relationType: string;
  }>;
  columns?: Array<{
    name: string;
    originalName?: string;
    type: string;
    isPrimaryKey?: boolean;
    isForeignKey?: boolean;
  }>;
  // 화면 노드용 테이블 정보
  mainTable?: string;
  filterTables?: Array<{
    tableName: string;
    tableLabel: string;
    filterColumns: string[];
    joinColumnRefs: Array<{
      column: string;
      refTable: string;
      refTableLabel?: string;
      refColumn: string;
    }>;
  }>;
}

interface NodeSettingModalProps {
  isOpen: boolean;
  onClose: () => void;
  // 노드 정보
  nodeType: "screen" | "table";
  nodeId: string;  // 노드 ID (예: screen-1, table-sales_order_mng)
  screenId: number;
  screenName: string;
  tableName?: string;  // 테이블 노드인 경우
  tableLabel?: string;
  // 그룹 정보 (데이터 흐름 설정에 필요)
  groupId?: number;
  groupScreens?: Array<{ screen_id: number; screen_name: string }>;
  // 기존 설정 정보 (화면 디자이너에서 추출한 조인/필터 정보)
  existingConfig?: ExistingConfig;
  // 새로고침 콜백
  onRefresh?: () => void;
}

// 탭 ID
type TabId = "table-relation" | "join-setting" | "data-flow" | "field-mapping";

// ============================================================
// 검색 가능한 셀렉트 컴포넌트
// ============================================================

interface SearchableSelectProps {
  value: string;
  onValueChange: (value: string) => void;
  options: Array<{ value: string; label: string; description?: string }>;
  placeholder?: string;
  searchPlaceholder?: string;
  emptyText?: string;
  disabled?: boolean;
  className?: string;
}

function SearchableSelect({
  value,
  onValueChange,
  options,
  placeholder = "선택",
  searchPlaceholder = "검색...",
  emptyText = "항목을 찾을 수 없습니다.",
  disabled = false,
  className,
}: SearchableSelectProps) {
  const [open, setOpen] = useState(false);

  const selectedOption = options.find((opt) => opt.value === value);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled}
          className={cn(
            "h-9 w-full justify-between text-xs font-normal",
            !value && "text-muted-foreground",
            className
          )}
        >
          <span className="truncate">
            {selectedOption?.label || placeholder}
          </span>
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="p-0"
        style={{ width: "var(--radix-popover-trigger-width)" }}
        align="start"
      >
        <Command>
          <CommandInput placeholder={searchPlaceholder} className="text-xs" />
          <CommandList>
            <CommandEmpty className="text-xs py-4 text-center">
              {emptyText}
            </CommandEmpty>
            <CommandGroup>
              {options.map((option) => (
                <CommandItem
                  key={option.value}
                  value={option.label}
                  onSelect={() => {
                    onValueChange(option.value);
                    setOpen(false);
                  }}
                  className="text-xs"
                >
                  <Check
                    className={cn(
                      "mr-2 h-4 w-4",
                      value === option.value ? "opacity-100" : "opacity-0"
                    )}
                  />
                  <div className="flex flex-col">
                    <span>{option.label}</span>
                    {option.description && (
                      <span className="text-[10px] text-muted-foreground">
                        {option.description}
                      </span>
                    )}
                  </div>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

// ============================================================
// 컴포넌트
// ============================================================

export default function NodeSettingModal({
  isOpen,
  onClose,
  nodeType,
  nodeId,
  screenId,
  screenName,
  tableName,
  tableLabel,
  groupId,
  groupScreens = [],
  existingConfig,
  onRefresh,
}: NodeSettingModalProps) {
  // 탭 상태
  const [activeTab, setActiveTab] = useState<TabId>("table-relation");
  
  // 로딩 상태
  const [loading, setLoading] = useState(false);
  
  // 테이블 목록 (조인/필터 설정용)
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [tableColumns, setTableColumns] = useState<Record<string, ColumnTypeInfo[]>>({});
  
  // 테이블 연결 데이터
  const [tableRelations, setTableRelations] = useState<TableRelation[]>([]);
  
  // 조인 설정 데이터
  const [fieldJoins, setFieldJoins] = useState<FieldJoin[]>([]);
  
  // 데이터 흐름 데이터
  const [dataFlows, setDataFlows] = useState<DataFlow[]>([]);

  // ============================================================
  // 데이터 로드
  // ============================================================

  // 테이블 목록 로드
  const loadTables = useCallback(async () => {
    try {
      const response = await tableManagementApi.getTableList();
      if (response.success && response.data) {
        setTables(response.data);
      }
    } catch (error) {
      console.error("테이블 목록 로드 실패:", error);
    }
  }, []);

  // 테이블 컬럼 로드
  const loadTableColumns = useCallback(async (tblName: string) => {
    if (tableColumns[tblName]) return; // 이미 로드됨
    
    try {
      const response = await tableManagementApi.getColumnList(tblName);
      if (response.success && response.data) {
        setTableColumns(prev => ({
          ...prev,
          [tblName]: response.data?.columns || [],
        }));
      }
    } catch (error) {
      console.error(`테이블 컬럼 로드 실패 (${tblName}):`, error);
    }
  }, [tableColumns]);

  // 테이블 연결 로드
  const loadTableRelations = useCallback(async () => {
    if (!screenId) return;
    
    setLoading(true);
    try {
      const response = await getTableRelations({ screen_id: screenId });
      if (response.success && response.data) {
        setTableRelations(response.data);
      }
    } catch (error) {
      console.error("테이블 연결 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  }, [screenId]);

  // 조인 설정 로드
  const loadFieldJoins = useCallback(async () => {
    if (!screenId) return;
    
    setLoading(true);
    try {
      const response = await getFieldJoins(screenId);
      if (response.success && response.data) {
        setFieldJoins(response.data);
      }
    } catch (error) {
      console.error("조인 설정 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  }, [screenId]);

  // 데이터 흐름 로드
  const loadDataFlows = useCallback(async () => {
    if (!groupId) return;
    
    setLoading(true);
    try {
      const response = await getDataFlows(groupId);
      if (response.success && response.data) {
        // 현재 화면 관련 흐름만 필터링
        const filtered = response.data.filter(
          flow => flow.source_screen_id === screenId || flow.target_screen_id === screenId
        );
        setDataFlows(filtered);
      }
    } catch (error) {
      console.error("데이터 흐름 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  }, [groupId, screenId]);

  // 모달 열릴 때 데이터 로드
  useEffect(() => {
    if (isOpen) {
      loadTables();
      loadTableRelations();
      loadFieldJoins();
      if (groupId) {
        loadDataFlows();
      }
      // 현재 테이블 컬럼 로드
      if (tableName) {
        loadTableColumns(tableName);
      }
    }
  }, [isOpen, loadTables, loadTableRelations, loadFieldJoins, loadDataFlows, tableName, groupId, loadTableColumns]);

  // ============================================================
  // 이벤트 핸들러
  // ============================================================

  // 모달 닫기
  const handleClose = () => {
    onClose();
  };

  // 새로고침
  const handleRefresh = async () => {
    setLoading(true);
    try {
      await Promise.all([
        loadTableRelations(),
        loadFieldJoins(),
        groupId ? loadDataFlows() : Promise.resolve(),
      ]);
      toast.success("데이터가 새로고침되었습니다.");
    } catch (error) {
      toast.error("새로고침 실패");
    } finally {
      setLoading(false);
    }
  };

  // ============================================================
  // 렌더링
  // ============================================================

  // 모달 제목
  const modalTitle = nodeType === "screen" 
    ? `화면 설정: ${screenName}` 
    : `테이블 설정: ${tableLabel || tableName}`;

  // 모달 설명
  const modalDescription = nodeType === "screen"
    ? "화면의 테이블 연결, 조인, 데이터 흐름을 설정합니다."
    : "테이블의 조인 관계 및 필드 매핑을 설정합니다.";

  return (
    <Dialog open={isOpen} onOpenChange={handleClose}>
      <DialogContent className="max-w-[95vw] sm:max-w-[900px] max-h-[90vh] overflow-hidden flex flex-col">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2 text-base sm:text-lg">
            {nodeType === "screen" ? (
              <Database className="h-5 w-5 text-blue-500" />
            ) : (
              <Database className="h-5 w-5 text-green-500" />
            )}
            {modalTitle}
          </DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            {modalDescription}
          </DialogDescription>
        </DialogHeader>

        <div className="flex-1 overflow-hidden">
          <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as TabId)} className="h-full flex flex-col">
            <div className="flex items-center justify-between border-b pb-2">
              <TabsList className="grid grid-cols-4 w-auto">
                <TabsTrigger value="table-relation" className="text-xs sm:text-sm gap-1">
                  <Database className="h-4 w-4" />
                  <span className="hidden sm:inline">테이블 연결</span>
                  <span className="sm:hidden">연결</span>
                </TabsTrigger>
                <TabsTrigger value="join-setting" className="text-xs sm:text-sm gap-1">
                  <Link2 className="h-4 w-4" />
                  <span className="hidden sm:inline">조인 설정</span>
                  <span className="sm:hidden">조인</span>
                </TabsTrigger>
                <TabsTrigger value="data-flow" className="text-xs sm:text-sm gap-1">
                  <GitBranch className="h-4 w-4" />
                  <span className="hidden sm:inline">데이터 흐름</span>
                  <span className="sm:hidden">흐름</span>
                </TabsTrigger>
                <TabsTrigger value="field-mapping" className="text-xs sm:text-sm gap-1">
                  <Columns3 className="h-4 w-4" />
                  <span className="hidden sm:inline">필드 매핑</span>
                  <span className="sm:hidden">매핑</span>
                </TabsTrigger>
              </TabsList>
              
              <Button
                variant="outline"
                size="sm"
                onClick={handleRefresh}
                disabled={loading}
                className="gap-1"
              >
                {loading ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <RefreshCw className="h-4 w-4" />
                )}
                <span className="hidden sm:inline">새로고침</span>
              </Button>
            </div>

            {/* 탭 컨텐츠 */}
            <div className="flex-1 overflow-auto pt-4">
              {/* 탭1: 테이블 연결 */}
              <TabsContent value="table-relation" className="mt-0 h-full">
                <TableRelationTab
                  screenId={screenId}
                  screenName={screenName}
                  tableRelations={tableRelations}
                  tables={tables}
                  loading={loading}
                  onReload={loadTableRelations}
                  onRefreshVisualization={onRefresh}
                  nodeType={nodeType}
                  existingConfig={existingConfig}
                />
              </TabsContent>

              {/* 탭2: 조인 설정 */}
              <TabsContent value="join-setting" className="mt-0 h-full">
                <JoinSettingTab
                  screenId={screenId}
                  tableName={tableName}
                  fieldJoins={fieldJoins}
                  tables={tables}
                  tableColumns={tableColumns}
                  loading={loading}
                  onReload={loadFieldJoins}
                  onLoadColumns={loadTableColumns}
                  onRefreshVisualization={onRefresh}
                  existingConfig={existingConfig}
                />
              </TabsContent>

              {/* 탭3: 데이터 흐름 */}
              <TabsContent value="data-flow" className="mt-0 h-full">
                <DataFlowTab
                  screenId={screenId}
                  groupId={groupId}
                  groupScreens={groupScreens}
                  dataFlows={dataFlows}
                  loading={loading}
                  onReload={loadDataFlows}
                  onRefreshVisualization={onRefresh}
                />
              </TabsContent>

              {/* 탭4: 필드 매핑 */}
              <TabsContent value="field-mapping" className="mt-0 h-full">
                <FieldMappingTab
                  screenId={screenId}
                  tableName={tableName}
                  tableColumns={tableColumns[tableName || ""] || []}
                  loading={loading}
                />
              </TabsContent>
            </div>
          </Tabs>
        </div>
      </DialogContent>
    </Dialog>
  );
}


// ============================================================
// 탭1: 테이블 연결 설정
// ============================================================

interface TableRelationTabProps {
  screenId: number;
  screenName: string;
  tableRelations: TableRelation[];
  tables: TableInfo[];
  loading: boolean;
  onReload: () => void;
  onRefreshVisualization?: () => void;
  nodeType: "screen" | "table";
  existingConfig?: ExistingConfig;
}

function TableRelationTab({
  screenId,
  screenName,
  tableRelations,
  tables,
  loading,
  onReload,
  onRefreshVisualization,
  nodeType,
  existingConfig,
}: TableRelationTabProps) {
  const [isEditing, setIsEditing] = useState(false);
  const [editItem, setEditItem] = useState<TableRelation | null>(null);
  const [formData, setFormData] = useState({
    table_name: "",
    relation_type: "main",
    crud_operations: "CR",
    description: "",
    is_active: "Y",
  });

  // 폼 초기화
  const resetForm = () => {
    setFormData({
      table_name: "",
      relation_type: "main",
      crud_operations: "CR",
      description: "",
      is_active: "Y",
    });
    setEditItem(null);
    setIsEditing(false);
  };

  // 수정 모드
  const handleEdit = (item: TableRelation) => {
    setEditItem(item);
    setFormData({
      table_name: item.table_name,
      relation_type: item.relation_type,
      crud_operations: item.crud_operations,
      description: item.description || "",
      is_active: item.is_active,
    });
    setIsEditing(true);
  };

  // 저장
  const handleSave = async () => {
    if (!formData.table_name) {
      toast.error("테이블을 선택해주세요.");
      return;
    }

    try {
      const payload = {
        screen_id: screenId,
        ...formData,
      };

      let response;
      if (editItem) {
        response = await updateTableRelation(editItem.id, payload);
      } else {
        response = await createTableRelation(payload);
      }

      if (response.success) {
        toast.success(editItem ? "테이블 연결이 수정되었습니다." : "테이블 연결이 추가되었습니다.");
        resetForm();
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "저장에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "저장 중 오류가 발생했습니다.");
    }
  };

  // 삭제
  const handleDelete = async (id: number) => {
    if (!confirm("정말 삭제하시겠습니까?")) return;

    try {
      const response = await deleteTableRelation(id);
      if (response.success) {
        toast.success("테이블 연결이 삭제되었습니다.");
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "삭제에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "삭제 중 오류가 발생했습니다.");
    }
  };

  // 화면 디자이너에서 추출한 테이블 관계를 통합 목록으로 변환
  const designerTableRelations = useMemo(() => {
    if (nodeType !== "screen" || !existingConfig) return [];
    
    const result: Array<{
      id: string;
      source: "designer";
      table_name: string;
      table_label?: string;
      relation_type: string;
      crud_operations: string;
      description: string;
      filterColumns?: string[];
      joinColumnRefs?: Array<{ column: string; refTable: string; refTableLabel?: string; refColumn: string; }>;
    }> = [];
    
    // 메인 테이블 추가
    if (existingConfig.mainTable) {
      result.push({
        id: `designer-main-${existingConfig.mainTable}`,
        source: "designer",
        table_name: existingConfig.mainTable,
        table_label: existingConfig.mainTable,
        relation_type: "main",
        crud_operations: "CRUD",
        description: "화면의 주요 데이터 소스 테이블",
      });
    }
    
    // 필터 테이블 추가
    if (existingConfig.filterTables) {
      existingConfig.filterTables.forEach((ft, idx) => {
        result.push({
          id: `designer-filter-${ft.tableName}-${idx}`,
          source: "designer",
          table_name: ft.tableName,
          table_label: ft.tableLabel,
          relation_type: "sub",
          crud_operations: "R",
          description: "마스터-디테일 필터 테이블",
          filterColumns: ft.filterColumns,
          joinColumnRefs: ft.joinColumnRefs,
        });
      });
    }
    
    return result;
  }, [nodeType, existingConfig]);
  
  // DB 테이블 관계와 디자이너 테이블 관계 통합
  const unifiedTableRelations = useMemo(() => {
    // DB 관계
    const dbRelations = tableRelations.map(item => ({
      ...item,
      id: item.id,
      source: "db" as const,
    }));
    
    // 디자이너 관계 (DB에 이미 있는 테이블은 제외)
    const dbTableNames = new Set(tableRelations.map(r => r.table_name));
    const filteredDesignerRelations = designerTableRelations.filter(
      dr => !dbTableNames.has(dr.table_name)
    );
    
    return [...filteredDesignerRelations, ...dbRelations];
  }, [tableRelations, designerTableRelations]);
  
  // 디자이너 항목 수정 (DB로 저장)
  const handleEditDesignerRelation = (item: typeof designerTableRelations[0]) => {
    setFormData({
      table_name: item.table_name,
      relation_type: item.relation_type,
      crud_operations: item.crud_operations,
      description: item.description || "",
      is_active: "Y",
    });
    setEditItem(null);
    setIsEditing(true);
  };

  return (
    <div className="space-y-4">
      {/* 입력 폼 */}
      <div className="bg-muted/50 rounded-lg p-4 space-y-3">
        <div className="text-sm font-medium">{isEditing ? "테이블 연결 수정" : "새 테이블 연결 추가"}</div>
        
        <div className="grid grid-cols-1 sm:grid-cols-4 gap-3">
          <div>
            <Label className="text-xs">테이블 *</Label>
            <SearchableSelect
              value={formData.table_name}
              onValueChange={(v) => setFormData(prev => ({ ...prev, table_name: v }))}
              options={tables.map((t) => ({
                value: t.tableName,
                label: t.displayName || t.tableName,
                description: t.tableName !== t.displayName ? t.tableName : undefined,
              }))}
              placeholder="테이블 선택"
              searchPlaceholder="테이블 검색..."
            />
          </div>

          <div>
            <Label className="text-xs">관계 유형</Label>
            <SearchableSelect
              value={formData.relation_type}
              onValueChange={(v) => setFormData(prev => ({ ...prev, relation_type: v }))}
              options={[
                { value: "main", label: "메인 테이블" },
                { value: "sub", label: "서브 테이블" },
                { value: "lookup", label: "조회 테이블" },
                { value: "save", label: "저장 테이블" },
              ]}
              placeholder="관계 유형"
              searchPlaceholder="유형 검색..."
            />
          </div>

          <div>
            <Label className="text-xs">CRUD 권한</Label>
            <SearchableSelect
              value={formData.crud_operations}
              onValueChange={(v) => setFormData(prev => ({ ...prev, crud_operations: v }))}
              options={[
                { value: "C", label: "생성(C)" },
                { value: "R", label: "읽기(R)" },
                { value: "CR", label: "생성+읽기(CR)" },
                { value: "CRU", label: "생성+읽기+수정(CRU)" },
                { value: "CRUD", label: "전체(CRUD)" },
              ]}
              placeholder="CRUD 권한"
              searchPlaceholder="권한 검색..."
            />
          </div>

          <div>
            <Label className="text-xs">설명</Label>
            <Input
              value={formData.description}
              onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
              placeholder="설명 입력"
              className="h-9 text-xs"
            />
          </div>
        </div>

        <div className="flex justify-end gap-2">
          {isEditing && (
            <Button variant="outline" size="sm" onClick={resetForm}>
              취소
            </Button>
          )}
          <Button size="sm" onClick={handleSave} className="gap-1">
            <Save className="h-4 w-4" />
            {isEditing ? "수정" : "추가"}
          </Button>
        </div>
      </div>

      {/* 목록 */}
      <div className="border rounded-lg">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="text-xs w-[60px]">출처</TableHead>
              <TableHead className="text-xs">테이블</TableHead>
              <TableHead className="text-xs">관계 유형</TableHead>
              <TableHead className="text-xs">CRUD</TableHead>
              <TableHead className="text-xs">설명</TableHead>
              <TableHead className="text-xs w-[100px]">작업</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              <TableRow>
                <TableCell colSpan={6} className="text-center py-8 text-muted-foreground">
                  <Loader2 className="h-5 w-5 animate-spin mx-auto" />
                </TableCell>
              </TableRow>
            ) : unifiedTableRelations.length === 0 ? (
              <TableRow>
                <TableCell colSpan={6} className="text-center py-8 text-muted-foreground text-sm">
                  등록된 테이블 연결이 없습니다.
                </TableCell>
              </TableRow>
            ) : (
              unifiedTableRelations.map((item) => (
                <TableRow key={item.id} className={item.source === "designer" ? "bg-orange-50/50" : ""}>
                  <TableCell className="text-xs">
                    <Badge variant="outline" className={cn(
                      "h-5 px-2",
                      item.source === "designer" 
                        ? "border-orange-400 text-orange-700 bg-orange-100" 
                        : "border-blue-400 text-blue-700 bg-blue-100"
                    )}>
                      {item.source === "designer" ? "화면" : "DB"}
                    </Badge>
                  </TableCell>
                  <TableCell className="text-xs">
                    <div>
                      <span className="font-medium">{item.table_label || item.table_name}</span>
                      {item.table_label && item.table_label !== item.table_name && (
                        <span className="text-muted-foreground ml-1">({item.table_name})</span>
                      )}
                    </div>
                    {/* 필터 테이블의 경우 필터 컬럼/조인 정보 표시 */}
                    {item.source === "designer" && "filterColumns" in item && item.filterColumns && item.filterColumns.length > 0 && (
                      <div className="flex flex-wrap gap-1 mt-1">
                        {item.filterColumns.map((col, idx) => (
                          <span key={idx} className="px-1.5 py-0.5 bg-purple-100 text-purple-600 text-[10px] rounded font-mono">
                            {col}
                          </span>
                        ))}
                      </div>
                    )}
                    {item.source === "designer" && "joinColumnRefs" in item && item.joinColumnRefs && item.joinColumnRefs.length > 0 && (
                      <div className="flex flex-wrap gap-1 mt-1">
                        {item.joinColumnRefs.map((join, idx) => (
                          <span key={idx} className="px-1.5 py-0.5 bg-orange-100 text-orange-600 text-[10px] rounded">
                            {join.column}→{join.refTable}
                          </span>
                        ))}
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="text-xs">
                    <span className={`px-2 py-1 rounded text-xs ${
                      item.relation_type === "main" ? "bg-blue-100 text-blue-700" :
                      item.relation_type === "sub" ? "bg-purple-100 text-purple-700" :
                      item.relation_type === "save" ? "bg-pink-100 text-pink-700" :
                      "bg-gray-100 text-gray-700"
                    }`}>
                      {item.relation_type === "main" ? "메인" :
                       item.relation_type === "sub" ? "필터" :
                       item.relation_type === "save" ? "저장" :
                       item.relation_type === "lookup" ? "조회" : item.relation_type}
                    </span>
                  </TableCell>
                  <TableCell className="text-xs">{item.crud_operations}</TableCell>
                  <TableCell className="text-xs text-muted-foreground">
                    {item.description || "-"}
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      {item.source === "db" ? (
                        <>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => handleEdit(item as TableRelation)}
                          >
                            <Pencil className="h-3 w-3" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7 text-destructive"
                            onClick={() => handleDelete(item.id as number)}
                          >
                            <Trash2 className="h-3 w-3" />
                          </Button>
                        </>
                      ) : (
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-7 w-7"
                          title="DB에 저장하여 수정"
                          onClick={() => handleEditDesignerRelation(item as typeof designerTableRelations[0])}
                        >
                          <Pencil className="h-3 w-3" />
                        </Button>
                      )}
                    </div>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>
    </div>
  );
}


// ============================================================
// 탭2: 조인 설정
// ============================================================

interface JoinSettingTabProps {
  screenId: number;
  tableName?: string;
  fieldJoins: FieldJoin[];
  tables: TableInfo[];
  tableColumns: Record<string, ColumnTypeInfo[]>;
  loading: boolean;
  onReload: () => void;
  onLoadColumns: (tableName: string) => void;
  onRefreshVisualization?: () => void;
  // 기존 설정 정보 (화면 디자이너에서 추출)
  existingConfig?: ExistingConfig;
}

// 화면 디자이너 조인 설정을 통합 형식으로 변환하기 위한 인터페이스
interface UnifiedJoinItem {
  id: number | string; // DB는 숫자, 화면 디자이너는 문자열
  source: "db" | "designer"; // 출처
  save_table: string;
  save_table_label?: string;
  save_column: string;
  join_table: string;
  join_table_label?: string;
  join_column: string;
  display_column?: string;
  join_type: string;
}

function JoinSettingTab({
  screenId,
  tableName,
  fieldJoins,
  tables,
  tableColumns,
  loading,
  onReload,
  onLoadColumns,
  onRefreshVisualization,
  existingConfig,
}: JoinSettingTabProps) {
  const [isEditing, setIsEditing] = useState(false);
  const [editItem, setEditItem] = useState<FieldJoin | null>(null);
  const [editingDesignerItem, setEditingDesignerItem] = useState<UnifiedJoinItem | null>(null);
  const [formData, setFormData] = useState({
    field_name: "",
    save_table: tableName || "",
    save_column: "",
    join_table: "",
    join_column: "",
    display_column: "",
    join_type: "LEFT",
    filter_condition: "",
    is_active: "Y",
  });

  // 테이블 라벨 가져오기 (tableName -> displayName) - 먼저 선언해야 함
  const tableLabel = tables.find(t => t.tableName === tableName)?.displayName;

  // 화면 디자이너 조인 설정을 통합 형식으로 변환
  // 1. 현재 테이블의 조인 설정
  const directJoins: UnifiedJoinItem[] = (existingConfig?.joinColumnRefs || []).map((ref, idx) => ({
    id: `designer-direct-${idx}`,
    source: "designer" as const,
    save_table: tableName || "",
    save_table_label: tableLabel || tableName,
    save_column: ref.column,
    join_table: ref.refTable,
    join_table_label: ref.refTableLabel,
    join_column: ref.refColumn,
    display_column: "",
    join_type: "LEFT",
  }));

  // 2. 필터 테이블들의 조인 설정 (화면 노드에서 열었을 때)
  const filterTableJoins: UnifiedJoinItem[] = (existingConfig?.filterTables || []).flatMap((ft, ftIdx) =>
    (ft.joinColumnRefs || []).map((ref, refIdx) => ({
      id: `designer-filter-${ftIdx}-${refIdx}`,
      source: "designer" as const,
      save_table: ft.tableName,
      save_table_label: ft.tableLabel || ft.tableName,
      save_column: ref.column,
      join_table: ref.refTable,
      join_table_label: ref.refTableLabel,
      join_column: ref.refColumn,
      display_column: "",
      join_type: "LEFT",
    }))
  );

  // 모든 디자이너 조인 설정 통합
  const designerJoins: UnifiedJoinItem[] = [...directJoins, ...filterTableJoins];

  // DB 조인 설정을 통합 형식으로 변환
  const dbJoins: UnifiedJoinItem[] = fieldJoins.map((item) => ({
    id: item.id,
    source: "db" as const,
    save_table: item.save_table,
    save_table_label: item.save_table_label,
    save_column: item.save_column,
    join_table: item.join_table,
    join_table_label: item.join_table_label,
    join_column: item.join_column,
    display_column: item.display_column,
    join_type: item.join_type,
  }));

  // 통합된 조인 목록 (화면 디자이너 + DB)
  const unifiedJoins = [...designerJoins, ...dbJoins];

  // 저장 테이블 변경 시 컬럼 로드
  useEffect(() => {
    if (formData.save_table) {
      onLoadColumns(formData.save_table);
    }
  }, [formData.save_table, onLoadColumns]);

  // 조인 테이블 변경 시 컬럼 로드
  useEffect(() => {
    if (formData.join_table) {
      onLoadColumns(formData.join_table);
    }
  }, [formData.join_table, onLoadColumns]);

  // 폼 초기화
  const resetForm = () => {
    setFormData({
      field_name: "",
      save_table: tableName || "",
      save_column: "",
      join_table: "",
      join_column: "",
      display_column: "",
      join_type: "LEFT",
      filter_condition: "",
      is_active: "Y",
    });
    setEditItem(null);
    setEditingDesignerItem(null);
    setIsEditing(false);
  };

  // 수정 모드 (DB 설정)
  const handleEdit = (item: FieldJoin) => {
    setEditItem(item);
    setEditingDesignerItem(null);
    setFormData({
      field_name: item.field_name || "",
      save_table: item.save_table,
      save_column: item.save_column,
      join_table: item.join_table,
      join_column: item.join_column,
      display_column: item.display_column,
      join_type: item.join_type,
      filter_condition: item.filter_condition || "",
      is_active: item.is_active,
    });
    setIsEditing(true);
    // 컬럼 로드
    onLoadColumns(item.save_table);
    onLoadColumns(item.join_table);
  };

  // 통합 목록에서 수정 버튼 클릭
  const handleEditUnified = (item: UnifiedJoinItem) => {
    if (item.source === "db") {
      // DB 설정은 기존 로직 사용
      const originalItem = fieldJoins.find(j => j.id === item.id);
      if (originalItem) handleEdit(originalItem);
    } else {
      // 화면 디자이너 설정은 폼에 채우고 새로 저장하도록
      setEditItem(null);
      setEditingDesignerItem(item);
      setFormData({
        field_name: "",
        save_table: item.save_table,
        save_column: item.save_column,
        join_table: item.join_table,
        join_column: item.join_column,
        display_column: item.display_column || "",
        join_type: item.join_type,
        filter_condition: "",
        is_active: "Y",
      });
      setIsEditing(true);
      // 컬럼 로드
      onLoadColumns(item.save_table);
      onLoadColumns(item.join_table);
    }
  };

  // 통합 목록에서 삭제 버튼 클릭
  const handleDeleteUnified = async (item: UnifiedJoinItem) => {
    if (item.source === "db") {
      // DB 설정만 삭제 가능
      await handleDelete(item.id as number);
    } else {
      // 화면 디자이너 설정은 삭제 불가 (화면 디자이너에서 수정해야 함)
      toast.info("화면 디자이너 설정은 화면 디자이너에서 수정해주세요.");
    }
  };

  // 저장
  const handleSave = async () => {
    if (!formData.save_table || !formData.save_column || !formData.join_table || !formData.join_column) {
      toast.error("필수 필드를 모두 입력해주세요.");
      return;
    }

    try {
      const payload = {
        screen_id: screenId,
        ...formData,
      };

      let response;
      if (editItem) {
        response = await updateFieldJoin(editItem.id, payload);
      } else {
        response = await createFieldJoin(payload);
      }

      if (response.success) {
        toast.success(editItem ? "조인 설정이 수정되었습니다." : "조인 설정이 추가되었습니다.");
        resetForm();
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "저장에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "저장 중 오류가 발생했습니다.");
    }
  };

  // 삭제
  const handleDelete = async (id: number) => {
    if (!confirm("정말 삭제하시겠습니까?")) return;

    try {
      const response = await deleteFieldJoin(id);
      if (response.success) {
        toast.success("조인 설정이 삭제되었습니다.");
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "삭제에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "삭제 중 오류가 발생했습니다.");
    }
  };

  // 저장 테이블 컬럼
  const saveTableColumns = tableColumns[formData.save_table] || [];
  
  // 조인 테이블 컬럼
  const joinTableColumns = tableColumns[formData.join_table] || [];

  return (
    <div className="space-y-4">
      {/* 필터링 컬럼 정보 */}
      {existingConfig?.filterColumns && existingConfig.filterColumns.length > 0 && (
        <div className="bg-purple-50 border border-purple-200 rounded-lg p-4">
          <div className="flex items-center gap-2 mb-2">
            <Database className="h-4 w-4 text-purple-600" />
            <span className="text-sm font-medium text-purple-800">필터링 컬럼 (마스터-디테일 연동)</span>
          </div>
          <div className="flex flex-wrap gap-2">
            {existingConfig.filterColumns.map((col, idx) => (
              <span key={idx} className="px-2 py-1 bg-purple-100 text-purple-700 text-xs rounded font-mono">
                {col}
              </span>
            ))}
          </div>
          <p className="text-xs text-purple-600 mt-2">
            * 이 컬럼들을 기준으로 상위 화면에서 데이터가 필터링됩니다.
          </p>
        </div>
      )}

      {/* 참조 정보 (이 테이블을 참조하는 다른 테이블들) */}
      {existingConfig?.referencedBy && existingConfig.referencedBy.length > 0 && (
        <div className="bg-green-50 border border-green-200 rounded-lg p-4">
          <div className="flex items-center gap-2 mb-3">
            <GitBranch className="h-4 w-4 text-green-600" />
            <span className="text-sm font-medium text-green-800">이 테이블을 참조하는 관계</span>
          </div>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="text-xs">참조하는 테이블</TableHead>
                <TableHead className="text-xs">참조 유형</TableHead>
                <TableHead className="text-xs">연결</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {existingConfig.referencedBy.map((ref, idx) => (
                <TableRow key={idx}>
                  <TableCell className="text-xs">
                    <span className="font-medium">{ref.fromTableLabel || ref.fromTable}</span>
                  </TableCell>
                  <TableCell className="text-xs">
                    <span className={`px-2 py-0.5 rounded text-xs ${
                      ref.relationType === 'join' ? 'bg-orange-100 text-orange-700' :
                      ref.relationType === 'filter' ? 'bg-purple-100 text-purple-700' :
                      'bg-gray-100 text-gray-700'
                    }`}>
                      {ref.relationType}
                    </span>
                  </TableCell>
                  <TableCell className="text-xs font-mono">
                    {ref.fromColumn} → {ref.toColumn}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      )}

      {/* 입력 폼 */}
      <div className="bg-muted/50 rounded-lg p-4 space-y-3">
        <div className="text-sm font-medium">{isEditing ? "조인 설정 수정" : "새 조인 설정 추가"}</div>
        
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
          {/* 저장 테이블 */}
          <div>
            <Label className="text-xs">저장 테이블 *</Label>
            <SearchableSelect
              value={formData.save_table}
              onValueChange={(v) => {
                setFormData(prev => ({ ...prev, save_table: v, save_column: "" }));
              }}
              options={tables.map((t) => ({
                value: t.tableName,
                label: t.displayName || t.tableName,
                description: t.tableName !== t.displayName ? t.tableName : undefined,
              }))}
              placeholder="테이블 선택"
              searchPlaceholder="테이블 검색..."
            />
          </div>

          {/* 저장 컬럼 */}
          <div>
            <Label className="text-xs">저장 컬럼 (FK) *</Label>
            <SearchableSelect
              value={formData.save_column}
              onValueChange={(v) => setFormData(prev => ({ ...prev, save_column: v }))}
              disabled={!formData.save_table}
              options={saveTableColumns.map((c) => ({
                value: c.columnName,
                label: c.displayName || c.columnName,
                description: c.columnName !== c.displayName ? c.columnName : undefined,
              }))}
              placeholder="컬럼 선택"
              searchPlaceholder="컬럼 검색..."
            />
          </div>

          {/* 조인 타입 */}
          <div>
            <Label className="text-xs">조인 타입</Label>
            <SearchableSelect
              value={formData.join_type}
              onValueChange={(v) => setFormData(prev => ({ ...prev, join_type: v }))}
              options={[
                { value: "LEFT", label: "LEFT JOIN" },
                { value: "INNER", label: "INNER JOIN" },
                { value: "RIGHT", label: "RIGHT JOIN" },
              ]}
              placeholder="조인 타입"
              searchPlaceholder="타입 검색..."
            />
          </div>
        </div>

        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
          {/* 조인 테이블 */}
          <div>
            <Label className="text-xs">조인 테이블 *</Label>
            <SearchableSelect
              value={formData.join_table}
              onValueChange={(v) => {
                setFormData(prev => ({ ...prev, join_table: v, join_column: "", display_column: "" }));
              }}
              options={tables.map((t) => ({
                value: t.tableName,
                label: t.displayName || t.tableName,
                description: t.tableName !== t.displayName ? t.tableName : undefined,
              }))}
              placeholder="테이블 선택"
              searchPlaceholder="테이블 검색..."
            />
          </div>

          {/* 조인 컬럼 */}
          <div>
            <Label className="text-xs">조인 컬럼 (PK) *</Label>
            <SearchableSelect
              value={formData.join_column}
              onValueChange={(v) => setFormData(prev => ({ ...prev, join_column: v }))}
              disabled={!formData.join_table}
              options={joinTableColumns.map((c) => ({
                value: c.columnName,
                label: c.displayName || c.columnName,
                description: c.columnName !== c.displayName ? c.columnName : undefined,
              }))}
              placeholder="컬럼 선택"
              searchPlaceholder="컬럼 검색..."
            />
          </div>

          {/* 표시 컬럼 */}
          <div>
            <Label className="text-xs">표시 컬럼</Label>
            <SearchableSelect
              value={formData.display_column}
              onValueChange={(v) => setFormData(prev => ({ ...prev, display_column: v }))}
              disabled={!formData.join_table}
              options={joinTableColumns.map((c) => ({
                value: c.columnName,
                label: c.displayName || c.columnName,
                description: c.columnName !== c.displayName ? c.columnName : undefined,
              }))}
              placeholder="표시할 컬럼 선택"
              searchPlaceholder="컬럼 검색..."
            />
          </div>
        </div>

        <div className="flex justify-end gap-2">
          {isEditing && (
            <Button variant="outline" size="sm" onClick={resetForm}>
              취소
            </Button>
          )}
          <Button size="sm" onClick={handleSave} className="gap-1">
            <Save className="h-4 w-4" />
            {isEditing ? "수정" : "추가"}
          </Button>
        </div>
      </div>

      {/* 통합 조인 목록 */}
      <div className="border rounded-lg overflow-x-auto">
        <div className="bg-muted/30 px-4 py-2 border-b flex items-center justify-between">
          <span className="text-sm font-medium flex items-center gap-2">
            <Link2 className="h-4 w-4" />
            조인 설정 목록
          </span>
          <span className="text-xs text-muted-foreground">
            총 {unifiedJoins.length}개
          </span>
        </div>
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="text-xs">출처</TableHead>
              <TableHead className="text-xs">저장 테이블</TableHead>
              <TableHead className="text-xs">FK 컬럼</TableHead>
              <TableHead className="text-xs">조인 테이블</TableHead>
              <TableHead className="text-xs">PK 컬럼</TableHead>
              <TableHead className="text-xs">타입</TableHead>
              <TableHead className="text-xs w-[100px]">작업</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              <TableRow>
                <TableCell colSpan={7} className="text-center py-8 text-muted-foreground">
                  <Loader2 className="h-5 w-5 animate-spin mx-auto" />
                </TableCell>
              </TableRow>
            ) : unifiedJoins.length === 0 ? (
              <TableRow>
                <TableCell colSpan={7} className="text-center py-8 text-muted-foreground text-sm">
                  등록된 조인 설정이 없습니다.
                </TableCell>
              </TableRow>
            ) : (
              unifiedJoins.map((item) => (
                <TableRow key={item.id} className={item.source === "designer" ? "bg-orange-50/50" : ""}>
                  <TableCell className="text-xs">
                    {item.source === "designer" ? (
                      <span className="px-2 py-0.5 rounded bg-orange-100 text-orange-700 text-xs">
                        화면
                      </span>
                    ) : (
                      <span className="px-2 py-0.5 rounded bg-blue-100 text-blue-700 text-xs">
                        DB
                      </span>
                    )}
                  </TableCell>
                  <TableCell className="text-xs">{item.save_table_label || item.save_table}</TableCell>
                  <TableCell className="text-xs font-mono">{item.save_column}</TableCell>
                  <TableCell className="text-xs">{item.join_table_label || item.join_table}</TableCell>
                  <TableCell className="text-xs font-mono">{item.join_column}</TableCell>
                  <TableCell className="text-xs">
                    <span className="px-2 py-1 rounded bg-gray-100 text-gray-700 text-xs">
                      {item.join_type}
                    </span>
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-7 w-7"
                        onClick={() => handleEditUnified(item)}
                        title={item.source === "designer" ? "DB 설정으로 저장" : "수정"}
                      >
                        <Pencil className="h-3 w-3" />
                      </Button>
                      {item.source === "db" && (
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-7 w-7 text-destructive"
                          onClick={() => handleDeleteUnified(item)}
                          title="삭제"
                        >
                          <Trash2 className="h-3 w-3" />
                        </Button>
                      )}
                    </div>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
        {designerJoins.length > 0 && (
          <div className="px-4 py-2 border-t text-xs text-muted-foreground bg-orange-50/30">
            <span className="text-orange-600">* 화면</span>: 화면 디자이너 설정 (수정 시 DB에 저장) | 
            <span className="text-blue-600 ml-1">* DB</span>: DB 저장 설정 (직접 수정/삭제 가능)
          </div>
        )}
      </div>
    </div>
  );
}


// ============================================================
// 탭3: 데이터 흐름
// ============================================================

interface DataFlowTabProps {
  screenId: number;
  groupId?: number;
  groupScreens: Array<{ screen_id: number; screen_name: string }>;
  dataFlows: DataFlow[];
  loading: boolean;
  onReload: () => void;
  onRefreshVisualization?: () => void;
}

function DataFlowTab({
  screenId,
  groupId,
  groupScreens,
  dataFlows,
  loading,
  onReload,
  onRefreshVisualization,
}: DataFlowTabProps) {
  const [isEditing, setIsEditing] = useState(false);
  const [editItem, setEditItem] = useState<DataFlow | null>(null);
  const [formData, setFormData] = useState({
    source_screen_id: screenId,
    source_action: "",
    target_screen_id: 0,
    target_action: "",
    flow_type: "unidirectional",
    flow_label: "",
    is_active: "Y",
  });

  // 폼 초기화
  const resetForm = () => {
    setFormData({
      source_screen_id: screenId,
      source_action: "",
      target_screen_id: 0,
      target_action: "",
      flow_type: "unidirectional",
      flow_label: "",
      is_active: "Y",
    });
    setEditItem(null);
    setIsEditing(false);
  };

  // 수정 모드
  const handleEdit = (item: DataFlow) => {
    setEditItem(item);
    setFormData({
      source_screen_id: item.source_screen_id,
      source_action: item.source_action || "",
      target_screen_id: item.target_screen_id,
      target_action: item.target_action || "",
      flow_type: item.flow_type,
      flow_label: item.flow_label || "",
      is_active: item.is_active,
    });
    setIsEditing(true);
  };

  // 저장
  const handleSave = async () => {
    if (!formData.source_screen_id || !formData.target_screen_id) {
      toast.error("소스 화면과 타겟 화면을 선택해주세요.");
      return;
    }

    try {
      const payload = {
        group_id: groupId,
        ...formData,
      };

      let response;
      if (editItem) {
        response = await updateDataFlow(editItem.id, payload);
      } else {
        response = await createDataFlow(payload);
      }

      if (response.success) {
        toast.success(editItem ? "데이터 흐름이 수정되었습니다." : "데이터 흐름이 추가되었습니다.");
        resetForm();
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "저장에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "저장 중 오류가 발생했습니다.");
    }
  };

  // 삭제
  const handleDelete = async (id: number) => {
    if (!confirm("정말 삭제하시겠습니까?")) return;

    try {
      const response = await deleteDataFlow(id);
      if (response.success) {
        toast.success("데이터 흐름이 삭제되었습니다.");
        onReload();
        onRefreshVisualization?.();
      } else {
        toast.error(response.message || "삭제에 실패했습니다.");
      }
    } catch (error: any) {
      toast.error(error.message || "삭제 중 오류가 발생했습니다.");
    }
  };

  // 그룹 없음 안내
  if (!groupId) {
    return (
      <div className="flex flex-col items-center justify-center py-12 text-center">
        <GitBranch className="h-12 w-12 text-muted-foreground mb-4" />
        <h3 className="text-lg font-semibold mb-2">그룹 정보가 없습니다</h3>
        <p className="text-sm text-muted-foreground">
          데이터 흐름 설정은 화면 그룹 내에서만 사용할 수 있습니다.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* 입력 폼 */}
      <div className="bg-muted/50 rounded-lg p-4 space-y-3">
        <div className="text-sm font-medium">{isEditing ? "데이터 흐름 수정" : "새 데이터 흐름 추가"}</div>
        
        <div className="grid grid-cols-1 sm:grid-cols-4 gap-3">
          {/* 소스 화면 */}
          <div>
            <Label className="text-xs">소스 화면 *</Label>
            <SearchableSelect
              value={formData.source_screen_id.toString()}
              onValueChange={(v) => setFormData(prev => ({ ...prev, source_screen_id: parseInt(v) }))}
              options={groupScreens.map((s) => ({
                value: s.screen_id.toString(),
                label: s.screen_name,
              }))}
              placeholder="화면 선택"
              searchPlaceholder="화면 검색..."
            />
          </div>

          {/* 소스 액션 */}
          <div>
            <Label className="text-xs">소스 액션</Label>
            <Input
              value={formData.source_action}
              onChange={(e) => setFormData(prev => ({ ...prev, source_action: e.target.value }))}
              placeholder="예: 행 선택"
              className="h-9 text-xs"
            />
          </div>

          {/* 타겟 화면 */}
          <div>
            <Label className="text-xs">타겟 화면 *</Label>
            <SearchableSelect
              value={formData.target_screen_id.toString()}
              onValueChange={(v) => setFormData(prev => ({ ...prev, target_screen_id: parseInt(v) }))}
              options={groupScreens
                .filter(s => s.screen_id !== formData.source_screen_id)
                .map((s) => ({
                  value: s.screen_id.toString(),
                  label: s.screen_name,
                }))}
              placeholder="화면 선택"
              searchPlaceholder="화면 검색..."
            />
          </div>

          {/* 흐름 타입 */}
          <div>
            <Label className="text-xs">흐름 타입</Label>
            <SearchableSelect
              value={formData.flow_type}
              onValueChange={(v) => setFormData(prev => ({ ...prev, flow_type: v }))}
              options={[
                { value: "unidirectional", label: "단방향" },
                { value: "bidirectional", label: "양방향" },
              ]}
              placeholder="흐름 타입"
              searchPlaceholder="타입 검색..."
            />
          </div>
        </div>

        <div className="flex justify-end gap-2">
          {isEditing && (
            <Button variant="outline" size="sm" onClick={resetForm}>
              취소
            </Button>
          )}
          <Button size="sm" onClick={handleSave} className="gap-1">
            <Save className="h-4 w-4" />
            {isEditing ? "수정" : "추가"}
          </Button>
        </div>
      </div>

      {/* 목록 */}
      <div className="border rounded-lg">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="text-xs">소스 화면</TableHead>
              <TableHead className="text-xs">액션</TableHead>
              <TableHead className="text-xs">타겟 화면</TableHead>
              <TableHead className="text-xs">흐름</TableHead>
              <TableHead className="text-xs w-[100px]">작업</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              <TableRow>
                <TableCell colSpan={5} className="text-center py-8 text-muted-foreground">
                  <Loader2 className="h-5 w-5 animate-spin mx-auto" />
                </TableCell>
              </TableRow>
            ) : dataFlows.length === 0 ? (
              <TableRow>
                <TableCell colSpan={5} className="text-center py-8 text-muted-foreground text-sm">
                  등록된 데이터 흐름이 없습니다.
                </TableCell>
              </TableRow>
            ) : (
              dataFlows.map((item) => (
                <TableRow key={item.id}>
                  <TableCell className="text-xs font-medium">
                    {item.source_screen_name || `화면 ${item.source_screen_id}`}
                  </TableCell>
                  <TableCell className="text-xs text-muted-foreground">
                    {item.source_action || "-"}
                  </TableCell>
                  <TableCell className="text-xs font-medium">
                    {item.target_screen_name || `화면 ${item.target_screen_id}`}
                  </TableCell>
                  <TableCell className="text-xs">
                    <span className={`px-2 py-1 rounded text-xs ${
                      item.flow_type === "bidirectional" 
                        ? "bg-purple-100 text-purple-700" 
                        : "bg-blue-100 text-blue-700"
                    }`}>
                      {item.flow_type === "bidirectional" ? "양방향" : "단방향"}
                    </span>
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-7 w-7"
                        onClick={() => handleEdit(item)}
                      >
                        <Pencil className="h-3 w-3" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-7 w-7 text-destructive"
                        onClick={() => handleDelete(item.id)}
                      >
                        <Trash2 className="h-3 w-3" />
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>
    </div>
  );
}


// ============================================================
// 탭4: 필드-컬럼 매핑 (화면 컴포넌트와 DB 컬럼 연결)
// ============================================================

interface FieldMappingTabProps {
  screenId: number;
  tableName?: string;
  tableColumns: ColumnTypeInfo[];
  loading: boolean;
}

function FieldMappingTab({
  screenId,
  tableName,
  tableColumns,
  loading,
}: FieldMappingTabProps) {
  // 필드 매핑은 screen_layouts.properties에서 관리됨
  // 이 탭에서는 현재 매핑 상태를 조회하고 편집 가능하게 제공
  
  return (
    <div className="space-y-4">
      <div className="bg-muted/50 rounded-lg p-4">
        <div className="flex items-center gap-2 mb-2">
          <Columns3 className="h-5 w-5 text-blue-500" />
          <span className="text-sm font-medium">필드-컬럼 매핑</span>
        </div>
        <p className="text-xs text-muted-foreground">
          화면 컴포넌트와 데이터베이스 컬럼 간의 바인딩을 설정합니다.
          <br />
          현재는 화면 디자이너에서 설정된 내용을 확인할 수 있습니다.
        </p>
      </div>

      {/* 테이블 컬럼 목록 */}
      {tableName && (
        <div className="border rounded-lg">
          <div className="bg-muted/30 px-4 py-2 border-b">
            <span className="text-sm font-medium">테이블: {tableName}</span>
          </div>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="text-xs">컬럼명</TableHead>
                <TableHead className="text-xs">한글명</TableHead>
                <TableHead className="text-xs">데이터 타입</TableHead>
                <TableHead className="text-xs">웹 타입</TableHead>
                <TableHead className="text-xs">PK</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={5} className="text-center py-8 text-muted-foreground">
                    <Loader2 className="h-5 w-5 animate-spin mx-auto" />
                  </TableCell>
                </TableRow>
              ) : tableColumns.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={5} className="text-center py-8 text-muted-foreground text-sm">
                    컬럼 정보가 없습니다.
                  </TableCell>
                </TableRow>
              ) : (
                tableColumns.slice(0, 20).map((col) => (
                  <TableRow key={col.columnName}>
                    <TableCell className="text-xs font-mono">{col.columnName}</TableCell>
                    <TableCell className="text-xs">{col.displayName}</TableCell>
                    <TableCell className="text-xs text-muted-foreground">{col.dbType}</TableCell>
                    <TableCell className="text-xs">
                      <span className="px-2 py-0.5 rounded bg-gray-100 text-gray-700 text-xs">
                        {col.webType}
                      </span>
                    </TableCell>
                    <TableCell className="text-xs">
                      {col.isPrimaryKey && (
                        <span className="px-2 py-0.5 rounded bg-yellow-100 text-yellow-700 text-xs">
                          PK
                        </span>
                      )}
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
          {tableColumns.length > 20 && (
            <div className="px-4 py-2 text-xs text-muted-foreground border-t">
              + {tableColumns.length - 20}개 더 있음
            </div>
          )}
        </div>
      )}

      {!tableName && (
        <div className="flex flex-col items-center justify-center py-12 text-center">
          <Database className="h-12 w-12 text-muted-foreground mb-4" />
          <h3 className="text-lg font-semibold mb-2">테이블 정보가 없습니다</h3>
          <p className="text-sm text-muted-foreground">
            테이블 노드에서 더블클릭하여 필드 매핑을 확인하세요.
          </p>
        </div>
      )}
    </div>
  );
}

