import { Injectable } from '@angular/core';
import { ComparedProduct, ContinueBrowsingState, FavoriteItem, RecentlyViewedItem, SavedSearch } from '../models/user-experience.model';
import { UserExperienceRepository } from './user-experience.repository';

const KEYS = {
  wishlist: 'marketplace.ux.wishlist',
  compare: 'marketplace.ux.compare',
  recentlyViewed: 'marketplace.ux.recently-viewed',
  savedSearches: 'marketplace.ux.saved-searches',
  continueBrowsingPrefix: 'marketplace.ux.continue-browsing:'
} as const;

@Injectable({ providedIn: 'root' })
export class LocalUserExperienceRepository implements UserExperienceRepository {
  getWishlist(): FavoriteItem[] {
    return this.readArray<FavoriteItem>(KEYS.wishlist);
  }

  saveWishlist(items: FavoriteItem[]): void {
    this.write(KEYS.wishlist, items);
  }

  getComparedProducts(): ComparedProduct[] {
    return this.readArray<ComparedProduct>(KEYS.compare);
  }

  saveComparedProducts(items: ComparedProduct[]): void {
    this.write(KEYS.compare, items);
  }

  getRecentlyViewed(): RecentlyViewedItem[] {
    return this.readArray<RecentlyViewedItem>(KEYS.recentlyViewed);
  }

  saveRecentlyViewed(items: RecentlyViewedItem[]): void {
    this.write(KEYS.recentlyViewed, items);
  }

  getSavedSearches(): SavedSearch[] {
    return this.readArray<SavedSearch>(KEYS.savedSearches);
  }

  saveSavedSearches(items: SavedSearch[]): void {
    this.write(KEYS.savedSearches, items);
  }

  getContinueBrowsing(routeKey: string): ContinueBrowsingState | null {
    return this.readSingle<ContinueBrowsingState>(this.continueKey(routeKey));
  }

  saveContinueBrowsing(state: ContinueBrowsingState): void {
    this.write(this.continueKey(state.routeKey), state);
  }

  clearContinueBrowsing(routeKey: string): void {
    if (!this.isBrowser()) {
      return;
    }

    localStorage.removeItem(this.continueKey(routeKey));
  }

  private readArray<T>(key: string): T[] {
    if (!this.isBrowser()) {
      return [];
    }

    try {
      const raw = localStorage.getItem(key);
      if (!raw) {
        return [];
      }

      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? (parsed as T[]) : [];
    } catch {
      return [];
    }
  }

  private readSingle<T>(key: string): T | null {
    if (!this.isBrowser()) {
      return null;
    }

    try {
      const raw = localStorage.getItem(key);
      if (!raw) {
        return null;
      }

      return JSON.parse(raw) as T;
    } catch {
      return null;
    }
  }

  private write<T>(key: string, value: T): void {
    if (!this.isBrowser()) {
      return;
    }

    localStorage.setItem(key, JSON.stringify(value));
  }

  private continueKey(routeKey: string): string {
    return `${KEYS.continueBrowsingPrefix}${routeKey}`;
  }

  private isBrowser(): boolean {
    return typeof window !== 'undefined';
  }
}
