// LocalStorage fallback for offline mode
const STORAGE_KEYS = {
  PROFILES: "hop_profiles",
  SONGS: "hop_songs",
  PLANS: "hop_plans",
  PLAN_SONGS: "hop_plan_songs",
  PROFILE_SONGS: "hop_profile_songs",
  PROFILE_SONG_KEYS: "hop_profile_song_keys",
  CURRENT_PROFILE: "hop_current_profile",
};

// Initialize with default data if empty
function initStorage() {
  if (!localStorage.getItem(STORAGE_KEYS.PROFILES)) {
    localStorage.setItem(
      STORAGE_KEYS.PROFILES,
      JSON.stringify([
        { id: 1, name: "Default Profile", default_key: "C", notes: "" },
      ])
    );
  }
  if (!localStorage.getItem(STORAGE_KEYS.SONGS)) {
    localStorage.setItem(STORAGE_KEYS.SONGS, JSON.stringify([]));
  }
  if (!localStorage.getItem(STORAGE_KEYS.PLANS)) {
    localStorage.setItem(STORAGE_KEYS.PLANS, JSON.stringify([]));
  }
  if (!localStorage.getItem(STORAGE_KEYS.PLAN_SONGS)) {
    localStorage.setItem(STORAGE_KEYS.PLAN_SONGS, JSON.stringify([]));
  }
  if (!localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS)) {
    localStorage.setItem(STORAGE_KEYS.PROFILE_SONGS, JSON.stringify([]));
  }
  if (!localStorage.getItem(STORAGE_KEYS.PROFILE_SONG_KEYS)) {
    localStorage.setItem(STORAGE_KEYS.PROFILE_SONG_KEYS, JSON.stringify([]));
  }
}

initStorage();

// Helper functions
function getNextId(items) {
  return items.length > 0 ? Math.max(...items.map((i) => i.id)) + 1 : 1;
}

export const localStorageAPI = {
  // Profiles
  async getProfiles() {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILES);
    return JSON.parse(data || "[]");
  },

  async createProfile(profile) {
    const profiles = await this.getProfiles();
    // Use provided ID if available (from backend), otherwise generate new one
    const newProfile = {
      ...profile,
      id: profile.id || getNextId(profiles),
    };
    profiles.push(newProfile);
    localStorage.setItem(STORAGE_KEYS.PROFILES, JSON.stringify(profiles));
    return newProfile;
  },

  async updateProfile(id, updates) {
    const profiles = await this.getProfiles();
    const index = profiles.findIndex((p) => p.id === id);
    if (index >= 0) {
      profiles[index] = { ...profiles[index], ...updates };
      localStorage.setItem(STORAGE_KEYS.PROFILES, JSON.stringify(profiles));
    } else {
      // Profile doesn't exist, create it
      const newProfile = { ...updates, id };
      profiles.push(newProfile);
      localStorage.setItem(STORAGE_KEYS.PROFILES, JSON.stringify(profiles));
      return newProfile;
    }
    return profiles[index];
  },

  async deleteProfile(id) {
    const profiles = await this.getProfiles();
    const filtered = profiles.filter((p) => p.id !== id);
    localStorage.setItem(STORAGE_KEYS.PROFILES, JSON.stringify(filtered));

    // Also delete associated profile songs
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS);
    const profileSongs = JSON.parse(data || "[]");
    const filteredSongs = profileSongs.filter((ps) => ps.profile_id !== id);
    localStorage.setItem(
      STORAGE_KEYS.PROFILE_SONGS,
      JSON.stringify(filteredSongs)
    );

    // Verify deletion
    const afterProfiles = await this.getProfiles();
    const stillExists = afterProfiles.some((p) => p.id === id);
    if (stillExists) {
      console.error(
        "[localStorage.deleteProfile] WARNING: Profile still exists after deletion!"
      );
    }

    return { success: true, id };
  },

  // Songs
  async getSongs(query = "") {
    const data = localStorage.getItem(STORAGE_KEYS.SONGS);
    const songs = JSON.parse(data || "[]");
    if (!query) return songs;

    const q = query.toLowerCase();
    return songs.filter(
      (s) =>
        (s.title || "").toLowerCase().includes(q) ||
        (s.artist || "").toLowerCase().includes(q) ||
        (s.band || "").toLowerCase().includes(q) ||
        (s.singer || "").toLowerCase().includes(q)
    );
  },

  async getSong(id) {
    const songs = await this.getSongs();
    return songs.find((s) => s.id === id);
  },

  async createSong(song) {
    const songs = await this.getSongs();
    const newSong = { ...song, id: getNextId(songs) };
    songs.push(newSong);
    localStorage.setItem(STORAGE_KEYS.SONGS, JSON.stringify(songs));
    return newSong;
  },

  async updateSong(id, updates) {
    const songs = await this.getSongs();
    const index = songs.findIndex((s) => s.id === id);
    if (index >= 0) {
      songs[index] = { ...songs[index], ...updates };
      localStorage.setItem(STORAGE_KEYS.SONGS, JSON.stringify(songs));
    }
    return songs[index];
  },

  async deleteSong(id) {
    const songs = await this.getSongs();
    const filtered = songs.filter((s) => s.id !== id);
    localStorage.setItem(STORAGE_KEYS.SONGS, JSON.stringify(filtered));
    return { success: true, id };
  },

  // Plans
  async getPlans() {
    const data = localStorage.getItem(STORAGE_KEYS.PLANS);
    return JSON.parse(data || "[]");
  },

  async createPlan(plan) {
    const plans = await this.getPlans();
    const { songs, ...planData } = plan;

    const newPlan = {
      ...planData,
      id: getNextId(plans),
      date: plan.date || new Date().toISOString().split("T")[0],
      notes: plan.notes || "",
    };
    plans.push(newPlan);
    localStorage.setItem(STORAGE_KEYS.PLANS, JSON.stringify(plans));

    // Add songs to plan if provided
    if (songs && songs.length > 0) {
      const data = localStorage.getItem(STORAGE_KEYS.PLAN_SONGS);
      const allPlanSongs = JSON.parse(data || "[]");

      // Get the max ID for proper ID generation
      const maxId =
        allPlanSongs.length > 0
          ? Math.max(...allPlanSongs.map((ps) => ps.id))
          : 0;

      const newPlanSongs = songs.map((song, idx) => ({
        id: maxId + idx + 1,
        plan_id: newPlan.id,
        song_id: song.id,
        order_index: idx,
      }));

      const updatedPlanSongs = [...allPlanSongs, ...newPlanSongs];
      localStorage.setItem(
        STORAGE_KEYS.PLAN_SONGS,
        JSON.stringify(updatedPlanSongs)
      );
    }

    return newPlan;
  },

  async updatePlan(id, updates) {
    const plans = await this.getPlans();
    const index = plans.findIndex((p) => p.id === id);
    if (index >= 0) {
      // Extract songs from updates to handle separately
      const { songs, ...planUpdates } = updates;

      // Update plan metadata
      plans[index] = { ...plans[index], ...planUpdates };
      localStorage.setItem(STORAGE_KEYS.PLANS, JSON.stringify(plans));

      // If songs are provided, update plan songs
      if (songs) {
        // Delete existing plan songs
        const data = localStorage.getItem(STORAGE_KEYS.PLAN_SONGS);
        const allPlanSongs = JSON.parse(data || "[]");
        const filteredSongs = allPlanSongs.filter((ps) => ps.plan_id !== id);

        // Get the max ID from all plan songs for proper ID generation
        const maxId =
          allPlanSongs.length > 0
            ? Math.max(...allPlanSongs.map((ps) => ps.id))
            : 0;

        // Add new plan songs with incremental IDs
        const newPlanSongs = songs.map((song, idx) => ({
          id: maxId + idx + 1,
          plan_id: id,
          song_id: song.id,
          order_index: idx,
        }));

        const updatedPlanSongs = [...filteredSongs, ...newPlanSongs];
        localStorage.setItem(
          STORAGE_KEYS.PLAN_SONGS,
          JSON.stringify(updatedPlanSongs)
        );
      }
    }
    return plans[index];
  },

  async deletePlan(id) {
    console.log("localStorage.deletePlan called for id:", id);

    const plans = await this.getPlans();
    console.log(
      "Plans before delete:",
      plans.length,
      plans.map((p) => ({ id: p.id, date: p.date }))
    );

    const filtered = plans.filter((p) => p.id !== id);
    console.log(
      "Plans after filter:",
      filtered.length,
      filtered.map((p) => ({ id: p.id, date: p.date }))
    );

    localStorage.setItem(STORAGE_KEYS.PLANS, JSON.stringify(filtered));

    // Also delete associated plan songs
    const data = localStorage.getItem(STORAGE_KEYS.PLAN_SONGS);
    const planSongs = JSON.parse(data || "[]");
    const filteredSongs = planSongs.filter((ps) => ps.plan_id !== id);
    localStorage.setItem(
      STORAGE_KEYS.PLAN_SONGS,
      JSON.stringify(filteredSongs)
    );

    // Verify deletion
    const verifyPlans = await this.getPlans();
    const stillExists = verifyPlans.find((p) => p.id === id);
    if (stillExists) {
      console.error("WARNING: Plan still exists after deletion!", stillExists);
    }

    return { success: true, id };
  },

  // Plan Songs
  async getPlanSongs(planId) {
    const data = localStorage.getItem(STORAGE_KEYS.PLAN_SONGS);
    const allPlanSongs = JSON.parse(data || "[]");
    return allPlanSongs
      .filter((ps) => ps.plan_id === planId)
      .sort((a, b) => a.order_index - b.order_index);
  },

  async addSongToPlan(planId, songData) {
    const data = localStorage.getItem(STORAGE_KEYS.PLAN_SONGS);
    const planSongs = JSON.parse(data || "[]");
    const newEntry = {
      id: getNextId(planSongs),
      plan_id: planId,
      song_id: songData.song_id,
      order_index: songData.order_index || 0,
    };
    planSongs.push(newEntry);
    localStorage.setItem(STORAGE_KEYS.PLAN_SONGS, JSON.stringify(planSongs));
    return newEntry;
  },

  // Current Profile
  getCurrentProfile() {
    return localStorage.getItem(STORAGE_KEYS.CURRENT_PROFILE);
  },

  setCurrentProfile(profileId) {
    localStorage.setItem(STORAGE_KEYS.CURRENT_PROFILE, profileId.toString());
  },

  // Profile Songs (saved songs for each user profile)
  async getProfileSongs(profileId) {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS);
    const allProfileSongs = JSON.parse(data || "[]");
    const profileSongIds = allProfileSongs
      .filter((ps) => ps.profile_id === profileId)
      .map((ps) => ps.song_id);

    // Get full song details
    const songs = await this.getSongs();
    return songs.filter((s) => profileSongIds.includes(s.id));
  },

  async addSongToProfile(profileId, songId) {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS);
    const profileSongs = JSON.parse(data || "[]");

    // Check if already exists
    const exists = profileSongs.find(
      (ps) => ps.profile_id === profileId && ps.song_id === songId
    );
    if (exists) {
      return exists;
    }

    const newEntry = {
      id: getNextId(profileSongs),
      profile_id: profileId,
      song_id: songId,
      added_at: new Date().toISOString(),
    };
    profileSongs.push(newEntry);
    localStorage.setItem(
      STORAGE_KEYS.PROFILE_SONGS,
      JSON.stringify(profileSongs)
    );
    return newEntry;
  },

  async removeSongFromProfile(profileId, songId) {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS);
    const profileSongs = JSON.parse(data || "[]");
    const filtered = profileSongs.filter(
      (ps) => !(ps.profile_id === profileId && ps.song_id === songId)
    );
    localStorage.setItem(STORAGE_KEYS.PROFILE_SONGS, JSON.stringify(filtered));
    return { success: true };
  },

  // Profile-specific song keys (for transpose)
  async getProfileSongKey(profileId, songId) {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONG_KEYS);
    const keys = JSON.parse(data || "[]");
    const entry = keys.find(
      (k) => k.profile_id === profileId && k.song_id === songId
    );
    return entry ? entry.key : null;
  },

  async saveProfileSongKey(profileId, songId, key) {
    const data = localStorage.getItem(STORAGE_KEYS.PROFILE_SONG_KEYS);
    const keys = JSON.parse(data || "[]");

    const existingIndex = keys.findIndex(
      (k) => k.profile_id === profileId && k.song_id === songId
    );

    if (existingIndex >= 0) {
      keys[existingIndex].key = key;
    } else {
      keys.push({
        id: getNextId(keys),
        profile_id: profileId,
        song_id: songId,
        key: key,
      });
    }

    localStorage.setItem(STORAGE_KEYS.PROFILE_SONG_KEYS, JSON.stringify(keys));
    return { success: true };
  },
};

// Export raw storage keys so migration/utilities can reference correct names
export { STORAGE_KEYS };
