/**
 * 데이터 전달 시스템 타입 정의
 * 컴포넌트 간, 화면 간 데이터 전달을 위한 공통 타입들
 */

/**
 * 데이터 수신 가능한 컴포넌트 타입
 */
export type DataReceivableComponentType = 
  | "table" 
  | "form" 
  | "input" 
  | "select" 
  | "repeater" 
  | "form-group" 
  | "hidden";

/**
 * 데이터 수신 모드
 */
export type DataReceiveMode = 
  | "append"    // 기존 데이터에 추가
  | "replace"   // 기존 데이터를 완전히 교체
  | "merge";    // 기존 데이터와 병합 (키 기준)

/**
 * 변환 함수 타입
 */
export type TransformFunction = 
  | "sum"       // 합계
  | "average"   // 평균
  | "concat"    // 문자열 결합
  | "first"     // 첫 번째 값
  | "last"      // 마지막 값
  | "count"     // 개수
  | "custom";   // 커스텀 함수

/**
 * 조건 연산자
 */
export type ConditionOperator = 
  | "equals" 
  | "contains" 
  | "greaterThan" 
  | "lessThan" 
  | "notEquals";

/**
 * 매핑 규칙
 * 소스 필드에서 타겟 필드로 데이터를 매핑하는 규칙
 */
export interface MappingRule {
  sourceField: string;        // 소스 필드명
  targetField: string;        // 타겟 필드명
  transform?: TransformFunction; // 변환 함수
  defaultValue?: any;         // 기본값
  required?: boolean;         // 필수 여부
}

/**
 * 멀티 테이블 매핑 그룹
 * 소스 테이블별로 별도의 매핑 규칙을 정의
 */
export interface MultiTableMappingGroup {
  sourceTable: string;
  mappingRules: MappingRule[];
}

/**
 * 데이터 수신자 설정
 * 데이터를 받을 타겟 컴포넌트의 설정
 */
export interface DataReceiverConfig {
  targetComponentId: string;           // 타겟 컴포넌트 ID
  targetComponentType: DataReceivableComponentType; // 타겟 컴포넌트 타입
  mode: DataReceiveMode;               // 수신 모드
  mappingRules: MappingRule[];         // 매핑 규칙 배열
  
  // 조건부 전달
  condition?: {
    field: string;
    operator: ConditionOperator;
    value: any;
  };
  
  // 검증 규칙
  validation?: {
    required?: boolean;
    minRows?: number;
    maxRows?: number;
  };
}

/**
 * 데이터 전달 설정
 * 버튼 액션에서 사용하는 데이터 전달 설정
 */
export interface DataTransferConfig {
  // 소스 설정
  sourceComponentId: string;           // 데이터를 가져올 컴포넌트 ID (테이블 등)
  sourceComponentType?: string;        // 소스 컴포넌트 타입
  
  // 타겟 설정
  targetType: "component" | "screen";  // 타겟 타입 (같은 화면의 컴포넌트 or 다른 화면)
  
  // 타겟이 컴포넌트인 경우
  targetComponentId?: string;          // 타겟 컴포넌트 ID
  targetComponentType?: DataReceivableComponentType; // 타겟 컴포넌트 타입
  
  // 타겟이 화면인 경우
  targetScreenId?: number;             // 타겟 화면 ID
  
  // 데이터 수신자 (여러 개 가능)
  dataReceivers: DataReceiverConfig[];
  
  // 전달 옵션
  clearAfterTransfer?: boolean;        // 전달 후 소스 데이터 초기화
  confirmBeforeTransfer?: boolean;     // 전달 전 확인 메시지
  confirmMessage?: string;             // 확인 메시지 내용
  
  // 검증
  validation?: {
    requireSelection?: boolean;        // 선택 필수
    minSelection?: number;             // 최소 선택 개수
    maxSelection?: number;             // 최대 선택 개수
  };
}

/**
 * 데이터 전달 결과
 */
export interface DataTransferResult {
  success: boolean;
  transferredCount: number;
  errors?: string[];
  message?: string;
}

/**
 * 데이터 수신 가능한 컴포넌트 인터페이스
 * 데이터를 받을 수 있는 컴포넌트가 구현해야 하는 인터페이스
 */
export interface DataReceivable {
  componentId: string;
  componentType: DataReceivableComponentType;
  
  /**
   * 데이터를 수신하는 메서드
   * @param data 전달받은 데이터 배열
   * @param config 수신 설정
   */
  receiveData(data: any[], config: DataReceiverConfig): Promise<void>;
  
  /**
   * 현재 컴포넌트의 데이터를 가져오는 메서드
   */
  getData(): any;
}

/**
 * 엔티티 조인 컬럼 메타데이터
 * 소스 테이블의 FK가 참조 테이블과 어떻게 조인되었는지 정보
 */
export interface EntityJoinColumnMeta {
  sourceColumn: string;
  joinAlias: string;
  referenceTable: string;
  sourceTable?: string;
}

/**
 * 데이터 제공 가능한 컴포넌트 인터페이스
 * 데이터를 제공할 수 있는 컴포넌트가 구현해야 하는 인터페이스
 */
export interface DataProvidable {
  componentId: string;
  componentType: string;
  tableName?: string;
  
  /**
   * 선택된 데이터를 가져오는 메서드
   */
  getSelectedData(): any[];
  
  /**
   * 모든 데이터를 가져오는 메서드
   */
  getAllData(): any[];
  
  /**
   * 선택 초기화 메서드
   */
  clearSelection(): void;

  /**
   * 엔티티 조인 컬럼 메타데이터 반환 (선택적)
   * 전달 매핑 시 조인 alias 해결에 사용
   */
  getEntityJoinColumns?(): EntityJoinColumnMeta[];
}

