/**
 * 웹타입을 INVYONE canonical 컴포넌트로 매핑하는 유틸리티
 */

export interface WebTypeMapping {
  web_type: string;
  componentId: string;
  description: string;
}

export interface V2ComponentMapping {
  componentType: string; // input/table/button 등 canonical component id
  config: Record<string, any>; // 컴포넌트별 기본 설정
}

/**
 * 웹타입 → INVYONE canonical 컴포넌트 매핑 테이블
 */
export const WEB_TYPE_V2_MAPPING: Record<string, V2ComponentMapping> = {
  // 텍스트 입력 계열 → InputComponent (InvField canonical)
  text: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "free" },
  },
  email: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "email" },
  },
  password: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "password" },
  },
  tel: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "phone" },
  },
  url: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "url" },
  },
  color: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "color" },
  },
  textarea: {
    componentType: "input",
    config: { kind: "input", type: "textarea", format: "free", rows: 3 },
  },

  // 숫자 입력 → InputComponent
  number: {
    componentType: "input",
    config: { kind: "input", type: "number", format: "int" },
  },
  decimal: {
    componentType: "input",
    config: { kind: "input", type: "number", format: "decimal", step: 0.01 },
  },
  slider: {
    componentType: "input",
    config: { kind: "input", type: "number", format: "slider", min: 0, max: 100, step: 1 },
  },

  // 날짜/시간 → InputComponent (type=date/datetime/time/daterange)
  date: {
    componentType: "input",
    config: { type: "date", dateFormat: "YYYY-MM-DD" },
  },
  datetime: {
    componentType: "input",
    config: { type: "datetime", dateFormat: "YYYY-MM-DD HH:mm" },
  },
  time: {
    componentType: "input",
    config: { type: "time" },
  },
  daterange: {
    componentType: "input",
    config: { type: "daterange", dateFormat: "YYYY-MM-DD" },
  },

  // 선택 입력 (single dropdown) → InputComponent (InvField canonical)
  select: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "list", options: [] },
  },
  dropdown: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "list", options: [] },
  },
  radio: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "list", mode: "radio", source: "static", options: [] },
  },
  checkbox: {
    componentType: "input",
    config: { kind: "choice", type: "multi", format: "list", mode: "check", source: "static", options: [] },
  },
  boolean: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "boolean", mode: "toggle", inputType: "boolean" },
  },

  // 코드/참조 → InputComponent (InvField canonical)
  code: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "code", mode: "dropdown", source: "category", inputType: "category", codeGroup: "" },
  },

  // 엔티티/참조 테이블 → InputComponent (InvField canonical)
  entity: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "entity", mode: "dropdown", source: "entity", inputType: "entity", searchable: true },
  },

  // 카테고리 → InputComponent (InvField canonical)
  category: {
    componentType: "input",
    config: { kind: "choice", type: "single", format: "code", mode: "dropdown", source: "category", inputType: "category" },
  },

  // 파일/이미지 → InputComponent (canonical input) — type=file, format 으로 image/file 분기
  file: {
    componentType: "input",
    config: {
      kind: "attach",
      type: "file",
      format: "file",
      accept: "*/*",
      multiple: true,
      maxFiles: 10,
    },
  },
  image: {
    componentType: "input",
    config: {
      kind: "attach",
      type: "file",
      format: "image",
      accept: "image/*",
      multiple: false,
      maxFiles: 1,
      showPreview: true,
    },
  },
  img: {
    componentType: "input",
    config: {
      kind: "attach",
      type: "file",
      format: "image",
      accept: "image/*",
      multiple: false,
      maxFiles: 1,
      showPreview: true,
    },
  },

  // 버튼은 V2 컴포넌트에서 제외 (기존 버튼 시스템 사용)
  button: {
    componentType: "button-primary", // 레거시 유지
    config: {},
  },

  // 라벨/텍스트 표시 → InputComponent (readonly)
  label: {
    componentType: "input",
    config: { kind: "input", type: "text", format: "free", readonly: true },
  },
};

/**
 * 레거시 매핑 테이블 (하위 호환성)
 */
export const WEB_TYPE_COMPONENT_MAPPING: Record<string, string> = {
  text: "input",
  email: "input",
  password: "input",
  tel: "input",
  url: "input",
  color: "input",
  number: "input",
  decimal: "input",
  slider: "input",
  textarea: "input",
  date: "input",
  datetime: "input",
  time: "input",
  daterange: "input",
  select: "input",
  dropdown: "input",
  checkbox: "input",
  radio: "input",
  boolean: "input",
  code: "input",
  entity: "input",
  category: "input",
  // file / image / img → canonical input (Phase D.4, 2026-05-12)
  file: "input",
  image: "input",
  img: "input",
  button: "button-primary",
  label: "input",
};

/**
 * 웹타입을 canonical 컴포넌트 ID로 변환
 */
export function getComponentIdFromWebType(webType: string): string {
  const mapping = WEB_TYPE_V2_MAPPING[webType];

  if (!mapping) {
    console.warn(`웹타입 "${webType}"에 대한 매핑을 찾을 수 없습니다. 기본값 'input' 사용`);
    return "input";
  }

  return mapping.componentType;
}

/**
 * 웹타입에 대한 canonical 컴포넌트 기본 설정 가져오기
 */
export function getV2ConfigFromWebType(webType: string): Record<string, any> {
  const mapping = WEB_TYPE_V2_MAPPING[webType];

  if (!mapping) {
    console.warn(`웹타입 "${webType}"에 대한 V2 설정을 찾을 수 없습니다. 기본 설정 사용`);
    return { inputType: "text" };
  }

  return { ...mapping.config };
}

/**
 * 웹타입에 대한 전체 canonical 매핑 정보 가져오기
 */
export function getV2MappingFromWebType(webType: string): V2ComponentMapping {
  const mapping = WEB_TYPE_V2_MAPPING[webType];

  if (!mapping) {
    return {
      componentType: "input",
      config: { kind: "input", type: "text", format: "free" },
    };
  }

  return {
    componentType: mapping.componentType,
    config: { ...mapping.config },
  };
}

/**
 * 컬럼 정보를 기반으로 canonical 컴포넌트 설정 생성
 */
export function createV2ConfigFromColumn(column: {
  widgetType: string;
  columnName: string;
  columnLabel?: string;
  codeInfo?: string;
  inputType?: string;
  required?: boolean;
  detailSettings?: string | Record<string, any>; // 테이블 타입 관리의 detail_settings
  // 직접 저장된 참조 정보 (column_labels 테이블)
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
}): { componentType: string; componentConfig: Record<string, any> } {
  const mapping = getV2MappingFromWebType(column.widgetType);

  // detailSettings 파싱 (문자열이면 JSON 파싱)
  let parsedDetailSettings: Record<string, any> = {};
  if (column.detailSettings) {
    if (typeof column.detailSettings === "string") {
      try {
        parsedDetailSettings = JSON.parse(column.detailSettings);
      } catch (e) {
        // JSON이 아닌 문자열일 수 있음 (예: "참조테이블: 회사관리")
        console.warn("detail_settings 파싱 실패 (문자열일 수 있음):", column.detailSettings);
      }
    } else {
      parsedDetailSettings = column.detailSettings;
    }
  }

  const componentConfig: Record<string, any> = {
    ...mapping.config,
    web_type: column.widgetType, // 원본 웹타입 보존
    // DB의 input_type이 있으면 사용, 없으면 매핑에서 가져온 값 유지
    inputType: column.inputType || mapping.config.inputType || "text",
    placeholder: parsedDetailSettings.placeholder || column.columnLabel || column.columnName,
  };

  // 코드 타입인 경우 코드 카테고리 추가
  if (column.widgetType === "code" && column.codeInfo) {
    componentConfig.codeGroup = column.codeInfo;
    componentConfig.codeInfo = column.codeInfo;
  }

  // 엔티티 타입인 경우 참조 테이블/컬럼 정보 추가
  if (column.widgetType === "entity") {
    componentConfig.searchable = parsedDetailSettings.searchable ?? true;
    
    // 다양한 필드명 지원 (레거시 호환)
    // referenceTable / entityTable 둘 다 지원
    const refTable = 
      parsedDetailSettings.referenceTable || 
      parsedDetailSettings.entityTable || 
      column.referenceTable;
    
    // referenceColumn / entityCodeColumn / entityValueColumn 지원
    const refColumn = 
      parsedDetailSettings.referenceColumn || 
      parsedDetailSettings.entityCodeColumn || 
      parsedDetailSettings.entityValueColumn ||
      column.referenceColumn || 
      "id";
    
    // displayColumn / entityLabelColumn 지원
    const dispColumn = 
      parsedDetailSettings.displayColumn || 
      parsedDetailSettings.entityLabelColumn ||
      column.displayColumn || 
      "name";
    
    console.log("🎯 엔티티 매핑:", {
      columnName: column.columnName,
      widgetType: column.widgetType,
      parsedDetailSettings,
      refTable,
      refColumn,
      dispColumn,
      "column.referenceTable": column.referenceTable,
    });
    
    if (refTable) {
      componentConfig.entityTable = refTable;
      componentConfig.entityValueColumn = refColumn;
      componentConfig.entityLabelColumn = dispColumn;
    }
  }

  // 카테고리 타입인 경우 추가 설정
  if (column.widgetType === "category") {
    componentConfig.searchable = true;
  }

  // select 타입인 경우: 해당 테이블의 해당 컬럼에서 DISTINCT 값 조회
  if (column.widgetType === "select" || column.inputType === "select") {
    componentConfig.source = "select"; // DISTINCT 조회 모드
    componentConfig.searchable = true;
  }

  return {
    componentType: mapping.componentType,
    componentConfig,
  };
}

/**
 * 컴포넌트 ID를 웹타입으로 역변환 (필요한 경우)
 */
export function getWebTypeFromComponentId(componentId: string): string {
  const entry = Object.entries(WEB_TYPE_COMPONENT_MAPPING).find(([_, id]) => id === componentId);
  return entry ? entry[0] : "text";
}

/**
 * 지원되는 모든 웹타입 목록 조회
 */
export function getSupportedWebTypes(): string[] {
  return Object.keys(WEB_TYPE_V2_MAPPING);
}

/**
 * 지원되는 모든 V2 컴포넌트 ID 목록 조회
 */
export function getSupportedComponentIds(): string[] {
  return [...new Set(Object.values(WEB_TYPE_V2_MAPPING).map((m) => m.componentType))];
}

/**
 * 매핑 정보 조회
 */
export function getWebTypeMappings(): WebTypeMapping[] {
  return Object.entries(WEB_TYPE_V2_MAPPING).map(([webType, mapping]) => ({
    web_type: webType,
    componentId: mapping.componentType,
    description: `${webType} → ${mapping.componentType}`,
  }));
}
