import { supabase } from '@/lib/supabase';
import { isSyncEnabled } from '../syncSettings';
import { getModifiedBudget, getModifiedCategoryBudgets } from './modifiedBudgetsTracker';

/**
 * 서버에서 예산 데이터 다운로드
 */
export const downloadBudgets = async (userId: string): Promise<void> => {
  if (!isSyncEnabled()) return;

  try {
    console.log('서버에서 예산 데이터 다운로드 시작');
    
    // 현재 로컬 예산 데이터 백업
    const localBudgetData = localStorage.getItem('budgetData');
    const localCategoryBudgets = localStorage.getItem('categoryBudgets');
    
    // 서버에 데이터가 없는지 확인
    const { data: budgetExists, error: checkError } = await supabase
      .from('budgets')
      .select('count')
      .eq('user_id', userId)
      .single();
      
    // 서버에 데이터가 없고 로컬에 데이터가 있으면 다운로드 건너뜀
    if ((budgetExists?.count === 0 || !budgetExists) && localBudgetData) {
      console.log('서버에 예산 데이터가 없고 로컬 데이터가 있어 다운로드 건너뜀');
      return;
    }
    
    // 예산 데이터 및 카테고리 예산 데이터 가져오기
    const [budgetData, categoryData] = await Promise.all([
      fetchBudgetData(userId),
      fetchCategoryBudgetData(userId)
    ]);
    
    // 예산 데이터 처리
    if (budgetData) {
      await processBudgetData(budgetData, localBudgetData);
    } else {
      console.log('서버에서 예산 데이터를 찾을 수 없음');
      // 로컬 데이터가 있으면 유지
      if (localBudgetData) {
        console.log('로컬 예산 데이터 유지');
      }
    }
    
    // 카테고리 예산 데이터 처리
    if (categoryData && categoryData.length > 0) {
      await processCategoryBudgetData(categoryData, localCategoryBudgets);
    } else {
      console.log('서버에서 카테고리 예산 데이터를 찾을 수 없음');
      // 로컬 데이터가 있으면 유지
      if (localCategoryBudgets) {
        console.log('로컬 카테고리 예산 데이터 유지');
      }
    }
    
    console.log('예산 데이터 다운로드 완료');
  } catch (error) {
    console.error('예산 데이터 다운로드 실패:', error);
    throw error;
  }
};

/**
 * 예산 데이터 조회
 */
async function fetchBudgetData(userId: string) {
  // 현재 월/년도 가져오기
  const now = new Date();
  const currentMonth = now.getMonth() + 1; // 0-11 -> 1-12
  const currentYear = now.getFullYear();
  
  const { data, error } = await supabase
    .from('budgets')
    .select('*')
    .eq('user_id', userId)
    .eq('month', currentMonth)
    .eq('year', currentYear);
    
  if (error) {
    console.error('예산 데이터 조회 실패:', error);
    throw error;
  }
  
  return data && data.length > 0 ? data[0] : null;
}

/**
 * 카테고리 예산 데이터 조회
 */
async function fetchCategoryBudgetData(userId: string) {
  const { data, error } = await supabase
    .from('category_budgets')
    .select('*')
    .eq('user_id', userId);
    
  if (error) {
    console.error('카테고리 예산 조회 실패:', error);
    throw error;
  }
  
  return data;
}

/**
 * 예산 데이터 처리 및 로컬 저장
 */
async function processBudgetData(budgetData: Record<string, any>, localBudgetDataStr: string | null) {
  console.log('서버에서 예산 데이터 수신:', budgetData);
  
  // 로컬에서 수정된 예산 정보 가져오기
  const modifiedBudget = getModifiedBudget();
  
  // 서버 예산이 0이고 로컬 예산이 있으면 로컬 데이터 유지
  if (budgetData.total_budget === 0 && localBudgetDataStr) {
    console.log('서버 예산이 0이고 로컬 예산이 있어 로컬 데이터 유지');
    return;
  }
  
  // 기존 로컬 데이터 가져오기 
  const localBudgetData = localBudgetDataStr ? JSON.parse(localBudgetDataStr) : {
    daily: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
    weekly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
    monthly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }
  };
  
  // 로컬에서 수정된 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
  if (modifiedBudget && (!budgetData.updated_at || new Date(budgetData.updated_at).getTime() < modifiedBudget.timestamp)) {
    console.log('로컬에서 수정된 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
    
    // 서버 데이터 대신 로컬에서 수정된 예산 사용
    const monthlyBudget = modifiedBudget.monthlyAmount;
    const dailyBudget = Math.round(monthlyBudget / 30); // 월간 예산 / 30일
    const weeklyBudget = Math.round(monthlyBudget / 4.3); // 월간 예산 / 4.3주
    
    const updatedBudgetData = {
      daily: {
        targetAmount: dailyBudget,
        spentAmount: localBudgetData.daily.spentAmount,
        remainingAmount: dailyBudget - localBudgetData.daily.spentAmount
      },
      weekly: {
        targetAmount: weeklyBudget,
        spentAmount: localBudgetData.weekly.spentAmount,
        remainingAmount: weeklyBudget - localBudgetData.weekly.spentAmount
      },
      monthly: {
        targetAmount: monthlyBudget,
        spentAmount: localBudgetData.monthly.spentAmount,
        remainingAmount: monthlyBudget - localBudgetData.monthly.spentAmount
      }
    };
    
    console.log('로컬 수정 데이터 기반 예산 계산:', updatedBudgetData);
    
    // 로컬 스토리지에 저장
    localStorage.setItem('budgetData', JSON.stringify(updatedBudgetData));
    localStorage.setItem('budgetData_backup', JSON.stringify(updatedBudgetData));
    console.log('로컬 수정 예산 데이터 유지 완료', updatedBudgetData);
    
    // 이벤트 발생시켜 UI 업데이트
    window.dispatchEvent(new Event('budgetDataUpdated'));
    return;
  }
  
  // 서버 데이터로 업데이트 (지출 금액은 유지)
  // 수정: 올바른 예산 계산 방식으로 변경
  const monthlyBudget = budgetData.total_budget;
  const dailyBudget = Math.round(monthlyBudget / 30); // 월간 예산 / 30일
  const weeklyBudget = Math.round(monthlyBudget / 4.3); // 월간 예산 / 4.3주
  
  const updatedBudgetData = {
    daily: {
      targetAmount: dailyBudget,
      spentAmount: localBudgetData.daily.spentAmount,
      remainingAmount: dailyBudget - localBudgetData.daily.spentAmount
    },
    weekly: {
      targetAmount: weeklyBudget,
      spentAmount: localBudgetData.weekly.spentAmount,
      remainingAmount: weeklyBudget - localBudgetData.weekly.spentAmount
    },
    monthly: {
      targetAmount: monthlyBudget,
      spentAmount: localBudgetData.monthly.spentAmount,
      remainingAmount: monthlyBudget - localBudgetData.monthly.spentAmount
    }
  };
  
  console.log('계산된 예산 데이터:', updatedBudgetData);
  
  // 로컬 스토리지에 저장
  localStorage.setItem('budgetData', JSON.stringify(updatedBudgetData));
  localStorage.setItem('budgetData_backup', JSON.stringify(updatedBudgetData));
  console.log('예산 데이터 로컬 저장 완료', updatedBudgetData);
  
  // 이벤트 발생시켜 UI 업데이트
  window.dispatchEvent(new Event('budgetDataUpdated'));
}

/**
 * 카테고리 예산 데이터 처리 및 로컬 저장
 */
async function processCategoryBudgetData(categoryData: Record<string, any>[], localCategoryBudgetsStr: string | null) {
  console.log(`${categoryData.length}개의 카테고리 예산 수신`);
  
  // 로컬에서 수정된 카테고리 예산 정보 가져오기
  const modifiedCategoryBudgets = getModifiedCategoryBudgets();
  
  // 서버 카테고리 예산 합계 계산
  const serverTotal = categoryData.reduce((sum, item) => sum + item.amount, 0);
  
  // 로컬 카테고리 예산이 있고 서버 데이터가 비어있거나 합계가 0이면 로컬 데이터 유지
  if (localCategoryBudgetsStr && (categoryData.length === 0 || serverTotal === 0)) {
    console.log('서버 카테고리 예산이 없거나 0이고 로컬 데이터가 있어 로컬 데이터 유지');
    return;
  }
  
  // 로컬에서 수정된 카테고리 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
  if (modifiedCategoryBudgets && categoryData.length > 0) {
    // 서버 데이터 중 가장 최근 업데이트 시간 확인
    const latestServerUpdate = categoryData.reduce((latest, curr) => {
      if (!curr.updated_at) return latest;
      const currTime = new Date(curr.updated_at).getTime();
      return currTime > latest ? currTime : latest;
    }, 0);
    
    if (latestServerUpdate < modifiedCategoryBudgets.timestamp) {
      console.log('로컬에서 수정된 카테고리 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
      return;
    }
  }
  
  // 카테고리 예산 로컬 형식으로 변환
  const localCategoryBudgets = categoryData.reduce((acc, curr) => {
    acc[curr.category] = curr.amount;
    return acc;
  }, {} as Record<string, number>);
  
  // 로컬 스토리지에 저장
  localStorage.setItem('categoryBudgets', JSON.stringify(localCategoryBudgets));
  localStorage.setItem('categoryBudgets_backup', JSON.stringify(localCategoryBudgets));
  console.log('카테고리 예산 로컬 저장 완료', localCategoryBudgets);
  
  // 이벤트 발생시켜 UI 업데이트
  window.dispatchEvent(new Event('categoryBudgetsUpdated'));
}
