import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

/**
 * 백엔드 JSONB(::text) 응답이 String 으로 올 때 안전하게 array 로 변환.
 * INVYONE 백엔드의 모든 ::text AS jsonb 컬럼이 가끔 미파싱 String 으로 옵니다.
 */
export const safeArray = <T = unknown>(v: unknown): T[] => {
  if (Array.isArray(v)) return v as T[];
  if (typeof v === "string") {
    try {
      const p = JSON.parse(v);
      return Array.isArray(p) ? (p as T[]) : [];
    } catch {
      return [];
    }
  }
  return [];
};

/**
 * JSONB string → object 안전 변환. array/null/undefined → 빈 객체.
 */
export const safeObject = <T extends Record<string, unknown> = Record<string, unknown>>(v: unknown): T => {
  if (v && typeof v === "object" && !Array.isArray(v)) return v as T;
  if (typeof v === "string") {
    try {
      const p = JSON.parse(v);
      return p && typeof p === "object" && !Array.isArray(p) ? (p as T) : ({} as T);
    } catch {
      return {} as T;
    }
  }
  return {} as T;
};

/**
 * 파일 크기를 사람이 읽기 쉬운 형태로 포맷팅
 */
export function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
