
import { BudgetData, Transaction } from './types';
import { format } from 'date-fns';

// 기본 예산 데이터
export const getInitialBudgetData = (): BudgetData => ({
  daily: {
    targetAmount: 0,
    spentAmount: 0,
    remainingAmount: 0
  },
  weekly: {
    targetAmount: 0,
    spentAmount: 0,
    remainingAmount: 0
  },
  monthly: {
    targetAmount: 0,
    spentAmount: 0,
    remainingAmount: 0
  }
});

// 기본 카테고리 예산 값 (수출)
export const DEFAULT_CATEGORY_BUDGETS = {};

// 안전한 스토리지 처리 (수출)
export const safeStorage = {
  setItem: (key: string, value: any) => {
    try {
      localStorage.setItem(key, JSON.stringify(value));
      return true;
    } catch (err) {
      console.error(`스토리지 저장 오류 (${key}):`, err);
      return false;
    }
  },
  getItem: (key: string, defaultValue: any = null) => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : defaultValue;
    } catch (err) {
      console.error(`스토리지 로드 오류 (${key}):`, err);
      return defaultValue;
    }
  }
};

// 예산 데이터 스토리지에서 로드
export const safelyLoadBudgetData = (): BudgetData => {
  try {
    const budgetDataStr = localStorage.getItem('budgetData');
    
    if (budgetDataStr) {
      const parsedData = JSON.parse(budgetDataStr);
      
      // 데이터 구조 검증 (필요한 키가 있는지 확인)
      if (parsedData && 
          typeof parsedData === 'object' && 
          'daily' in parsedData && 
          'weekly' in parsedData && 
          'monthly' in parsedData) {
        return parsedData;
      } else {
        console.warn('저장된 예산 데이터 구조가 유효하지 않습니다. 기본값을 반환합니다.');
      }
    }
  } catch (error) {
    console.error('예산 데이터 로드 중 오류:', error);
  }
  
  // 오류 발생 또는 유효하지 않은 데이터인 경우 기본값 반환
  return getInitialBudgetData();
};

// 지출 금액 계산 함수
export const calculateSpentAmounts = (transactions: Transaction[], budgetData: BudgetData): BudgetData => {
  // 기존 예산 데이터 복사
  const newBudgetData = JSON.parse(JSON.stringify(budgetData));
  
  // 지출 트랜잭션만 필터링
  const expenseTransactions = transactions.filter(t => t.type === 'expense');
  
  // 현재 날짜 정보
  const now = new Date();
  const currentDay = now.getDate();
  const currentMonth = now.getMonth();
  const currentYear = now.getFullYear();
  const todayStr = format(now, 'yyyy-MM-dd');
  
  // 월간 지출 합계 (현재 월의 모든 지출)
  const monthlyExpenses = expenseTransactions.filter(t => {
    try {
      const transactionDate = new Date(t.date);
      return (
        transactionDate.getMonth() === currentMonth &&
        transactionDate.getFullYear() === currentYear
      );
    } catch (e) {
      return false; // 날짜 파싱 오류 시 포함하지 않음
    }
  });
  
  // 주간 지출 합계 (최근 7일)
  const weeklyExpenses = expenseTransactions.filter(t => {
    try {
      const transactionDate = new Date(t.date);
      const diffTime = now.getTime() - transactionDate.getTime();
      const diffDays = diffTime / (1000 * 3600 * 24);
      return diffDays <= 7;
    } catch (e) {
      return false;
    }
  });
  
  // 일일 지출 합계 (오늘)
  const dailyExpenses = expenseTransactions.filter(t => {
    try {
      const transactionDateStr = format(new Date(t.date), 'yyyy-MM-dd');
      return transactionDateStr === todayStr;
    } catch (e) {
      return false;
    }
  });
  
  // 계산된 지출 금액
  const dailyTotal = dailyExpenses.reduce((sum, t) => sum + t.amount, 0);
  const weeklyTotal = weeklyExpenses.reduce((sum, t) => sum + t.amount, 0);
  const monthlyTotal = monthlyExpenses.reduce((sum, t) => sum + t.amount, 0);
  
  // 예산 데이터에 적용
  newBudgetData.daily.spentAmount = dailyTotal;
  newBudgetData.daily.remainingAmount = Math.max(0, newBudgetData.daily.targetAmount - dailyTotal);
  
  newBudgetData.weekly.spentAmount = weeklyTotal;
  newBudgetData.weekly.remainingAmount = Math.max(0, newBudgetData.weekly.targetAmount - weeklyTotal);
  
  newBudgetData.monthly.spentAmount = monthlyTotal;
  newBudgetData.monthly.remainingAmount = Math.max(0, newBudgetData.monthly.targetAmount - monthlyTotal);
  
  return newBudgetData;
};

// 예산 목표 업데이트 함수
export const calculateUpdatedBudgetData = (
  budgetData: BudgetData, 
  type: 'daily' | 'weekly' | 'monthly', 
  amount: number
): BudgetData => {
  const newBudgetData = JSON.parse(JSON.stringify(budgetData));
  
  // 새로운 예산 목표 설정 및 남은 금액 계산
  newBudgetData[type].targetAmount = amount;
  newBudgetData[type].remainingAmount = Math.max(0, amount - newBudgetData[type].spentAmount);
  
  // 월간 예산 기준으로 일일/주간 예산 자동 계산 (월간 예산이 설정된 경우만)
  if (type === 'monthly' && amount > 0) {
    // 현재 날짜 기준으로 이번 달 남은 일수 계산
    const today = new Date();
    const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();
    const remainingDays = lastDayOfMonth - today.getDate() + 1;
    
    // 일일 예산 계산 (남은 금액 / 남은 일수)
    if (newBudgetData.daily.targetAmount === 0) {
      const dailyBudget = Math.round(amount / lastDayOfMonth);
      newBudgetData.daily.targetAmount = dailyBudget;
      newBudgetData.daily.remainingAmount = Math.max(0, dailyBudget - newBudgetData.daily.spentAmount);
    }
    
    // 주간 예산 계산 (월간 예산 / 4.3주)
    if (newBudgetData.weekly.targetAmount === 0) {
      const weeklyBudget = Math.round(amount / 4.3);
      newBudgetData.weekly.targetAmount = weeklyBudget;
      newBudgetData.weekly.remainingAmount = Math.max(0, weeklyBudget - newBudgetData.weekly.spentAmount);
    }
  }
  
  return newBudgetData;
};
