/**
 * 백엔드 통합 웹 타입 정의
 * 프론트엔드와 동일한 웹 타입 정의 유지
 */

// 기본 웹 타입 (프론트엔드와 동일)
export type BaseWebType =
  | "text" // 일반 텍스트
  | "number" // 숫자 (정수)
  | "decimal" // 소수점 숫자
  | "date" // 날짜
  | "datetime" // 날짜시간
  | "time" // 시간
  | "textarea" // 여러줄 텍스트
  | "select" // 선택박스
  | "dropdown" // 드롭다운 (select와 동일)
  | "checkbox" // 체크박스
  | "radio" // 라디오버튼
  | "boolean" // 불린값
  | "file" // 파일 업로드
  | "email" // 이메일
  | "tel" // 전화번호
  | "url" // URL
  | "password" // 패스워드
  | "code" // 공통코드 참조
  | "entity" // 엔티티 참조
  | "button"; // 버튼

// 레거시 지원용
export type LegacyWebType = "text_area"; // textarea와 동일

// 전체 웹 타입
export type WebType = BaseWebType | LegacyWebType;

// 동적 웹 타입 (런타임에 DB에서 로드되는 타입 포함)
export type DynamicWebType = WebType | string;

// 웹 타입 매핑 (레거시 지원)
export const WEB_TYPE_MAPPINGS: Record<LegacyWebType, BaseWebType> = {
  text_area: "textarea",
};

// 웹 타입 정규화 함수
export const normalizeWebType = (webType: DynamicWebType): WebType => {
  if (webType in WEB_TYPE_MAPPINGS) {
    return WEB_TYPE_MAPPINGS[webType as LegacyWebType];
  }
  return webType as WebType;
};

// 웹 타입 검증 함수
export const isValidWebType = (webType: string): webType is WebType => {
  return (
    [
      "text",
      "number",
      "decimal",
      "date",
      "datetime",
      "time",
      "textarea",
      "select",
      "dropdown",
      "checkbox",
      "radio",
      "boolean",
      "file",
      "email",
      "tel",
      "url",
      "password",
      "code",
      "entity",
      "button",
      "text_area", // 레거시 지원
    ] as string[]
  ).includes(webType);
};

// DB 타입과 웹 타입 매핑
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",

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

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

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

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

// 웹 타입별 PostgreSQL 타입 변환 규칙
export const WEB_TYPE_TO_POSTGRES_CONVERTER: Record<
  WebType,
  (value: any) => any
> = {
  text: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  number: (value) => {
    if (value === null || value === undefined || value === "") return null;
    const num = parseInt(String(value));
    return isNaN(num) ? null : num;
  },

  decimal: (value) => {
    if (value === null || value === undefined || value === "") return null;
    const num = parseFloat(String(value));
    return isNaN(num) ? null : num;
  },

  date: (value) => {
    if (value === null || value === undefined || value === "") return null;
    const date = new Date(value);
    return isNaN(date.getTime()) ? null : date.toISOString().split("T")[0];
  },

  datetime: (value) => {
    if (value === null || value === undefined || value === "") return null;
    const date = new Date(value);
    return isNaN(date.getTime()) ? null : date.toISOString();
  },

  time: (value) => {
    if (value === null || value === undefined || value === "") return null;
    // 시간 형식 처리 (HH:mm:ss)
    return String(value);
  },

  textarea: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  select: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  dropdown: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  checkbox: (value) => {
    if (value === null || value === undefined) return false;
    if (typeof value === "boolean") return value;
    if (typeof value === "string") {
      return value.toLowerCase() === "true" || value === "1" || value === "Y";
    }
    return Boolean(value);
  },

  radio: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  boolean: (value) => {
    if (value === null || value === undefined) return null;
    if (typeof value === "boolean") return value;
    if (typeof value === "string") {
      return value.toLowerCase() === "true" || value === "1" || value === "Y";
    }
    return Boolean(value);
  },

  file: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  email: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  tel: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  url: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  password: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  code: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  entity: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),

  button: (value) => null, // 버튼은 저장하지 않음

  // 레거시 지원
  text_area: (value) =>
    value === null || value === undefined || value === ""
      ? null
      : String(value),
};

// 웹 타입별 검증 규칙
export const WEB_TYPE_VALIDATION_PATTERNS: Record<WebType, RegExp | null> = {
  text: null,
  number: /^-?\d+$/,
  decimal: /^-?\d+(\.\d+)?$/,
  date: /^\d{4}-\d{2}-\d{2}$/,
  datetime: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/,
  time: /^\d{2}:\d{2}(:\d{2})?$/,
  textarea: null,
  select: null,
  dropdown: null,
  checkbox: null,
  radio: null,
  boolean: null,
  file: null,
  email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
  tel: /^(\d{2,3}-?\d{3,4}-?\d{4}|\d{10,11})$/,
  url: /^https?:\/\/.+/,
  password: null,
  code: null,
  entity: null,
  button: null,
  text_area: null, // 레거시 지원
};

// 업데이트된 웹 타입 옵션 (기존 WEB_TYPE_OPTIONS 대체)
export const V2_WEB_TYPE_OPTIONS = [
  {
    value: "text",
    label: "text",
    description: "일반 텍스트 입력",
    category: "input",
  },
  {
    value: "number",
    label: "number",
    description: "숫자 입력 (정수)",
    category: "input",
  },
  {
    value: "decimal",
    label: "decimal",
    description: "소수점 숫자 입력",
    category: "input",
  },
  {
    value: "date",
    label: "date",
    description: "날짜 선택기",
    category: "input",
  },
  {
    value: "datetime",
    label: "datetime",
    description: "날짜시간 선택기",
    category: "input",
  },
  {
    value: "time",
    label: "time",
    description: "시간 선택기",
    category: "input",
  },
  {
    value: "textarea",
    label: "textarea",
    description: "여러 줄 텍스트",
    category: "input",
  },
  {
    value: "select",
    label: "select",
    description: "선택박스",
    category: "selection",
  },
  {
    value: "dropdown",
    label: "dropdown",
    description: "드롭다운",
    category: "selection",
  },
  {
    value: "checkbox",
    label: "checkbox",
    description: "체크박스",
    category: "selection",
  },
  {
    value: "radio",
    label: "radio",
    description: "라디오 버튼",
    category: "selection",
  },
  {
    value: "boolean",
    label: "boolean",
    description: "불린값 (예/아니오)",
    category: "selection",
  },
  {
    value: "file",
    label: "file",
    description: "파일 업로드",
    category: "upload",
  },
  {
    value: "email",
    label: "email",
    description: "이메일 주소",
    category: "input",
  },
  { value: "tel", label: "tel", description: "전화번호", category: "input" },
  {
    value: "url",
    label: "url",
    description: "웹사이트 주소",
    category: "input",
  },
  {
    value: "password",
    label: "password",
    description: "비밀번호",
    category: "input",
  },
  {
    value: "code",
    label: "code",
    description: "코드 선택 (공통코드)",
    category: "reference",
  },
  {
    value: "entity",
    label: "entity",
    description: "엔티티 참조 (참조테이블)",
    category: "reference",
  },
  { value: "button", label: "button", description: "버튼", category: "action" },
] as const;

// 웹 타입별 기본 설정
export const WEB_TYPE_DEFAULT_CONFIGS: Record<WebType, Record<string, any>> = {
  text: { maxLength: 255, placeholder: "텍스트를 입력하세요" },
  number: { min: 0, max: 2147483647, step: 1 },
  decimal: { min: 0, step: 0.01, decimalPlaces: 2 },
  date: { format: "YYYY-MM-DD" },
  datetime: { format: "YYYY-MM-DD HH:mm:ss", showTime: true },
  time: { format: "HH:mm:ss" },
  textarea: { rows: 4, cols: 50, maxLength: 1000 },
  select: { placeholder: "선택하세요", searchable: false },
  dropdown: { placeholder: "선택하세요", searchable: true },
  checkbox: { defaultChecked: false },
  radio: { inline: false },
  boolean: { trueValue: true, falseValue: false },
  file: { multiple: false, preview: true },
  email: { placeholder: "이메일을 입력하세요" },
  tel: { placeholder: "전화번호를 입력하세요" },
  url: { placeholder: "URL을 입력하세요" },
  password: { placeholder: "비밀번호를 입력하세요" },
  code: { placeholder: "코드를 선택하세요", searchable: true },
  entity: { placeholder: "항목을 선택하세요", searchable: true },
  button: { variant: "default" },
  text_area: { rows: 4, cols: 50, maxLength: 1000 }, // 레거시 지원
};
