
import { Transaction } from '@/components/TransactionCard';
import { CATEGORY_TITLE_SUGGESTIONS } from '@/constants/categoryIcons';

// 지출 제목 사용 빈도를 저장하는 로컬 스토리지 키
const TITLE_PREFERENCES_KEY = 'userTitlePreferences';

// 기본 분석 대상 트랜잭션 수
const DEFAULT_ANALYSIS_COUNT = 50;

// 사용자 제목 선호도 타입 정의
export interface TitlePreference {
  count: number;    // 사용 횟수
  lastUsed: string; // 마지막 사용 일시 (ISO 문자열)
}

// 카테고리별 제목 선호도
export interface CategoryTitlePreferences {
  [title: string]: TitlePreference;
}

// 전체 제목 선호도 데이터 구조
export interface UserTitlePreferences {
  음식: CategoryTitlePreferences;
  쇼핑: CategoryTitlePreferences;
  교통: CategoryTitlePreferences;
  기타: CategoryTitlePreferences;
  [key: string]: CategoryTitlePreferences;
}

/**
 * 로컬 스토리지에서 사용자 제목 선호도 데이터 로드
 */
export const loadUserTitlePreferences = (): UserTitlePreferences => {
  try {
    const storedPreferences = localStorage.getItem(TITLE_PREFERENCES_KEY);
    if (storedPreferences) {
      return JSON.parse(storedPreferences);
    }
  } catch (error) {
    console.error('제목 선호도 데이터 로드 중 오류:', error);
  }
  
  // 기본값 반환 - 기본 카테고리 구조 생성
  return {
    음식: {},
    쇼핑: {},
    교통: {},
    기타: {}
  };
};

/**
 * 사용자 제목 선호도 데이터 저장
 */
export const saveUserTitlePreferences = (preferences: UserTitlePreferences): void => {
  try {
    localStorage.setItem(TITLE_PREFERENCES_KEY, JSON.stringify(preferences));
  } catch (error) {
    console.error('제목 선호도 데이터 저장 중 오류:', error);
  }
};

/**
 * 트랜잭션에서 제목 사용 업데이트
 * 새로운 트랜잭션이 추가되거나 수정될 때 호출
 */
export const updateTitleUsage = (transaction: Transaction): void => {
  // 타입이 expense가 아니거나 제목이 없으면 무시
  if (transaction.type !== 'expense' || !transaction.title) return;
  
  const { category, title } = transaction;
  const preferences = loadUserTitlePreferences();
  
  // 해당 카테고리가 없으면 초기화
  if (!preferences[category]) {
    preferences[category] = {};
  }
  
  // 해당 제목이 없으면 초기화
  if (!preferences[category][title]) {
    preferences[category][title] = {
      count: 0,
      lastUsed: new Date().toISOString()
    };
  }
  
  // 카운트 증가 및 마지막 사용 시간 업데이트
  preferences[category][title].count += 1;
  preferences[category][title].lastUsed = new Date().toISOString();
  
  // 저장
  saveUserTitlePreferences(preferences);
};

/**
 * 트랜잭션 목록에서 제목 사용 빈도 분석하여 업데이트
 * 앱 초기화 시 또는 주기적으로 호출하여 최신 데이터 반영
 */
export const analyzeTransactionTitles = (
  transactions: Transaction[], 
  analysisCount: number = DEFAULT_ANALYSIS_COUNT
): void => {
  // 지출 항목만 필터링하고 최신 순으로 정렬
  const recentTransactions = transactions
    .filter(tx => tx.type === 'expense')
    .sort((a, b) => {
      const dateA = a.localTimestamp ? new Date(a.localTimestamp).getTime() : 0;
      const dateB = b.localTimestamp ? new Date(b.localTimestamp).getTime() : 0;
      return dateB - dateA;
    })
    .slice(0, analysisCount); // 최신 N개만 분석
  
  // 선호도 데이터 초기화 (기존 데이터 유지를 원하면 이 부분 제거)
  let preferences: UserTitlePreferences = {
    음식: {},
    쇼핑: {},
    교통: {},
    기타: {}
  };
  
  // 트랜잭션 분석
  recentTransactions.forEach(tx => {
    if (!tx.category || !tx.title) return;
    
    if (!preferences[tx.category]) {
      preferences[tx.category] = {};
    }
    
    if (!preferences[tx.category][tx.title]) {
      preferences[tx.category][tx.title] = {
        count: 0,
        lastUsed: tx.localTimestamp || new Date().toISOString()
      };
    }
    
    preferences[tx.category][tx.title].count += 1;
    
    // 가장 최근 사용일자 업데이트
    if (tx.localTimestamp) {
      preferences[tx.category][tx.title].lastUsed = tx.localTimestamp;
    }
  });
  
  // 저장
  saveUserTitlePreferences(preferences);
};

/**
 * 카테고리별 추천 제목 목록 가져오기
 * 사용자 선호도 + 기본 추천 제목 결합
 */
export const getPersonalizedTitleSuggestions = (category: string): string[] => {
  // 기본 제목 목록
  const defaultSuggestions = CATEGORY_TITLE_SUGGESTIONS[category] || [];
  
  try {
    const preferences = loadUserTitlePreferences();
    const categoryPreferences = preferences[category] || {};
    
    // 사용 횟수 기준으로 정렬된 사용자 정의 제목 목록
    const personalizedTitles = Object.entries(categoryPreferences)
      .sort((a, b) => {
        // 우선 사용 횟수로 정렬 (내림차순)
        const countDiff = b[1].count - a[1].count;
        if (countDiff !== 0) return countDiff;
        
        // 사용 횟수가 같으면 최근 사용일자로 정렬 (내림차순)
        const dateA = new Date(a[1].lastUsed).getTime();
        const dateB = new Date(b[1].lastUsed).getTime();
        return dateB - dateA;
      })
      .map(([title]) => title);
    
    // 사용자 선호 제목에는 없지만 기본 제목에 있는 항목 추가
    const remainingDefaultTitles = defaultSuggestions.filter(
      title => !personalizedTitles.includes(title)
    );
    
    // 최종 개인화된 제목 목록 (선호도 순 + 기본 제목)
    return [...personalizedTitles, ...remainingDefaultTitles];
  } catch (error) {
    console.error('개인화된 제목 목록 생성 중 오류:', error);
    return defaultSuggestions;
  }
};
