/**
 * DB 타입 → 웹 타입 자동 매핑 유틸리티
 *
 * 백엔드의 v2-web-types.ts와 동기화된 매핑 로직을 제공합니다.
 * 테이블 정보를 불러올 때 DB 타입을 적절한 웹 타입으로 자동 변환합니다.
 */

import { WebType } from "@/types";

/**
 * PostgreSQL DB 타입 → 웹 타입 매핑 테이블
 * (백엔드 v2-web-types.ts와 동기화됨)
 */
export const DB_TYPE_TO_WEB_TYPE: Record<string, WebType> = {
  // 텍스트 타입
  "character varying": "text",
  varchar: "text",
  text: "textarea",
  char: "text",

  // 숫자 타입
  integer: "number",
  bigint: "number",
  smallint: "number",
  serial: "number",
  bigserial: "number",
  numeric: "decimal",
  decimal: "decimal",
  real: "decimal",
  "double precision": "decimal",
  float: "decimal",
  double: "decimal",

  // 날짜/시간 타입
  date: "date",
  timestamp: "datetime",
  "timestamp with time zone": "datetime",
  "timestamp without time zone": "datetime",
  datetime: "datetime",
  time: "datetime",
  "time with time zone": "datetime",
  "time without time zone": "datetime",

  // 불린 타입
  boolean: "checkbox",
  bool: "checkbox",

  // JSON 타입 (텍스트로 처리)
  json: "textarea",
  jsonb: "textarea",

  // 배열 타입 (텍스트로 처리)
  ARRAY: "textarea",

  // UUID 타입
  uuid: "text",
};

/**
 * 컬럼명 기반 스마트 웹 타입 추론 규칙
 */
export const COLUMN_NAME_TO_WEB_TYPE: Record<string, WebType> = {
  // 이미지 관련
  image: "image",
  img: "image",
  picture: "image",
  photo: "image",
  thumbnail: "image",
  avatar: "image",
  icon: "image",
  logo: "image",
  
  // 이메일 관련
  email: "email",
  mail: "email",
  e_mail: "email",

  // 전화번호 관련
  phone: "tel",
  tel: "tel",
  telephone: "tel",
  mobile: "tel",
  cellphone: "tel",

  // URL 관련
  url: "text",
  link: "text",
  website: "text",
  homepage: "text",

  // 비밀번호 관련
  password: "text",
  pwd: "text",
  pass: "text",
  passwd: "text",

  // 파일 관련
  file: "file",
  attach: "file",
  attachment: "file",
  upload: "file",
  document: "file",
  doc: "file",
  docs: "file",
  image: "file",
  img: "file",
  photo: "file",
  picture: "file",
  media: "file",

  // 코드 관련 (선택박스로 처리)
  code: "code",
  status: "code",
  state: "code",
  category: "code",
  type: "code",

  // 긴 텍스트 관련
  description: "textarea",
  desc: "textarea",
  content: "textarea",
  comment: "textarea",
  note: "textarea",
  memo: "textarea",
  remark: "textarea",
  detail: "textarea",
};

/**
 * 컬럼 정보를 기반으로 최적의 웹 타입을 자동 추론합니다.
 *
 * @param dataType PostgreSQL 데이터 타입 (예: "integer", "varchar", "timestamp")
 * @param columnName 컬럼명 (스마트 추론용)
 * @returns 추론된 웹 타입
 */
export function inferWebTypeFromColumn(dataType: string, columnName: string = ""): WebType {
  const type = dataType.toLowerCase();
  const name = columnName.toLowerCase();

  console.log("🔍 웹타입 자동 추론:", {
    dataType,
    columnName,
    normalizedType: type,
    normalizedName: name,
  });

  // 1. 정확한 DB 타입 매칭 우선
  if (DB_TYPE_TO_WEB_TYPE[type]) {
    console.log(`✅ 정확한 매핑: ${type} → ${DB_TYPE_TO_WEB_TYPE[type]}`);
    return DB_TYPE_TO_WEB_TYPE[type];
  }

  // 2. 부분 문자열 매칭 (PostgreSQL 타입 변형 대응)
  for (const [dbType, webType] of Object.entries(DB_TYPE_TO_WEB_TYPE)) {
    if (type.includes(dbType.toLowerCase()) || dbType.toLowerCase().includes(type)) {
      console.log(`✅ 부분 매핑: ${type} → ${webType} (기준: ${dbType})`);
      return webType;
    }
  }

  // 3. 추가 정밀 매핑 (일반적인 패턴)
  if (type.includes("int") && !type.includes("point")) {
    console.log(`✅ 패턴 매핑: ${type} → number (정수 패턴)`);
    return "number";
  }
  if (type.includes("numeric") || type.includes("decimal")) {
    console.log(`✅ 패턴 매핑: ${type} → decimal (실수 패턴)`);
    return "decimal";
  }
  if (type.includes("timestamp") || type.includes("datetime")) {
    console.log(`✅ 패턴 매핑: ${type} → datetime (타임스탬프 패턴)`);
    return "datetime";
  }
  if (type.includes("date")) {
    console.log(`✅ 패턴 매핑: ${type} → date (날짜 패턴)`);
    return "date";
  }
  if (type.includes("time")) {
    console.log(`✅ 패턴 매핑: ${type} → datetime (시간 패턴)`);
    return "datetime";
  }
  if (type.includes("bool")) {
    console.log(`✅ 패턴 매핑: ${type} → checkbox (불린 패턴)`);
    return "checkbox";
  }

  // 4. 컬럼명 기반 스마트 추론
  for (const [namePattern, webType] of Object.entries(COLUMN_NAME_TO_WEB_TYPE)) {
    if (name.includes(namePattern)) {
      console.log(`✅ 컬럼명 기반 매핑: ${columnName} → ${webType} (패턴: ${namePattern})`);
      return webType;
    }
  }

  // 5. 텍스트 타입 세분화
  if (type.includes("char") || type.includes("varchar") || type.includes("text")) {
    const webType = type.includes("text") ? "textarea" : "text";
    console.log(`✅ 텍스트 타입 매핑: ${type} → ${webType}`);
    return webType;
  }

  // 6. 최종 기본값
  console.log(`⚠️ 기본값 사용: ${type} → text (매핑 규칙 없음)`);
  return "text";
}

/**
 * 웹 타입이 DB 타입과 호환되는지 확인합니다.
 *
 * @param webType 설정된 웹 타입
 * @param dbType DB 데이터 타입
 * @returns 호환성 검사 결과
 */
export function checkWebTypeCompatibility(
  webType: WebType,
  dbType: string,
): {
  compatible: boolean;
  risk: "none" | "low" | "medium" | "high";
  warning?: string;
} {
  const normalizedDbType = dbType.toLowerCase();
  const recommendedWebType = inferWebTypeFromColumn(dbType);

  // 완전 호환
  if (webType === recommendedWebType) {
    return { compatible: true, risk: "none" };
  }

  // 위험도별 분류
  const incompatiblePairs: Record<string, { risk: "low" | "medium" | "high"; warning: string }> = {
    // 높은 위험: 데이터 손실 가능성 높음
    "text-integer": {
      risk: "high",
      warning: "텍스트 입력에서 정수 DB로 저장 시 숫자가 아닌 데이터는 손실됩니다.",
    },
    "text-numeric": {
      risk: "high",
      warning: "텍스트 입력에서 숫자 DB로 저장 시 숫자가 아닌 데이터는 손실됩니다.",
    },
    "text-boolean": {
      risk: "high",
      warning: "텍스트 입력에서 불린 DB로 저장 시 예상치 못한 변환이 발생할 수 있습니다.",
    },

    // 중간 위험: 일부 데이터 손실 또는 형식 문제
    "number-varchar": {
      risk: "medium",
      warning: "숫자 입력이 텍스트로 저장되어 숫자 연산에 제한이 있을 수 있습니다.",
    },
    "date-varchar": {
      risk: "medium",
      warning: "날짜 입력이 텍스트로 저장되어 날짜 연산에 제한이 있을 수 있습니다.",
    },

    // 낮은 위험: 호환 가능하지만 최적이 아님
    "textarea-varchar": {
      risk: "low",
      warning: "긴 텍스트 입력이 짧은 텍스트 필드에 저장될 수 있습니다.",
    },
    "text-varchar": {
      risk: "low",
      warning: "일반적으로 호환되지만 길이 제한에 주의하세요.",
    },
  };

  // DB 타입 정규화
  let normalizedPair = "";
  if (normalizedDbType.includes("int") || normalizedDbType.includes("serial")) {
    normalizedPair = `${webType}-integer`;
  } else if (normalizedDbType.includes("numeric") || normalizedDbType.includes("decimal")) {
    normalizedPair = `${webType}-numeric`;
  } else if (normalizedDbType.includes("bool")) {
    normalizedPair = `${webType}-boolean`;
  } else if (normalizedDbType.includes("varchar") || normalizedDbType.includes("char")) {
    normalizedPair = `${webType}-varchar`;
  } else if (normalizedDbType.includes("text")) {
    normalizedPair = `${webType}-text`;
  } else if (normalizedDbType.includes("date") || normalizedDbType.includes("timestamp")) {
    normalizedPair = `${webType}-date`;
  }

  const incompatibility = incompatiblePairs[normalizedPair];
  if (incompatibility) {
    return {
      compatible: false,
      risk: incompatibility.risk,
      warning: incompatibility.warning,
    };
  }

  // 알려지지 않은 조합은 중간 위험으로 처리
  return {
    compatible: false,
    risk: "medium",
    warning: `웹 타입 '${webType}'와 DB 타입 '${dbType}'의 호환성을 확인해주세요.`,
  };
}

/**
 * 테이블의 모든 컬럼에 대해 자동 웹 타입 매핑을 수행합니다.
 */
export function autoMapTableColumns(
  columns: Array<{ columnName: string; dataType: string }>,
): Array<{ columnName: string; dataType: string; recommendedWebType: WebType; confidence: "high" | "medium" | "low" }> {
  return columns.map((column) => {
    const recommendedWebType = inferWebTypeFromColumn(column.dataType, column.columnName);

    // 신뢰도 계산
    let confidence: "high" | "medium" | "low" = "medium";

    // 정확한 매핑이 있으면 높은 신뢰도
    if (DB_TYPE_TO_WEB_TYPE[column.dataType.toLowerCase()]) {
      confidence = "high";
    }
    // 컬럼명 기반 매핑이 있으면 높은 신뢰도
    else if (
      Object.keys(COLUMN_NAME_TO_WEB_TYPE).some((pattern) => column.columnName.toLowerCase().includes(pattern))
    ) {
      confidence = "high";
    }
    // 기본값을 사용한 경우 낮은 신뢰도
    else if (recommendedWebType === "text") {
      confidence = "low";
    }

    return {
      ...column,
      recommendedWebType,
      confidence,
    };
  });
}
