// src/utils/dataHelpers.js

/**
 * @fileoverview webOS TV 데이터 처리 유틸리티 함수들
 * 
 * Chromium68 기반 구형 webOS TV 호환성을 위해 Optional Chaining(?.) 대신 
 * lodash를 사용하여 안전한 객체 속성 접근을 제공합니다.
 * 
 * Optional Chaining은 Chrome 80+에서만 지원되므로, 
 * Chromium68 환경에서는 문법 오류가 발생할 수 있습니다.
 * 
 * @author Your Team
 * @since 2.0.0
 * @requires lodash
 */

import { get, isEmpty, isArray } from 'lodash';

/**
 * 객체의 중첩된 속성에 안전하게 접근합니다.
 * Optional Chaining(obj?.prop?.nested) 대신 사용하는 호환성 함수입니다.
 * 
 * @param {Object|Array|null|undefined} obj - 접근할 객체
 * @param {string|Array} path - 접근할 속성 경로 (점 표기법 또는 배열)
 * @param {*} [defaultValue=null] - 값이 없을 때 반환할 기본값
 * @returns {*} 찾은 값 또는 기본값
 * 
 * @example
 * // 기존 Optional Chaining 방식 (Chromium68에서 작동 안함)
 * // const city = user?.profile?.address?.city;
 * 
 * // 호환성을 위한 새로운 방식
 * const user = { profile: { address: { city: 'Seoul' } } };
 * const city = safeGet(user, 'profile.address.city'); // 'Seoul'
 * const country = safeGet(user, 'profile.address.country', 'Unknown'); // 'Unknown'
 * 
 * // 배열 접근
 * const items = [{ name: 'Apple' }, { name: 'Banana' }];
 * const firstItem = safeGet(items, '[0].name'); // 'Apple'
 * const thirdItem = safeGet(items, '[2].name', 'Not Found'); // 'Not Found'
 * 
 * // webOS API 응답 처리
 * const deviceInfo = safeGet(webOSResponse, 'device.modelName', 'Unknown TV');
 */
export const safeGet = (obj, path, defaultValue = null) => 
  get(obj, path, defaultValue);

/**
 * 데이터가 유효한 배열인지 확인합니다.
 * API 응답이나 상태 데이터가 렌더링 가능한 배열 형태인지 검증할 때 사용합니다.
 * 
 * @param {*} data - 검증할 데이터
 * @returns {boolean} 유효한 배열이면 true, 아니면 false
 * 
 * @example
 * // API 응답 검증
 * const apiResponse = { data: { products: [] } };
 * const products = safeGet(apiResponse, 'data.products', []);
 * 
 * if (hasValidData(products)) {
 *   // 안전하게 배열 렌더링
 *   return products.map(product => <ProductCard key={product.id} {...product} />);
 * } else {
 *   return <EmptyState message="상품이 없습니다" />;
 * }
 * 
 * // 다양한 케이스 테스트
 * hasValidData([1, 2, 3]);     // true
 * hasValidData([]);            // false (빈 배열)
 * hasValidData(null);          // false
 * hasValidData(undefined);     // false
 * hasValidData({});            // false (객체)
 * hasValidData('string');      // false (문자열)
 */
export const hasValidData = (data) => 
  !isEmpty(data) && isArray(data);

/**
 * API 응답에서 데이터 부분을 안전하게 추출합니다.
 * 일반적인 API 응답 구조에서 실제 데이터 객체를 가져올 때 사용합니다.
 * 
 * @param {Object} response - API 응답 객체
 * @param {string} [dataPath='data'] - 데이터가 위치한 경로
 * @returns {Object} 추출된 데이터 객체 (기본값: 빈 객체)
 * 
 * @example
 * // 일반적인 API 응답 구조
 * const apiResponse = {
 *   status: 'success',
 *   data: {
 *     products: [...],
 *     pagination: { ... },
 *     metadata: { ... }
 *   }
 * };
 * 
 * // 데이터 추출
 * const responseData = getApiData(apiResponse); // { products: [...], pagination: {...}, ... }
 * const products = safeGet(responseData, 'products', []);
 * 
 * // 커스텀 경로 지정
 * const nestedResponse = {
 *   result: {
 *     payload: {
 *       items: [...]
 *     }
 *   }
 * };
 * const payloadData = getApiData(nestedResponse, 'result.payload'); // { items: [...] }
 * 
 * // webOS 서비스 응답 처리
 * const webOSServiceResponse = {
 *   returnValue: true,
 *   response: {
 *     deviceList: [...]
 *   }
 * };
 * const serviceData = getApiData(webOSServiceResponse, 'response'); // { deviceList: [...] }
 * 
 * // 오류나 빈 응답 처리
 * const emptyResponse = null;
 * const safeData = getApiData(emptyResponse); // {} (빈 객체)
 */
export const getApiData = (response, dataPath = 'data') => 
  get(response, dataPath, {});

/**
 * 추가 유틸리티 함수들 - webOS TV 환경에서 자주 사용되는 패턴들
 */

/**
 * 객체에 특정 속성이 존재하는지 안전하게 확인합니다.
 * 
 * @param {Object} obj - 확인할 객체
 * @param {string} path - 확인할 속성 경로
 * @returns {boolean} 속성이 존재하면 true
 * 
 * @example
 * const settings = { user: { preferences: { theme: 'dark' } } };
 * 
 * // 기존 방식 (Chromium68에서 위험)
 * // const hasTheme = settings?.user?.preferences?.theme !== undefined;
 * 
 * // 호환성 방식
 * const hasTheme = safeHas(settings, 'user.preferences.theme'); // true
 * const hasLanguage = safeHas(settings, 'user.preferences.language'); // false
 */
export const safeHas = (obj, path) => {
  return get(obj, path) !== undefined;
};

/**
 * 배열의 첫 번째 요소를 안전하게 가져옵니다.
 * 
 * @param {Array} array - 대상 배열
 * @param {*} [defaultValue=null] - 기본값
 * @returns {*} 첫 번째 요소 또는 기본값
 * 
 * @example
 * const products = [{ id: 1, name: 'TV' }, { id: 2, name: 'Phone' }];
 * const firstProduct = safeFirst(products); // { id: 1, name: 'TV' }
 * 
 * const emptyArray = [];
 * const firstItem = safeFirst(emptyArray, { id: 0, name: 'Default' }); // { id: 0, name: 'Default' }
 */
export const safeFirst = (array, defaultValue = null) => {
  return hasValidData(array) ? array[0] : defaultValue;
};

/**
 * 문자열이 비어있지 않은지 확인합니다.
 * 
 * @param {string} str - 확인할 문자열
 * @returns {boolean} 유효한 문자열이면 true
 * 
 * @example
 * isValidString('Hello'); // true
 * isValidString('');      // false
 * isValidString(null);    // false
 * isValidString(undefined); // false
 * isValidString('   ');   // false (공백만 있는 경우)
 */
export const isValidString = (str) => {
  return typeof str === 'string' && str.trim().length > 0;
};

// 사용 예시를 위한 실제 webOS TV 컴포넌트에서의 활용
/**
 * @example 실제 컴포넌트에서의 사용법
 * 
 * import { safeGet, hasValidData, getApiData } from '../utils/dataHelpers';
 * 
 * const ProductList = ({ apiResponse }) => {
 *   // API 응답에서 안전하게 데이터 추출
 *   const responseData = getApiData(apiResponse);
 *   const products = safeGet(responseData, 'products', []);
 *   const totalCount = safeGet(responseData, 'pagination.total', 0);
 *   
 *   // 데이터 유효성 검사
 *   if (!hasValidData(products)) {
 *     return <div>상품이 없습니다.</div>;
 *   }
 *   
 *   return (
 *     <div>
 *       <h2>상품 목록 ({totalCount}개)</h2>
 *       {products.map(product => {
 *         const productName = safeGet(product, 'name', '이름 없음');
 *         const productPrice = safeGet(product, 'price.amount', 0);
 *         const productImage = safeGet(product, 'images[0].url', '/default-image.jpg');
 *         
 *         return (
 *           <div key={product.id}>
 *             <img src={productImage} alt={productName} />
 *             <h3>{productName}</h3>
 *             <p>{productPrice}원</p>
 *           </div>
 *         );
 *       })}
 *     </div>
 *   );
 * };
 */