/**
 * 🗄️ 테이블 타입관리 시스템 전용 타입 정의
 *
 * 데이터베이스 테이블 스키마, 컬럼 타입, 웹타입 매핑 등 테이블 관리에서만 사용하는 타입들
 */

import {
  DynamicWebType,
  CompanyCode,
  ActiveStatus,
  TimestampFields,
  BaseApiResponse,
  PaginatedResponse,
  ConditionOperator,
} from "./v2-core";

// ===== 기본 테이블 정보 =====

/**
 * 테이블 정보
 */
export interface TableInfo {
  tableName: string;
  displayName: string;
  description: string;
  columnCount: number;
  companyCode?: CompanyCode;
  isActive?: ActiveStatus;
  createdDate?: Date;
  updatedDate?: Date;
}

/**
 * 통합된 컬럼 정보 (프론트엔드/백엔드 호환)
 */
export interface V2ColumnInfo {
  // 기본 정보
  tableName: string;
  columnName: string;
  displayName: string;

  // 데이터 타입
  dataType: string; // DB 데이터 타입 (varchar, integer, timestamp 등)
  dbType: string; // DB 내부 타입
  webType: DynamicWebType; // 웹 입력 타입 (text, number, date 등)

  // 입력 설정
  inputType: "direct" | "auto";
  input_type?: string; // 🎯 데이터베이스의 input_type 필드 (entity, text, number 등)
  detailSettings?: Record<string, unknown>; // JSON 파싱된 객체
  description?: string;

  // 제약 조건
  isNullable: boolean; // Y/N → boolean 변환
  isPrimaryKey: boolean;
  defaultValue?: string;

  // 크기 제한
  maxLength?: number;
  numericPrecision?: number;
  numericScale?: number;

  // 표시 옵션
  isVisible?: boolean;
  displayOrder?: number;

  // 참조 관계
  codeCategory?: string;
  codeValue?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;

  // 메타데이터
  companyCode?: CompanyCode;
  createdDate?: Date;
  updatedDate?: Date;
}

/**
 * 백엔드 호환용 컬럼 타입 정보 (기존 ColumnTypeInfo)
 */
export interface ColumnTypeInfo {
  tableName?: string;
  columnName: string;
  displayName: string;
  dataType: string;
  dbType: string;
  webType: string; // string 타입 (백엔드 호환)
  inputType?: "direct" | "auto";
  detailSettings: string; // JSON 문자열
  description: string; // 필수 필드
  isNullable: string; // Y/N 문자열
  isPrimaryKey: boolean;
  defaultValue?: string;
  maxLength?: number;
  numericPrecision?: number;
  numericScale?: number;
  codeCategory?: string;
  codeValue?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
  displayOrder?: number;
  isVisible?: boolean;
}

/**
 * 컬럼 설정 (업데이트용)
 */
export interface ColumnSettings {
  columnName?: string; // 컬럼명 (업데이트 시 필요)
  columnLabel: string; // 컬럼 표시명
  webType: string; // 웹 입력 타입
  detailSettings: string; // 상세 설정 (JSON 문자열)
  codeCategory: string; // 코드 카테고리
  codeValue: string; // 코드 값
  referenceTable: string; // 참조 테이블
  referenceColumn: string; // 참조 컬럼
  displayColumn?: string; // 표시할 컬럼명
  displayOrder?: number; // 표시 순서
  isVisible?: boolean; // 표시 여부
}

// ===== 웹타입 표준 정의 =====

/**
 * 웹타입 표준 정보 (DB의 web_type_standards 테이블)
 */
export interface WebTypeStandard extends TimestampFields {
  web_type: string;
  type_name: string;
  type_name_eng?: string;
  description?: string;
  category: string;
  default_config?: unknown; // JSON
  validation_rules?: unknown; // JSON
  default_style?: unknown; // JSON
  input_properties?: unknown; // JSON
  sort_order?: number;
  is_active: ActiveStatus;
  component_name?: string;
  config_panel?: string;
}

/**
 * 프론트엔드용 웹타입 정의 (WebTypeStandard 변환)
 */
export interface WebTypeDefinition {
  webType: string; // web_type 필드
  typeName: string; // type_name 필드
  typeNameEng?: string; // type_name_eng 필드
  description?: string;
  category: string;
  defaultConfig: Record<string, unknown>; // JSON 타입 매핑
  validationRules?: Record<string, unknown>; // JSON 타입 매핑
  defaultStyle?: Record<string, unknown>; // JSON 타입 매핑
  inputProperties?: Record<string, unknown>; // JSON 타입 매핑
  componentName?: string; // component_name 필드
  configPanel?: string; // config_panel 필드
  sortOrder?: number; // sort_order 필드
  isActive: boolean; // is_active Y/N → boolean 변환
}

// ===== 테이블 라벨 관리 =====

/**
 * 테이블 라벨
 */
export interface TableLabels extends TimestampFields {
  tableName: string;
  tableLabel?: string;
  description?: string;
  companyCode?: CompanyCode;
}

/**
 * 컬럼 라벨
 */
export interface ColumnLabels extends TimestampFields {
  id?: number;
  tableName: string;
  columnName: string;
  columnLabel?: string;
  webType?: string;
  detailSettings?: string;
  description?: string;
  displayOrder?: number;
  isVisible?: boolean;
  codeCategory?: string;
  codeValue?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
  companyCode?: CompanyCode;
}

// ===== 엔티티 조인 관리 =====

/**
 * 엔티티 조인 설정
 */
export interface EntityJoinConfig {
  sourceTable: string; // 원본 테이블 (예: companies)
  sourceColumn: string; // 원본 컬럼 (예: writer)
  referenceTable: string; // 참조 테이블 (예: user_info)
  referenceColumn: string; // 조인 키 (예: user_id)
  displayColumn: string; // 표시할 값 (예: user_name)
  aliasColumn: string; // 결과 컬럼명 (예: writer_name)
  companyCode?: CompanyCode;
}

/**
 * 엔티티 조인 응답
 */
export interface EntityJoinResponse {
  data: Record<string, unknown>[];
  total: number;
  page: number;
  size: number;
  totalPages: number;
  entityJoinInfo?: {
    joinConfigs: EntityJoinConfig[];
    strategy: "full_join" | "cache_lookup" | "hybrid";
    performance: {
      queryTime: number;
      cacheHitRate?: number;
      hybridBreakdown?: {
        dbJoins: number;
        cacheJoins: number;
      };
    };
  };
}

/**
 * 배치 조회 요청
 */
export interface BatchLookupRequest {
  table: string;
  key: string;
  displayColumn: string;
  companyCode?: CompanyCode;
}

/**
 * 배치 조회 응답
 */
export interface BatchLookupResponse {
  key: string;
  value: unknown;
}

// ===== 테이블 관계 관리 =====

/**
 * 테이블 관계 정의
 */
export interface TableRelationship extends TimestampFields {
  relationship_id?: number;
  relationship_name?: string;
  from_table_name?: string;
  from_column_name?: string;
  to_table_name?: string;
  to_column_name?: string;
  relationship_type?: string;
  connection_type?: string;
  company_code?: CompanyCode;
  settings?: unknown; // JSON
  is_active?: ActiveStatus;
  diagram_id?: number;
}

/**
 * 데이터 관계 브릿지
 */
export interface DataRelationshipBridge extends TimestampFields {
  bridge_id?: number;
  relationship_id?: number;
  from_table_name: string;
  from_column_name: string;
  to_table_name: string;
  to_column_name: string;
  connection_type: string;
  company_code: CompanyCode;
  is_active?: ActiveStatus;
  bridge_data?: unknown; // JSON
  from_key_value?: string;
  from_record_id?: string;
  to_key_value?: string;
  to_record_id?: string;
}

// ===== 컬럼 웹타입 설정 =====

/**
 * 컬럼 웹타입 설정
 */
export interface ColumnWebTypeSetting {
  tableName: string;
  columnName: string;
  webType: DynamicWebType;
  detailSettings?: Record<string, unknown>;
  codeCategory?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
  companyCode?: CompanyCode;
}

// ===== API 응답 타입들 =====

/**
 * 테이블 목록 응답
 */
export interface TableListResponse extends BaseApiResponse<TableInfo[]> {}

/**
 * 컬럼 목록 응답
 */
export interface ColumnListResponse extends BaseApiResponse<V2ColumnInfo[]> {}

/**
 * 컬럼 타입 정보 응답 (백엔드 호환)
 */
export interface ColumnTypeInfoResponse extends BaseApiResponse<ColumnTypeInfo[]> {}

/**
 * 컬럼 설정 응답
 */
export interface ColumnSettingsResponse extends BaseApiResponse<void> {}

/**
 * 웹타입 표준 목록 응답
 */
export interface WebTypeStandardListResponse extends BaseApiResponse<WebTypeStandard[]> {}

/**
 * 웹타입 정의 목록 응답
 */
export interface WebTypeDefinitionListResponse extends BaseApiResponse<WebTypeDefinition[]> {}

/**
 * 테이블 데이터 조회 응답
 */
export interface TableDataResponse extends PaginatedResponse<Record<string, unknown>> {}

// ===== 웹타입 옵션 상수 =====

/**
 * 웹타입 옵션 (기존 호환성 유지)
 */
export const WEB_TYPE_OPTIONS = [
  { value: "text", label: "text", description: "일반 텍스트 입력" },
  { value: "number", label: "number", description: "숫자 입력" },
  { value: "decimal", label: "decimal", description: "소수 입력" },
  { value: "date", label: "date", description: "날짜 선택기" },
  { value: "datetime", label: "datetime", description: "날짜시간 선택기" },
  { value: "code", label: "code", description: "코드 선택 (공통코드 지정)" },
  { value: "entity", label: "entity", description: "엔티티 참조 (참조테이블 지정)" },
  { value: "textarea", label: "textarea", description: "여러 줄 텍스트" },
  { value: "select", label: "select", description: "드롭다운 선택" },
  { value: "dropdown", label: "dropdown", description: "드롭다운 선택" },
  { value: "checkbox", label: "checkbox", description: "체크박스" },
  { value: "boolean", label: "boolean", description: "참/거짓" },
  { value: "radio", label: "radio", description: "라디오 버튼" },
  { value: "file", label: "file", description: "파일 업로드" },
  { value: "email", label: "email", description: "이메일 입력" },
  { value: "tel", label: "tel", description: "전화번호 입력" },
  { value: "url", label: "url", description: "URL 입력" },
  { value: "checkbox-group", label: "checkbox-group", description: "체크박스 그룹" },
  { value: "radio-horizontal", label: "radio-horizontal", description: "가로 라디오" },
  { value: "radio-vertical", label: "radio-vertical", description: "세로 라디오" },
] as const;

/**
 * 웹타입 (기존 호환성)
 */
export type WebType = (typeof WEB_TYPE_OPTIONS)[number]["value"];

// ===== 변환 유틸리티 함수들 =====

/**
 * WebTypeStandard를 WebTypeDefinition으로 변환
 */
export const mapWebTypeStandardToDefinition = (standard: WebTypeStandard): WebTypeDefinition => ({
  webType: standard.web_type,
  typeName: standard.type_name,
  typeNameEng: standard.type_name_eng || undefined,
  description: standard.description || undefined,
  category: standard.category || "input",
  defaultConfig: (standard.default_config as Record<string, unknown>) || {},
  validationRules: (standard.validation_rules as Record<string, unknown>) || undefined,
  defaultStyle: (standard.default_style as Record<string, unknown>) || undefined,
  inputProperties: (standard.input_properties as Record<string, unknown>) || undefined,
  componentName: standard.component_name || undefined,
  configPanel: standard.config_panel || undefined,
  sortOrder: standard.sort_order || 0,
  isActive: standard.is_active === "Y",
});

/**
 * ColumnTypeInfo를 V2ColumnInfo로 변환
 */
export const mapColumnTypeInfoToV2 = (columnInfo: ColumnTypeInfo): V2ColumnInfo => ({
  tableName: columnInfo.tableName || "",
  columnName: columnInfo.columnName,
  displayName: columnInfo.displayName,
  dataType: columnInfo.dataType,
  dbType: columnInfo.dbType,
  webType: columnInfo.webType,
  inputType: columnInfo.inputType || "direct",
  detailSettings: columnInfo.detailSettings ? JSON.parse(columnInfo.detailSettings) : undefined,
  description: columnInfo.description,
  isNullable: columnInfo.isNullable === "Y",
  isPrimaryKey: columnInfo.isPrimaryKey,
  defaultValue: columnInfo.defaultValue,
  maxLength: columnInfo.maxLength,
  numericPrecision: columnInfo.numericPrecision,
  numericScale: columnInfo.numericScale,
  isVisible: columnInfo.isVisible,
  displayOrder: columnInfo.displayOrder,
  codeCategory: columnInfo.codeCategory,
  codeValue: columnInfo.codeValue,
  referenceTable: columnInfo.referenceTable,
  referenceColumn: columnInfo.referenceColumn,
  displayColumn: columnInfo.displayColumn,
});

/**
 * V2ColumnInfo를 ColumnTypeInfo로 변환
 */
export const mapV2ToColumnTypeInfo = (v2: V2ColumnInfo): ColumnTypeInfo => ({
  tableName: v2.tableName,
  columnName: v2.columnName,
  displayName: v2.displayName,
  dataType: v2.dataType,
  dbType: v2.dbType,
  webType: v2.webType,
  inputType: v2.inputType,
  detailSettings: v2.detailSettings ? JSON.stringify(v2.detailSettings) : "{}",
  description: v2.description || "",
  isNullable: v2.isNullable ? "Y" : "N",
  isPrimaryKey: v2.isPrimaryKey,
  defaultValue: v2.defaultValue,
  maxLength: v2.maxLength,
  numericPrecision: v2.numericPrecision,
  numericScale: v2.numericScale,
  isVisible: v2.isVisible,
  displayOrder: v2.displayOrder,
  codeCategory: v2.codeCategory,
  codeValue: v2.codeValue,
  referenceTable: v2.referenceTable,
  referenceColumn: v2.referenceColumn,
  displayColumn: v2.displayColumn,
});

// ===== 타입 가드 함수들 =====

/**
 * 웹타입이 참조 타입인지 확인
 */
export const isReferenceWebType = (webType: string): boolean => {
  return ["code", "entity"].includes(webType);
};

/**
 * 웹타입이 숫자 타입인지 확인
 */
export const isNumericWebType = (webType: string): boolean => {
  return ["number", "decimal"].includes(webType);
};

/**
 * 웹타입이 날짜 타입인지 확인
 */
export const isDateWebType = (webType: string): boolean => {
  return ["date", "datetime"].includes(webType);
};

/**
 * 웹타입이 선택 타입인지 확인
 */
export const isSelectWebType = (webType: string): boolean => {
  return ["select", "dropdown", "radio", "checkbox", "boolean"].includes(webType);
};

/**
 * 컬럼이 필수 필드인지 확인
 */
export const isRequiredColumn = (column: V2ColumnInfo): boolean => {
  return !column.isNullable || column.isPrimaryKey;
};

/**
 * 컬럼이 시스템 컬럼인지 확인
 */
export const isSystemColumn = (columnName: string): boolean => {
  const systemColumns = [
    "created_date",
    "updated_date",
    "created_by",
    "updated_by",
    "is_active",
    "company_code",
    "version",
    "id",
  ];
  return systemColumns.includes(columnName.toLowerCase());
};
