/**
 * 통합 폼 시스템 타입 정의
 * 
 * V2 컴포넌트들과 레거시 컴포넌트들이 공유하는 폼 관련 타입
 */

import { ValidationRule } from "./v2-core";

// ===== 폼 상태 타입 =====

/**
 * 폼 액션 타입
 */
export type FormActionType =
  | "submit"      // 저장
  | "reset"       // 초기화 (원본 데이터로 복원)
  | "validate"    // 검증
  | "clear"       // 비우기 (빈 상태로)
  | "refresh"     // 새로고침 (데이터 다시 로드)
  | "cancel";     // 취소

/**
 * 폼 상태
 */
export interface FormStatus {
  isSubmitting: boolean;   // 저장 중
  isValidating: boolean;   // 검증 중
  isDirty: boolean;        // 변경됨
  isValid: boolean;        // 유효함
  isLoading: boolean;      // 데이터 로딩 중
  submitCount: number;     // 저장 시도 횟수
}

/**
 * 필드 에러
 */
export interface FieldError {
  fieldId: string;
  message: string;
  type: "required" | "format" | "range" | "custom" | "server";
}

/**
 * 필드 상태
 */
export interface FieldState {
  value: unknown;
  originalValue?: unknown;  // 수정 모드에서 원본 값
  touched: boolean;         // 사용자가 건드렸는지
  dirty: boolean;           // 값이 변경되었는지
  error?: FieldError;
  disabled?: boolean;
  visible?: boolean;
  validating?: boolean;
}

// ===== 저장 설정 타입 =====

/**
 * 저장 모드
 */
export type SaveMode = "insert" | "update" | "upsert";

/**
 * 리피터 필드 설정
 */
export interface RepeaterFieldConfig {
  fieldName: string;      // formData에서의 필드명
  targetTable: string;    // 저장할 대상 테이블
  fkColumn: string;       // 부모 테이블과 연결할 FK 컬럼
  fkSourceField?: string; // FK 값을 가져올 부모 필드 (기본: 부모 PK)
}

/**
 * 저장 후 액션
 */
export interface AfterSubmitAction {
  action: "close" | "reset" | "redirect" | "refresh" | "stay";
  redirectUrl?: string;
  redirectScreenId?: number;
  showSuccessToast?: boolean;
  successMessage?: string;
}

/**
 * 저장 설정
 */
export interface SubmitConfig {
  tableName: string;
  mode: SaveMode;
  primaryKey?: string;
  
  // 리피터 데이터 처리
  repeaterFields?: RepeaterFieldConfig[];
  
  // 저장 후 액션
  afterSubmit?: AfterSubmitAction;
  
  // 검증 옵션
  validateBeforeSubmit?: boolean;
  
  // 추가 데이터 (userId, companyCode 등 자동 주입)
  additionalData?: Record<string, unknown>;
  
  // 콜백
  onBeforeSubmit?: (data: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;
  onAfterSubmit?: (result: SubmitResult) => void;
}

/**
 * 저장 결과
 */
export interface SubmitResult {
  success: boolean;
  data?: Record<string, unknown>;
  insertedId?: string | number;
  error?: string;
  errors?: FieldError[];
}

// ===== 검증 설정 타입 =====

/**
 * 필드 검증 설정
 */
export interface FieldValidationConfig {
  fieldId: string;
  rules: ValidationRule[];
  validateOnChange?: boolean;
  validateOnBlur?: boolean;
}

/**
 * 폼 검증 설정
 */
export interface FormValidationConfig {
  fields: FieldValidationConfig[];
  validateOnSubmit?: boolean;
  stopOnFirstError?: boolean;
}

/**
 * 검증 결과
 */
export interface ValidationResult {
  valid: boolean;
  errors: FieldError[];
}

// ===== 화면 간 데이터 전달 타입 =====

/**
 * 필드 매핑
 */
export interface FieldMapping {
  sourceField: string;
  targetField: string;
  transform?: "copy" | "lookup" | "calculate" | "format";
  transformConfig?: Record<string, unknown>;
}

/**
 * 데이터 전달 트리거
 */
export type DataTransferTrigger = 
  | "onSelect"    // 행 선택 시
  | "onSave"      // 저장 시
  | "onLoad"      // 로드 시
  | "onChange"    // 값 변경 시
  | "manual";     // 수동 호출

/**
 * 화면 간 데이터 전달 설정
 */
export interface ScreenDataTransferConfig {
  // 소스 (데이터를 보내는 쪽)
  source: {
    screenId?: number;
    componentId?: string;
    fields: string[];  // 전달할 필드들
  };
  
  // 타겟 (데이터를 받는 쪽)
  target: {
    screenId?: number;
    componentId?: string;
    mappings: FieldMapping[];
  };
  
  // 트리거
  trigger: DataTransferTrigger;
  
  // 조건 (선택사항)
  condition?: {
    field: string;
    operator: "=" | "!=" | ">" | "<" | "in" | "notIn";
    value: unknown;
  };
}

// ===== Context 타입 =====

/**
 * 확장된 V2FormContext 값
 */
export interface ExtendedFormContextValue {
  // === 기존 V2FormContext 기능 ===
  formData: Record<string, unknown>;
  fieldStates: Record<string, FieldState>;
  
  getValue: (fieldId: string) => unknown;
  setValue: (fieldId: string, value: unknown) => void;
  setValues: (values: Record<string, unknown>) => void;
  
  // === 새로 추가되는 기능 ===
  
  // 원본 데이터 (수정 모드)
  originalData: Record<string, unknown>;
  
  // 폼 상태
  status: FormStatus;
  errors: FieldError[];
  
  // 폼 액션
  submit: (config?: Partial<SubmitConfig>) => Promise<SubmitResult>;
  reset: () => void;
  validate: (fieldIds?: string[]) => Promise<ValidationResult>;
  clear: () => void;
  
  // 초기 데이터 설정 (수정 모드 진입)
  setInitialData: (data: Record<string, unknown>) => void;
  
  // 에러 관리
  setFieldError: (fieldId: string, error: string, type?: FieldError["type"]) => void;
  clearFieldError: (fieldId: string) => void;
  clearAllErrors: () => void;
  
  // dirty 체크
  getChangedFields: () => string[];
  hasChanges: () => boolean;
  
  // 필드 등록/해제
  registerField: (fieldId: string, config?: { initialValue?: unknown; validation?: ValidationRule[] }) => void;
  unregisterField: (fieldId: string) => void;
  
  // 리피터 데이터 관리
  getRepeaterData: (fieldName: string) => unknown[];
  setRepeaterData: (fieldName: string, data: unknown[]) => void;
  addRepeaterRow: (fieldName: string, row: Record<string, unknown>) => void;
  updateRepeaterRow: (fieldName: string, index: number, row: Record<string, unknown>) => void;
  deleteRepeaterRow: (fieldName: string, index: number) => void;
  
  // 설정
  submitConfig?: SubmitConfig;
  validationConfig?: FormValidationConfig;
}

// ===== 호환성 브릿지 타입 =====

/**
 * 레거시 폼 데이터 핸들러
 */
export type LegacyFormDataChangeHandler = (fieldName: string, value: unknown) => void;

/**
 * 호환성 브릿지 옵션
 */
export interface FormCompatibilityOptions {
  // 레거시 콜백 지원
  legacyOnFormDataChange?: LegacyFormDataChangeHandler;
  
  // ScreenContext 연동
  screenContext?: {
    updateFormData?: (field: string, value: unknown) => void;
    formData?: Record<string, unknown>;
  };
  
  // beforeFormSave 이벤트 발생 여부
  emitLegacyEvents?: boolean;
}

/**
 * 호환성 브릿지 반환값
 */
export interface FormCompatibilityBridge {
  // 값 관리 (통합 API)
  getValue: (field: string) => unknown;
  setValue: (field: string, value: unknown) => void;
  
  // 폼 액션 (통합 API)
  submit: (config?: Partial<SubmitConfig>) => Promise<SubmitResult>;
  reset: () => void;
  validate: () => Promise<ValidationResult>;
  
  // 폼 데이터 (읽기 전용)
  formData: Record<string, unknown>;
  
  // 상태
  isSubmitting: boolean;
  isDirty: boolean;
  errors: FieldError[];
  
  // 모드
  isV2Mode: boolean;  // V2FormContext 사용 여부
  isLegacyMode: boolean;   // 레거시 모드 여부
}

// ===== 이벤트 타입 =====

/**
 * 폼 이벤트 상세
 */
export interface FormEventDetail {
  formData: Record<string, unknown>;
  fieldName?: string;
  value?: unknown;
  action?: FormActionType;
}

/**
 * beforeFormSave 이벤트 (레거시 호환)
 */
export interface BeforeFormSaveEvent extends CustomEvent<FormEventDetail> {
  type: "beforeFormSave";
}

/**
 * afterFormSave 이벤트
 */
export interface AfterFormSaveEvent extends CustomEvent<{
  success: boolean;
  data?: Record<string, unknown>;
  error?: string;
}> {
  type: "afterFormSave";
}

/**
 * 화면 간 데이터 전달 이벤트
 */
export interface ScreenDataTransferEvent extends CustomEvent<{
  sourceScreenId?: number;
  targetScreenId?: number;
  data: Record<string, unknown>;
  trigger: DataTransferTrigger;
}> {
  type: "screenDataTransfer";
}

// ===== 유틸리티 타입 =====

/**
 * 폼 데이터에서 특정 필드만 추출
 */
export type PickFormFields<T extends Record<string, unknown>, K extends keyof T> = Pick<T, K>;

/**
 * 폼 데이터에서 특정 필드 제외
 */
export type OmitFormFields<T extends Record<string, unknown>, K extends keyof T> = Omit<T, K>;

/**
 * 필드를 옵셔널로 변환
 */
export type PartialFormData<T extends Record<string, unknown>> = Partial<T>;

/**
 * 리피터 데이터 타입
 */
export type RepeaterData<T extends Record<string, unknown> = Record<string, unknown>> = T[];

