// Client-side storage utilities for tracking data
// Now uses API calls to persist data in SQLite database

export interface UsageEntry {
  date: string; // ISO date string YYYY-MM-DD
  count: number;
  substance: 'nicotine' | 'weed';
}

export interface UserPreferences {
  substance: 'nicotine' | 'weed';
  trackingStartDate: string | null;
  hasCompletedSetup: boolean;
  dailyGoal: number | null;
  quitPlan: QuitPlan | null;
  userName: string | null;
  userAge: number | null;
  religion: 'christian' | 'secular' | null;
  lastNicotineUsageTime?: string | null; // ISO timestamp of last usage
  lastWeedUsageTime?: string | null; // ISO timestamp of last usage
}

export interface QuitPlan {
  startDate: string;
  endDate: string;
  weeklyTargets: number[];
  baselineAverage: number;
}

// ============ NEW FEATURE INTERFACES ============

export interface Achievement {
  badgeId: string;
  unlockedAt: string;
  substance: 'nicotine' | 'weed' | 'both';
}

export interface ReminderSettings {
  enabled: boolean;
  reminderTime: string; // HH:MM format
  frequency: 'daily' | 'hourly';
  hourlyStart?: string; // HH:MM
  hourlyEnd?: string;   // HH:MM
  timezone?: string;    // e.g. 'America/New_York'
}

export interface SavingsConfig {
  costPerUnit: number;
  unitsPerDay: number;
  savingsGoal: number | null;
  goalName: string | null;
  currency: string;
  substance: 'nicotine' | 'weed';
}

export interface BadgeDefinition {
  id: string;
  name: string;
  description: string;
  howToUnlock: string;
  icon: string;
}

export interface HealthMilestone {
  id: string;
  timeMinutes: number;
  title: string;
  description: string;
  icon: string;
}

export interface MoodEntry {
  id: string;
  userId: string;
  mood: 'good' | 'neutral' | 'bad';
  date: string;
  comment: string | null;
  createdAt: string;
}

// ============ BADGE DEFINITIONS ============

export const BADGE_DEFINITIONS: BadgeDefinition[] = [
  { id: 'first_day', name: 'First Step', description: 'Logged your first usage', howToUnlock: 'Log your usage for the first time', icon: 'Footprints' },
  { id: 'streak_3', name: 'Hat Trick', description: '3 days substance-free', howToUnlock: 'Go 3 consecutive days without using a tracked substance', icon: 'Flame' },
  { id: 'streak_7', name: 'Week Warrior', description: 'Tracked for one week', howToUnlock: 'Track your usage for 7 days', icon: 'Shield' },
  { id: 'fighter', name: 'Fighter', description: '7 days substance-free', howToUnlock: 'Go 7 consecutive days without using any substance', icon: 'Swords' },
  { id: 'one_month', name: 'Monthly Master', description: 'One month tracked with 50% reduction', howToUnlock: 'Track for 30 days and reduce your usage by at least 50%', icon: 'Crown' },
  { id: 'goal_crusher', name: 'Goal Crusher', description: 'One month substance-free', howToUnlock: 'Go 30 consecutive days without using any substance', icon: 'Trophy' },
];

// ============ HEALTH MILESTONES ============

export const HEALTH_MILESTONES: HealthMilestone[] = [
  { id: '20min', timeMinutes: 20, title: 'Blood Pressure Normalizes', description: 'Your heart rate and blood pressure begin to drop', icon: 'Heart' },
  { id: '8hr', timeMinutes: 480, title: 'Oxygen Levels Rise', description: 'Carbon monoxide levels drop, oxygen levels increase', icon: 'Wind' },
  { id: '24hr', timeMinutes: 1440, title: 'Heart Attack Risk Drops', description: 'Your risk of heart attack begins to decrease', icon: 'HeartPulse' },
  { id: '48hr', timeMinutes: 2880, title: 'Senses Sharpen', description: 'Taste and smell begin to improve', icon: 'Eye' },
  { id: '72hr', timeMinutes: 4320, title: 'Breathing Easier', description: 'Bronchial tubes relax, energy levels increase', icon: 'Wind' },
  { id: '2wk', timeMinutes: 20160, title: 'Circulation Improves', description: 'Blood circulation significantly improves', icon: 'Activity' },
  { id: '1mo', timeMinutes: 43200, title: 'Lung Function Improves', description: 'Lung capacity increases up to 30%', icon: 'TrendingUp' },
  { id: '3mo', timeMinutes: 129600, title: 'Cilia Regenerate', description: 'Lungs begin to heal, coughing decreases', icon: 'Sparkles' },
  { id: '1yr', timeMinutes: 525600, title: 'Heart Disease Risk Halved', description: 'Risk of coronary heart disease cut in half', icon: 'HeartHandshake' },
];

const defaultPreferences: UserPreferences = {
  substance: 'nicotine',
  trackingStartDate: null,
  hasCompletedSetup: false,
  dailyGoal: null,
  quitPlan: null,
  userName: null,
  userAge: null,
  religion: null,
};

// Cache for preferences and usage data to avoid excessive API calls
let preferencesCache: UserPreferences | null = null;
let usageDataCache: UsageEntry[] | null = null;
let achievementsCache: Achievement[] | null = null;
let reminderSettingsCache: ReminderSettings | null = null;
let savingsConfigCache: SavingsConfig | null = null;
let moodEntriesCache: MoodEntry[] | null = null;

export function clearCache(): void {
  preferencesCache = null;
  usageDataCache = null;
  achievementsCache = null;
  reminderSettingsCache = null;
  savingsConfigCache = null;
  moodEntriesCache = null;
}

// These functions are kept for backwards compatibility but no longer used
export function setCurrentUserId(_userId: string): void {
  // No-op - user ID is now managed by session
}

export function getCurrentUserId(): string | null {
  return null;
}

// Async API functions
export async function fetchPreferences(): Promise<UserPreferences> {
  if (preferencesCache) return preferencesCache;
  try {
    const response = await fetch('/api/preferences');
    if (!response.ok) {
      console.error('Failed to fetch preferences');
      return defaultPreferences;
    }
    const data = await response.json() as UserPreferences;
    preferencesCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching preferences:', error);
    return defaultPreferences;
  }
}

export async function savePreferencesAsync(preferences: UserPreferences): Promise<void> {
  try {
    const response = await fetch('/api/preferences', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(preferences),
    });
    if (response.ok) {
      preferencesCache = preferences;
    }
  } catch (error) {
    console.error('Error saving preferences:', error);
  }
}

export async function fetchUsageData(): Promise<UsageEntry[]> {
  if (usageDataCache) return usageDataCache;
  try {
    const response = await fetch('/api/usage');
    if (!response.ok) {
      console.error('Failed to fetch usage data');
      return [];
    }
    const data = await response.json() as UsageEntry[];
    usageDataCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching usage data:', error);
    return [];
  }
}

export async function saveUsageEntryAsync(entry: UsageEntry): Promise<void> {
  try {
    await fetch('/api/usage', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(entry),
    });
    usageDataCache = null; // Invalidate cache
  } catch (error) {
    console.error('Error saving usage entry:', error);
  }
}

export async function setUsageForDateAsync(
  date: string,
  count: number,
  substance: 'nicotine' | 'weed'
): Promise<void> {
  try {
    await fetch('/api/usage', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ date, count, substance }),
    });
    usageDataCache = null; // Invalidate cache
  } catch (error) {
    console.error('Error setting usage for date:', error);
  }
}

export async function clearDayDataAsync(
  date: string,
  substance: 'nicotine' | 'weed'
): Promise<void> {
  try {
    await fetch(`/api/usage?date=${date}&substance=${substance}`, {
      method: 'DELETE',
    });
    usageDataCache = null; // Invalidate cache
  } catch (error) {
    console.error('Error clearing day data:', error);
  }
}

// ============ ACHIEVEMENTS FUNCTIONS ============

export async function fetchAchievements(): Promise<Achievement[]> {
  if (achievementsCache) return achievementsCache;
  try {
    const response = await fetch('/api/achievements');
    if (!response.ok) return [];
    const data = await response.json() as Achievement[];
    achievementsCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching achievements:', error);
    return [];
  }
}

export async function unlockAchievement(
  badgeId: string,
  substance: 'nicotine' | 'weed' | 'both'
): Promise<{ achievement: Achievement | null; isNew: boolean }> {
  try {
    const response = await fetch('/api/achievements', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ badgeId, substance }),
    });
    if (response.ok) {
      const data = await response.json() as { badgeId: string; unlockedAt: string; substance: 'nicotine' | 'weed' | 'both'; alreadyUnlocked?: boolean };
      achievementsCache = null; // Invalidate cache
      return {
        achievement: {
          badgeId: data.badgeId,
          unlockedAt: data.unlockedAt,
          substance: data.substance,
        },
        isNew: !data.alreadyUnlocked,
      };
    }
    return { achievement: null, isNew: false };
  } catch (error) {
    console.error('Error unlocking achievement:', error);
    return { achievement: null, isNew: false };
  }
}

export function getAchievements(): Achievement[] {
  return achievementsCache || [];
}

// ============ REMINDERS FUNCTIONS ============

export async function fetchReminderSettings(): Promise<ReminderSettings> {
  if (reminderSettingsCache) return reminderSettingsCache;
  try {
    const response = await fetch('/api/reminders');
    if (!response.ok) return { enabled: false, reminderTime: '09:00', frequency: 'daily' };
    const data = await response.json() as ReminderSettings;
    reminderSettingsCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching reminder settings:', error);
    return { enabled: false, reminderTime: '09:00', frequency: 'daily' };
  }
}

export async function saveReminderSettings(settings: ReminderSettings): Promise<void> {
  try {
    const response = await fetch('/api/reminders', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(settings),
    });
    if (response.ok) {
      reminderSettingsCache = settings;
    }
  } catch (error) {
    console.error('Error saving reminder settings:', error);
  }
}

export function getReminderSettings(): ReminderSettings {
  return reminderSettingsCache || { enabled: false, reminderTime: '09:00', frequency: 'daily' };
}

// ============ SAVINGS FUNCTIONS ============

export async function fetchSavingsConfig(): Promise<SavingsConfig | null> {
  if (savingsConfigCache) return savingsConfigCache;
  try {
    const response = await fetch('/api/savings');
    if (!response.ok) return null;
    const data = await response.json() as SavingsConfig | null;
    savingsConfigCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching savings config:', error);
    return null;
  }
}

export async function saveSavingsConfig(config: SavingsConfig): Promise<void> {
  try {
    const response = await fetch('/api/savings', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(config),
    });
    if (response.ok) {
      savingsConfigCache = config;
    }
  } catch (error) {
    console.error('Error saving savings config:', error);
  }
}

export function getSavingsConfig(): SavingsConfig | null {
  return savingsConfigCache;
}

// ============ MOOD FUNCTIONS ============

export async function fetchMoodEntries(): Promise<MoodEntry[]> {
  if (moodEntriesCache) return moodEntriesCache;
  try {
    const response = await fetch('/api/mood');
    if (!response.ok) return [];
    const data = await response.json() as MoodEntry[];
    moodEntriesCache = data;
    return data;
  } catch (error) {
    console.error('Error fetching mood entries:', error);
    return [];
  }
}

export async function saveMoodEntry(mood: 'good' | 'neutral' | 'bad', comment?: string): Promise<{ entry: MoodEntry; affirmation: string } | null> {
  try {
    const response = await fetch('/api/mood', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ mood, comment }),
    });
    if (response.ok) {
      const data = await response.json() as { entry: MoodEntry; affirmation: string };
      moodEntriesCache = null; // Invalidate cache
      return data;
    }
    return null;
  } catch (error) {
    console.error('Error saving mood entry:', error);
    return null;
  }
}

// ============ CALCULATION HELPERS ============

export function calculateStreak(
  usageData: UsageEntry[],
  substance: 'nicotine' | 'weed'
): number {
  let streak = 0;
  const today = new Date();
  const substanceData = usageData.filter((e) => e.substance === substance);

  for (let i = 0; i <= 365; i++) {
    const checkDate = new Date(today);
    checkDate.setDate(checkDate.getDate() - i);
    const dateStr = checkDate.toISOString().split('T')[0];
    const dayUsage = substanceData.find((e) => e.date === dateStr)?.count ?? -1;

    if (dayUsage === 0) {
      streak++;
    } else if (dayUsage > 0) {
      break;
    }
    // If dayUsage === -1 (no entry), we continue but don't count it as a streak day
  }
  return streak;
}

export function calculateTotalSaved(
  savingsConfig: SavingsConfig | null,
  usageData: UsageEntry[],
  startDate: string | null
): number {
  if (!savingsConfig || !startDate) return 0;

  const start = new Date(startDate);
  const today = new Date();
  const daysSinceStart = Math.floor(
    (today.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)
  );

  if (daysSinceStart <= 0) return 0;

  // Expected spending if they continued at baseline (unitsPerDay is now unitsPerWeek)
  const weeksSinceStart = daysSinceStart / 7;
  const expectedSpend =
    weeksSinceStart * savingsConfig.costPerUnit * savingsConfig.unitsPerDay;

  // Actual usage converted to cost (assuming ~20 puffs/hits per unit)
  const relevantUsage = usageData.filter(
    (e) => e.substance === savingsConfig.substance && new Date(e.date) >= start
  );
  const actualUnits = relevantUsage.reduce((sum, e) => sum + e.count, 0);
  const unitsPerPack = 20; // Average puffs per pack/unit
  const actualSpend = (actualUnits / unitsPerPack) * savingsConfig.costPerUnit;

  return Math.max(0, expectedSpend - actualSpend);
}



export function checkBadgeEligibility(
  badgeId: string,
  usageData: UsageEntry[],
  preferences: UserPreferences,
  substance: 'nicotine' | 'weed'
): boolean {
  const streak = calculateStreak(usageData, substance);
  const nicotineStreak = calculateStreak(usageData, 'nicotine');
  const weedStreak = calculateStreak(usageData, 'weed');
  const totalDays = new Set(
    usageData.filter((e) => e.substance === substance).map((e) => e.date)
  ).size;

  // Check if user has tracked for at least 30 days and reduced usage by 50%
  const checkMonthlyReduction = (): boolean => {
    if (!preferences.trackingStartDate) return false;
    const startDate = new Date(preferences.trackingStartDate);
    const today = new Date();
    const daysSinceStart = Math.floor(
      (today.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)
    );
    if (daysSinceStart < 30) return false;

    // Get first week's average
    const firstWeekData = usageData.filter((e) => {
      const entryDate = new Date(e.date);
      const daysSinceEntry = Math.floor(
        (entryDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)
      );
      return e.substance === substance && daysSinceEntry >= 0 && daysSinceEntry < 7;
    });
    const firstWeekTotal = firstWeekData.reduce((sum, e) => sum + e.count, 0);
    const firstWeekAvg = firstWeekData.length > 0 ? firstWeekTotal / 7 : 0;

    // Get last week's average
    const lastWeekData = usageData.filter((e) => {
      const entryDate = new Date(e.date);
      const daysAgo = Math.floor(
        (today.getTime() - entryDate.getTime()) / (1000 * 60 * 60 * 24)
      );
      return e.substance === substance && daysAgo >= 0 && daysAgo < 7;
    });
    const lastWeekTotal = lastWeekData.reduce((sum, e) => sum + e.count, 0);
    const lastWeekAvg = lastWeekTotal / 7;

    // Check if reduced by at least 50%
    if (firstWeekAvg <= 0) return lastWeekAvg === 0;
    return lastWeekAvg <= firstWeekAvg * 0.5;
  };

  switch (badgeId) {
    case 'first_day':
      // Log usage for the first time
      return totalDays >= 1;
    case 'streak_3':
      // 3 days off a tracked substance
      return streak >= 3;
    case 'streak_7':
      // Track usage for one week (7 days of entries)
      return totalDays >= 7;
    case 'fighter':
      // 7 days off ANY substance (both nicotine AND weed)
      return nicotineStreak >= 7 && weedStreak >= 7;
    case 'one_month':
      // Track one month and reduce usage by 50%
      return checkMonthlyReduction();
    case 'goal_crusher':
      // One month substance free (both substances)
      return nicotineStreak >= 30 && weedStreak >= 30;
    default:
      return false;
  }
}

// Synchronous functions that use cache (for backwards compatibility)
// These should be replaced with async versions in components

export function getPreferences(_userId?: string): UserPreferences {
  return preferencesCache || defaultPreferences;
}

export function getUsageData(_userId?: string): UsageEntry[] {
  return usageDataCache || [];
}

export function savePreferences(preferences: UserPreferences, _userId?: string): void {
  preferencesCache = preferences;
  savePreferencesAsync(preferences);
}

export function saveUsageEntry(entry: UsageEntry, _userId?: string): void {
  saveUsageEntryAsync(entry);
}

export function setUsageForDate(
  date: string,
  count: number,
  substance: 'nicotine' | 'weed',
  _userId?: string
): void {
  setUsageForDateAsync(date, count, substance);
}

export function getUsageForDate(
  date: string,
  substance: 'nicotine' | 'weed',
  _userId?: string
): number {
  const data = usageDataCache || [];
  const entry = data.find((e) => e.date === date && e.substance === substance);
  return entry?.count ?? 0;
}

export function clearDayData(
  date: string,
  substance: 'nicotine' | 'weed',
  _userId?: string
): void {
  clearDayDataAsync(date, substance);
}

const LAST_PROMPT_KEY = 'quittraq_last_prompt_date';

export function shouldShowUsagePrompt(): boolean {
  if (typeof window === 'undefined') return false;

  const today = new Date().toISOString().split('T')[0];
  const lastPromptDate = localStorage.getItem(LAST_PROMPT_KEY);

  return lastPromptDate !== today;
}

export function markPromptShown(): void {
  if (typeof window === 'undefined') return;

  const today = new Date().toISOString().split('T')[0];
  localStorage.setItem(LAST_PROMPT_KEY, today);
}

export function getWeeklyData(substance: 'nicotine' | 'weed', _userId?: string): UsageEntry[] {
  const data = usageDataCache || [];
  const today = new Date();
  const weekAgo = new Date(today);
  weekAgo.setDate(weekAgo.getDate() - 7);

  return data.filter((entry) => {
    const entryDate = new Date(entry.date);
    return entry.substance === substance && entryDate >= weekAgo && entryDate <= today;
  });
}

export function calculateWeeklyAverage(substance: 'nicotine' | 'weed', _userId?: string): number {
  const weeklyData = getWeeklyData(substance);
  if (weeklyData.length === 0) return 0;

  const total = weeklyData.reduce((sum, entry) => sum + entry.count, 0);
  return Math.round(total / weeklyData.length);
}

export function hasOneWeekOfData(substance: 'nicotine' | 'weed', _userId?: string): boolean {
  const prefs = preferencesCache;
  if (!prefs?.trackingStartDate) return false;

  const startDate = new Date(prefs.trackingStartDate);
  const today = new Date();
  const daysDiff = Math.floor((today.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));

  return daysDiff >= 7;
}

export function generateQuitPlan(substance: 'nicotine' | 'weed', _userId?: string): QuitPlan {
  const baseline = calculateWeeklyAverage(substance);
  const today = new Date();
  const startDate = today.toISOString().split('T')[0];

  // 4-week reduction plan with 25% weekly reduction
  const endDate = new Date(today);
  endDate.setDate(endDate.getDate() + 28);

  // Gradual reduction: each week reduce by 25%
  const weeklyTargets: number[] = [];
  let current = baseline;
  for (let i = 0; i < 4; i++) {
    current = Math.max(0, Math.round(current * 0.75));
    weeklyTargets.push(current);
  }

  return {
    startDate,
    endDate: endDate.toISOString().split('T')[0],
    weeklyTargets,
    baselineAverage: baseline,
  };
}

export function getCurrentWeekTarget(_userId?: string): number | null {
  const prefs = preferencesCache;
  if (!prefs?.quitPlan) return null;

  const startDate = new Date(prefs.quitPlan.startDate);
  const today = new Date();
  const weekNumber = Math.floor((today.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24 * 7));

  if (weekNumber >= prefs.quitPlan.weeklyTargets.length) {
    return 0; // Goal achieved
  }

  return prefs.quitPlan.weeklyTargets[weekNumber];
}

export async function clearAllDataAsync(): Promise<void> {
  // This would need a dedicated API endpoint
  console.warn('clearAllData not implemented for API-based storage');
}

export function clearAllData(_userId?: string): void {
  clearAllDataAsync();
}
