import { Injectable, signal, computed, effect } from '@angular/core'; import { ApiService } from './api.service'; import { Item, CartItem } from '../models'; import type { } from '../types/telegram.types'; @Injectable({ providedIn: 'root' }) export class CartService { private readonly STORAGE_KEY = 'dexarmarket_cart'; private cartItems = signal([]); private isTelegram = typeof window !== 'undefined' && !!window.Telegram?.WebApp; items = this.cartItems.asReadonly(); itemCount = computed(() => { const items = this.cartItems(); if (!Array.isArray(items)) return 0; return items.reduce((total, item) => total + item.quantity, 0); }); totalPrice = computed(() => { const items = this.cartItems(); if (!Array.isArray(items)) return 0; return items.reduce((total, item) => { const price = item.price * (1 - item.discount / 100); return total + (price * item.quantity); }, 0); }); constructor(private apiService: ApiService) { this.loadCart(); // Auto-save whenever cart changes effect(() => { const items = this.cartItems(); this.saveToStorage(items); }); } private saveToStorage(items: CartItem[]): void { const data = JSON.stringify(items); // Always save to sessionStorage sessionStorage.setItem(this.STORAGE_KEY, data); // Also save to Telegram CloudStorage if available if (this.isTelegram) { window.Telegram!.WebApp.CloudStorage.setItem(this.STORAGE_KEY, data, (err) => { if (err) { console.error('Error saving to Telegram CloudStorage:', err); } }); } } private loadCart(): void { if (this.isTelegram) { // Load from Telegram CloudStorage first window.Telegram!.WebApp.CloudStorage.getItem(this.STORAGE_KEY, (err, value) => { if (err) { console.error('Error loading from Telegram CloudStorage:', err); this.loadFromSessionStorage(); } else if (value) { try { const items = JSON.parse(value); if (Array.isArray(items)) { // Migrate old items without quantity field const migratedItems: CartItem[] = items.map(item => ({ ...item, quantity: item.quantity || 1 })); this.cartItems.set(migratedItems); } else { this.cartItems.set([]); } } catch (parseErr) { console.error('Error parsing cart data:', parseErr); this.loadFromSessionStorage(); } } else { // No data in CloudStorage, try sessionStorage this.loadFromSessionStorage(); } }); } else { // Load from sessionStorage this.loadFromSessionStorage(); } } private loadFromSessionStorage(): void { const stored = sessionStorage.getItem(this.STORAGE_KEY); if (stored) { try { const items = JSON.parse(stored); if (Array.isArray(items)) { // Migrate old items without quantity field const migratedItems: CartItem[] = items.map(item => ({ ...item, quantity: item.quantity || 1 })); this.cartItems.set(migratedItems); } else { this.cartItems.set([]); } } catch (err) { console.error('Error parsing cart from sessionStorage:', err); this.cartItems.set([]); } } else { this.cartItems.set([]); } } addItem(itemID: number, quantity: number = 1): void { const currentItems = this.cartItems(); const existingItem = currentItems.find(i => i.itemID === itemID); if (existingItem) { // Item exists, increase quantity this.updateQuantity(itemID, existingItem.quantity + quantity); } else { // Get item details from API and add to cart this.apiService.getItem(itemID).subscribe({ next: (item) => { const cartItem: CartItem = { ...item, quantity }; this.cartItems.set([...this.cartItems(), cartItem]); }, error: (err) => { console.error('Error adding to cart:', err); alert('Ошибка добавления в корзину: ' + (err.error?.message || err.message)); } }); } } updateQuantity(itemID: number, quantity: number): void { if (quantity <= 0) { this.removeItem(itemID); return; } const currentItems = this.cartItems(); const updatedItems = currentItems.map(item => item.itemID === itemID ? { ...item, quantity } : item ); this.cartItems.set(updatedItems); } removeItems(itemIDs: number[]): void { const currentItems = this.cartItems(); const updatedItems = currentItems.filter(item => !itemIDs.includes(item.itemID)); this.cartItems.set(updatedItems); } removeItem(itemID: number): void { this.removeItems([itemID]); } clearCart(): void { this.cartItems.set([]); } }