import { supabase } from './supabase';
import * as offline from './offlineStorage';
import { generateHabitsFromIdentity } from '../utils/helpers';
import { todayISO, addDays } from '../utils/date';

// Must match authService.js
const USE_OFFLINE = true;

// ========================
// GET IDENTITY
// ========================
export async function getIdentity(userId) {
  if (USE_OFFLINE) {
    return offline.getOne('identities', { user_id: userId });
  }

  const { data, error } = await supabase
    .from('identities')
    .select('*')
    .eq('user_id', userId)
    .order('created_at', { ascending: false })
    .limit(1)
    .single();

  if (error && error.code !== 'PGRST116') throw error;
  return data || null;
}

// ========================
// CREATE IDENTITY
// ========================
export async function createIdentity(userId, title, description, customHabits, storyText) {
  const startDate = todayISO();
  const endDate = addDays(new Date(), 40);

  if (USE_OFFLINE) {
    const identity = await offline.insert('identities', {
      user_id: userId,
      title,
      description: description || title,
      story_text: storyText || '',
      start_date: startDate,
      end_date: endDate,
      status: 'active',
    });

    const habitsList = customHabits && customHabits.length > 0
      ? customHabits
      : generateHabitsFromIdentity(title);

    const habitsToInsert = habitsList.map((h) => ({
      identity_id: identity.id,
      title: h.title,
      description: h.description || h.why || '',
      best_time: h.best_time || '',
      duration: h.duration || 0,
      frequency: h.frequency || '',
      category: h.category || '',
      difficulty: h.difficulty || '',
    }));

    const habits = await offline.insertMany('habits', habitsToInsert);

    await offline.insert('stats', {
      identity_id: identity.id,
      discipline_score: 0,
      focus_score: 0,
      consistency_score: 0,
    });

    return { identity, habits };
  }

  // --- Supabase path ---
  const { data, error } = await supabase
    .from('identities')
    .insert({
      user_id: userId,
      title,
      description: description || title,
      story_text: storyText || '',
      start_date: startDate,
      end_date: endDate,
      status: 'active',
    })
    .select()
    .single();

  if (error) throw error;

  const habitsList = customHabits && customHabits.length > 0
    ? customHabits
    : generateHabitsFromIdentity(title);

  const habitsToInsert = habitsList.map((h) => ({
    identity_id: data.id,
    title: h.title,
    description: h.description || h.why || '',
    best_time: h.best_time || '',
    duration: h.duration || 0,
    frequency: h.frequency || '',
    category: h.category || '',
    difficulty: h.difficulty || '',
  }));

  const { data: habits, error: habitsError } = await supabase
    .from('habits')
    .insert(habitsToInsert)
    .select();

  if (habitsError) throw habitsError;

  await supabase.from('stats').insert({
    identity_id: data.id,
    discipline_score: 0,
    focus_score: 0,
    consistency_score: 0,
  });

  return { identity: data, habits: habits || [] };
}

// ========================
// DAILY LOGS
// ========================
export async function getDailyLogs(identityId) {
  if (USE_OFFLINE) {
    const logs = await offline.getAll('daily_logs', { identity_id: identityId });
    return logs.sort((a, b) => a.day_number - b.day_number);
  }

  const { data, error } = await supabase
    .from('daily_logs')
    .select('*')
    .eq('identity_id', identityId)
    .order('day_number', { ascending: true });

  if (error) throw error;
  return data || [];
}

export async function saveDailyLog(identityId, dayNumber, identityCheck, note) {
  const today = todayISO();

  if (USE_OFFLINE) {
    await offline.upsert(
      'daily_logs',
      { identity_id: identityId, date: today },
      { day_number: dayNumber, identity_check: identityCheck, note: note || '' }
    );

    // Update stats
    const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0;
    if (scoreAdd > 0) {
      const stats = await offline.getOne('stats', { identity_id: identityId });
      if (stats) {
        await offline.update('stats', { id: stats.id }, {
          discipline_score: stats.discipline_score + scoreAdd,
          consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1),
          focus_score: stats.focus_score + scoreAdd,
        });
      }
    }
    return;
  }

  // --- Supabase path ---
  const { data: existing } = await supabase
    .from('daily_logs')
    .select('id')
    .eq('identity_id', identityId)
    .eq('date', today)
    .maybeSingle();

  if (existing) {
    const { error } = await supabase
      .from('daily_logs')
      .update({ identity_check: identityCheck, note: note || '' })
      .eq('id', existing.id);
    if (error) throw error;
  } else {
    const { error } = await supabase
      .from('daily_logs')
      .insert({
        identity_id: identityId,
        date: today,
        day_number: dayNumber,
        identity_check: identityCheck,
        note: note || '',
      });
    if (error) throw error;
  }

  const scoreAdd = identityCheck === 'yes' ? 3 : identityCheck === 'almost' ? 1 : 0;
  if (scoreAdd > 0) {
    const { data: stats } = await supabase
      .from('stats')
      .select('*')
      .eq('identity_id', identityId)
      .maybeSingle();

    if (stats) {
      await supabase
        .from('stats')
        .update({
          discipline_score: stats.discipline_score + scoreAdd,
          consistency_score: stats.consistency_score + (identityCheck === 'yes' ? 2 : 1),
          focus_score: stats.focus_score + scoreAdd,
        })
        .eq('id', stats.id);
    }
  }
}

// ========================
// STATS
// ========================
export async function getStats(identityId) {
  if (USE_OFFLINE) {
    return offline.getOne('stats', { identity_id: identityId });
  }

  const { data, error } = await supabase
    .from('stats')
    .select('*')
    .eq('identity_id', identityId)
    .single();

  if (error && error.code !== 'PGRST116') throw error;
  return data || null;
}

// ========================
// GAME SESSIONS
// ========================
export async function saveGameScore(identityId, gameType, score) {
  if (USE_OFFLINE) {
    await offline.insert('game_sessions', {
      identity_id: identityId,
      game_type: gameType,
      score,
    });
    return;
  }

  const { error } = await supabase.from('game_sessions').insert({
    identity_id: identityId,
    game_type: gameType,
    score,
  });
  if (error) throw error;
}

// ========================
// RESET JOURNEY
// ========================
export async function resetJourney(identityId, reason) {
  if (USE_OFFLINE) {
    // Save reset log
    await offline.insert('reset_logs', {
      identity_id: identityId,
      reason: reason || '',
      reset_at: new Date().toISOString(),
    });
    // Remove all related data
    await offline.removeAll('habits', { identity_id: identityId });
    await offline.removeAll('daily_logs', { identity_id: identityId });
    await offline.removeAll('habit_logs'); // habit_logs don't have identity_id directly
    await offline.removeAll('stats', { identity_id: identityId });
    await offline.removeAll('game_sessions', { identity_id: identityId });
    await offline.removeAll('identities', { id: identityId });
    return;
  }

  // Supabase path
  await supabase.from('habits').delete().eq('identity_id', identityId);
  await supabase.from('daily_logs').delete().eq('identity_id', identityId);
  await supabase.from('stats').delete().eq('identity_id', identityId);
  await supabase.from('game_sessions').delete().eq('identity_id', identityId);
  await supabase.from('identities').delete().eq('id', identityId);
}
